source: trunk/oscam.c @ 431

Last change on this file since 431 was 121, checked in by smurzch2, 10 years ago

Make code compiling under Mac OS X.

Functions like strncpy, fopen, ... wants char *, not unsigned char *.

File size: 64.9 KB
Line 
1#define CS_CORE
2#include "globals.h"
3#ifdef CS_WITH_GBOX
4#  include "csgbox/gbox.h"
5#  define CS_VERSION_X  CS_VERSION "-gbx-" GBXVERSION
6#else
7#  define CS_VERSION_X  CS_VERSION
8#endif
9/*****************************************************************************
10        Globals
11*****************************************************************************/
12int pfd=0;          // Primary FD, must be closed on exit
13int mfdr=0;         // Master FD (read)
14int fd_m2c=0;       // FD Master -> Client (for clients / read )
15int fd_c2m=0;       // FD Client -> Master (for clients / write )
16int fd_c2l=0;       // FD Client -> Logger (for clients / write )
17int cs_dblevel=0;       // Debug Level (TODO !!)
18int cs_idx=0;       // client index (0=master, ...)
19int cs_ptyp=D_MASTER;   // process-type
20struct s_module ph[CS_MAX_MOD]; // Protocols
21int maxph=0;        // Protocols used
22int cs_hw=0;        // hardware autodetect
23int is_server=0;        // used in modules to specify function
24pid_t   master_pid=0;       // master pid OUTSIDE shm
25ushort  len4caid[256];      // table for guessing caid (by len)
26char    cs_confdir[128]=CS_CONFDIR;
27uchar   mbuf[1024];     // global buffer
28ECM_REQUEST *ecmtask;
29EMM_PACKET  epg;
30#ifdef CS_ANTICASC
31struct s_acasc ac_stat[CS_MAXPID];
32#endif
33
34/*****************************************************************************
35        Shared Memory
36*****************************************************************************/
37int         *ecmidx;    // Shared Memory
38int         *logidx;    // Shared Memory
39int         *oscam_sem; // sem (multicam.o)
40int         *c_start;   // idx of 1st client
41int         *log_fd;    // log-process is running
42struct  s_ecm         *ecmcache;  // Shared Memory
43struct  s_client    *client;      // Shared Memory
44struct  s_reader    *reader;      // Shared Memory
45
46struct  card_struct *Cards;   // Shared Memory
47struct  idstore_struct  *idstore;     // Shared Memory
48unsigned long   *IgnoreList;      // Shared Memory
49
50struct  s_config    *cfg;           // Shared Memory
51#ifdef CS_ANTICASC
52struct  s_acasc_shm   *acasc; // anti-cascading table indexed by account.ac_idx
53#endif
54#ifdef CS_LOGHISTORY
55int         *loghistidx;    // ptr to current entry
56char        *loghist;       // ptr of log-history
57#endif
58int     *mcl=0;       // Master close log?
59
60static  int  shmsize =  CS_ECMCACHESIZE*(sizeof(struct s_ecm)) +
61                        CS_MAXPID*(sizeof(struct s_client)) +
62                        CS_MAXREADER*(sizeof(struct s_reader)) +
63#ifdef CS_WITH_GBOX
64                        CS_MAXCARDS*(sizeof(struct card_struct))+
65                        CS_MAXIGNORE*(sizeof(long))+
66                        CS_MAXPID*(sizeof(struct idstore_struct))+
67#endif
68#ifdef CS_ANTICASC
69                        CS_MAXPID*(sizeof(struct s_acasc_shm)) + 
70#endif
71#ifdef CS_LOGHISTORY
72                        CS_MAXLOGHIST*CS_LOGHISTSIZE + sizeof(int) +
73#endif
74                        sizeof(struct s_config)+(6*sizeof(int));
75
76#ifdef CS_NOSHM
77char    cs_memfile[128]=CS_MMAPFILE;
78#endif
79
80/*****************************************************************************
81        Statics
82*****************************************************************************/
83static  char    mloc[128]={0};
84static  int shmid=0;        // Shared Memory ID
85static  int cs_last_idx=0;      // client index of last fork (master only)
86static  char*   credit[] = {
87        "dukat for the great MpCS piece of code",
88        "all members of streamboard.de.vu for testing",
89        "scotty and aroureos for the first softcam (no longer used)",
90        "John Moore for the hsic-client (humax 5400) and the arm-support",
91        "doz21 for the sio-routines and his support on camd3-protocol",
92        "kindzadza for his support on radegast-protocol",
93        "DS and ago for several modules in mpcs development",
94        "dingo35 for seca reader-support",
95        "dingo35 and okmikel for newcamd-support",
96        "hellmaster1024 for gb*x-support",
97        "the vdr-sc team for several good ideas :-)",
98        NULL };
99
100static void cs_set_mloc(int ato, char *txt)
101{
102  if (ato>=0)
103    alarm(ato);
104  if (txt)
105    strcpy(mloc, txt);
106}
107
108char *cs_platform(char *buf)
109{
110  static char *hw=NULL;
111  if (!hw)
112  {
113#ifdef TUXBOX
114    struct stat st;
115    cs_hw=CS_HW_DBOX2;                  // dbox2, default for now
116    if (!stat("/dev/sci0", &st)) cs_hw=CS_HW_DREAM; // dreambox
117    switch(cs_hw)
118    {
119#ifdef PPC
120      case CS_HW_DBOX2: hw="dbox2"   ; break;
121#endif
122      case CS_HW_DREAM: hw="dreambox"; break;
123    }
124#endif
125    if (!hw) hw=CS_OS_HW;
126  }
127  sprintf(buf, "%s-%s-%s", CS_OS_CPU, hw, CS_OS_SYS);
128  return(buf);
129}
130
131static void usage()
132{
133  int i;
134  fprintf(stderr, "\nOSCam cardserver v%s (%s) - (w) 2009 by smurzch\n", CS_VERSION_X, CS_OSTYPE);
135  fprintf(stderr, "\tbased on streamboard mp-cardserver v0.9d - (w) 2004-2007 by dukat\n\n");
136  fprintf(stderr, "oscam [-b] [-c config-dir]");
137#ifdef CS_NOSHM
138  fprintf(stderr, " [-m memory-file]");
139#endif
140  fprintf(stderr, "\n\n\t-b       : start in background\n");
141  fprintf(stderr, "\t-c <dir> : read configuration from <dir>\n");
142  fprintf(stderr, "\t           default=%s\n", CS_CONFDIR);
143#ifdef CS_NOSHM
144  fprintf(stderr, "\t-m <file>: use <file> as mmaped memory file\n");
145  fprintf(stderr, "\t           default=%s\n", CS_MMAPFILE);
146#endif
147  fprintf(stderr, "\nthanks to ...\n");
148  for (i=0; credit[i]; i++)
149    fprintf(stderr, "\t%s\n", credit[i]);
150  fprintf(stderr, "\n");
151  exit(1);
152}
153
154#ifdef NEED_DAEMON
155#ifdef OS_MACOSX
156// this is done because daemon is being deprecated starting with 10.5 and -Werror will always trigger an error
157static int daemon_compat(int nochdir, int noclose)
158#else
159static int daemon(int nochdir, int noclose)
160#endif
161{
162  int fd;
163
164  switch (fork())
165  {
166    case -1: return (-1);
167    case 0:  break;
168    default: _exit(0);
169  }
170
171  if (setsid()==(-1))
172    return(-1);
173
174  if (!nochdir)
175    (void)chdir("/");
176
177  if (!noclose && (fd=open("/dev/null", O_RDWR, 0)) != -1)
178  {
179    (void)dup2(fd, STDIN_FILENO);
180    (void)dup2(fd, STDOUT_FILENO);
181    (void)dup2(fd, STDERR_FILENO);
182    if (fd>2)
183      (void)close(fd);
184  }
185  return(0);
186}
187#endif
188
189int recv_from_udpipe(uchar *buf, int l)
190{
191  unsigned short n;
192  if (!pfd) return(-9);
193  if (!read(pfd, buf, 3)) cs_exit(1);
194  if (buf[0]!='U')
195  {
196    cs_log("INTERNAL PIPE-ERROR");
197    cs_exit(1);
198  }
199  memcpy(&n, buf+1, 2);
200  return(read(pfd, buf, n));
201}
202
203char *username(int idx)
204{
205  if (client[idx].usr[0])
206    return(client[idx].usr);
207  else
208    return("anonymous");
209}
210
211static int idx_from_ip(in_addr_t ip, in_port_t port)
212{
213  int i, idx;
214  for (i=idx=0; (i<CS_MAXPID) && (!idx); i++)
215    if ((client[i].ip==ip) && (client[i].port==port) &&
216        ((client[i].typ=='c') || (client[i].typ=='m')))
217      idx=i;
218  return(idx);
219}
220
221int idx_from_pid(pid_t pid)
222{
223  int i, idx;
224  for (i=0, idx=(-1); (i<CS_MAXPID) && (idx<0); i++)
225    if (client[i].pid==pid)
226      idx=i;
227  return(idx);
228}
229
230static long chk_caid(ushort caid, CAIDTAB *ctab)
231{
232  int n;
233  long rc;
234  for (rc=(-1), n=0; (n<CS_MAXCAIDTAB) && (rc<0); n++)
235    if ((caid & ctab->mask[n]) == ctab->caid[n])
236      rc=ctab->cmap[n] ? ctab->cmap[n] : caid;
237  return(rc);
238}
239
240int chk_bcaid(ECM_REQUEST *er, CAIDTAB *ctab)
241{
242  long caid;
243  if ((caid=chk_caid(er->caid, ctab))<0)
244    return(0);
245  er->caid=caid;
246  return(1);
247}
248
249/*
250 * void set_signal_handler(int sig, int flags, void (*sighandler)(int))
251 * flags: 1 = restart, 2 = don't modify if SIG_IGN, may be combined
252 */
253void set_signal_handler(int sig, int flags, void (*sighandler)(int))
254{
255#ifdef CS_SIGBSD
256  if ((signal(sig, sighandler)==SIG_IGN) && (flags & 2))
257  {
258    signal(sig, SIG_IGN);
259    siginterrupt(sig, 0);
260  }
261  else
262    siginterrupt(sig, (flags & 1) ? 0 : 1);
263#else
264  struct sigaction sa;
265  sigaction(sig, (struct sigaction *) 0, &sa);
266  if (!((flags & 2) && (sa.sa_handler==SIG_IGN)))
267  {
268    sigemptyset(&sa.sa_mask);
269    sa.sa_flags=(flags & 1) ? SA_RESTART : 0;
270    sa.sa_handler=sighandler;
271    sigaction(sig, &sa, (struct sigaction *) 0);
272  }
273#endif
274}
275
276static void cs_alarm(int sig)
277{
278  cs_debug("Got alarm signal");
279  cs_log("disconnect from %s (deadlock!)", cs_inet_ntoa(client[cs_idx].ip));
280  cs_exit(0);
281}
282
283static void cs_master_alarm(int sig)
284{
285  cs_log("PANIC: master deadlock! last location: %s", mloc);
286  fprintf(stderr, "PANIC: master deadlock! last location: %s", mloc);
287  fflush(stderr);
288  cs_exit(0);
289}
290
291static void cs_sigpipe(int sig)
292{
293  if ((cs_idx) && (master_pid!=getppid()))
294    cs_exit(0);
295  cs_log("Got sigpipe signal -> captured");
296}
297
298void cs_exit(int sig)
299{
300  int i;
301
302  set_signal_handler(SIGCHLD, 1, SIG_IGN);
303  set_signal_handler(SIGHUP , 1, SIG_IGN);
304  if (sig && (sig!=SIGQUIT))
305    cs_log("exit with signal %d", sig);
306  switch(client[cs_idx].typ)
307  {
308    case 'c': cs_statistics(cs_idx);
309    case 'm': break;
310    case 'n': *log_fd=0;
311              break;
312    case 's': *log_fd=0;
313              for (i=1; i<CS_MAXPID; i++)
314                if (client[i].pid)
315                  kill(client[i].pid, SIGQUIT);
316              cs_log("cardserver down");
317#ifndef CS_NOSHM
318              if (ecmcache) shmdt((void *)ecmcache);
319#endif
320              break;
321  }
322  if (pfd) close(pfd);
323#ifdef CS_NOSHM
324  munmap((void *)ecmcache, (size_t)shmsize);
325  if (shmid) close(shmid);
326  unlink(CS_MMAPFILE);      // ignore errors, last process must succeed
327#endif
328  exit(sig);
329}
330
331static void cs_reinit_clients()
332{
333  int i;
334  struct s_auth *account;
335
336  for( i=1; i<CS_MAXPID; i++ )
337    if( client[i].pid && client[i].typ=='c' && client[i].usr[0] )
338    {
339      for (account=cfg->account; (account) ; account=account->next)
340        if (!strcmp(client[i].usr, account->usr))
341          break;
342
343      if (account && 
344          client[i].pcrc==crc32(0L, MD5((uchar *)account->pwd, strlen(account->pwd), NULL), 16)) 
345      {
346        client[i].grp     = account->grp;
347        client[i].au      = account->au;
348        client[i].tosleep = (60*account->tosleep);
349        client[i].monlvl  = account->monlvl;
350        client[i].fchid   = account->fchid;  // CHID filters
351        client[i].cltab   = account->cltab;  // Class
352        client[i].ftab    = account->ftab;   // Ident
353        client[i].sidtabok= account->sidtabok;   // services
354        client[i].sidtabno= account->sidtabno;   // services
355        memcpy(&client[i].ctab, &account->ctab, sizeof(client[i].ctab));
356        memcpy(&client[i].ttab, &account->ttab, sizeof(client[i].ttab));
357#ifdef CS_ANTICASC
358        client[i].ac_idx     = account->ac_idx;
359        client[i].ac_penalty = account->ac_penalty;
360        client[i].ac_limit   = (account->ac_users*100+80)*cfg->ac_stime;
361#endif     
362      }
363      else 
364      {
365        if (ph[client[i].ctyp].type & MOD_CONN_NET) 
366        {
367          cs_debug("client '%s', pid=%d not found in db (or password changed)", 
368                    client[i].usr, client[i].pid);
369          kill(client[i].pid, SIGQUIT);
370        }
371      }
372    }
373}
374
375static void cs_sighup()
376{
377  uchar dummy[1]={0x00};
378  write_to_pipe(fd_c2m, PIP_ID_HUP, dummy, 1);
379}
380
381static void cs_accounts_chk()
382{
383  int i;
384
385  init_userdb();
386  cs_reinit_clients();
387#ifdef CS_ANTICASC
388  for (i=0; i<CS_MAXPID; i++)
389    if (client[i].typ=='a')
390    {
391      kill(client[i].pid, SIGHUP);
392      break;
393    }
394#endif
395}
396
397static void cs_debug_level()
398{
399  int i;
400
401  cs_dblevel ^= D_ALL_DUMP;
402  if (master_pid==getpid()) 
403    for (i=0; i<CS_MAXPID && client[i].pid; i++)
404      client[i].dbglvl=cs_dblevel;
405  else
406    client[cs_idx].dbglvl=cs_dblevel;
407  cs_log("%sdebug_level=%d", (master_pid==getpid())?"all ":"",cs_dblevel);
408}
409
410static void cs_card_info(int i)
411{
412  uchar dummy[1]={0x00};
413  for( i=1; i<CS_MAXPID; i++ )
414    if( client[i].pid && client[i].typ=='r' && client[i].fd_m2c ){
415      write_to_pipe(client[i].fd_m2c, PIP_ID_CIN, dummy, 1);
416    }
417
418      //kill(client[i].pid, SIGUSR2);
419}
420
421static void cs_child_chk(int i)
422{
423  while (waitpid(0, NULL, WNOHANG)>0);
424  for (i=1; i<CS_MAXPID; i++)
425    if (client[i].pid)
426      if (kill(client[i].pid, 0)) {
427        if ((client[i].typ!='c') && (client[i].typ!='m'))
428        {
429          char *txt="";
430          *log_fd=0;
431          switch(client[i].typ)
432          {
433#ifdef CS_ANTICASC
434            case 'a': txt="anticascader"; break;
435#endif
436            case 'l': txt="logger"; break;
437            case 'p': txt="proxy";  break;
438            case 'r': txt="reader"; break;
439            case 'n': txt="resolver";   break;
440          }
441          cs_log("PANIC: %s lost !! (pid=%d)", txt, client[i].pid);
442          cs_exit(1);
443        }
444        else
445        {
446#ifdef CS_ANTICASC
447          char usr[32];
448          ushort    ac_idx;
449          ushort    ac_limit;
450          uchar     ac_penalty;
451          if( cfg->ac_enabled )
452          {
453            strncpy(usr, client[i].usr, sizeof(usr)-1);
454            ac_idx = client[i].ac_idx;
455            ac_limit = client[i].ac_limit;
456            ac_penalty = client[i].ac_penalty;
457          }
458#endif
459          if (client[i].fd_m2c) close(client[i].fd_m2c);
460          if (client[i].ufd) close(client[i].ufd);
461          memset(&client[i], 0, sizeof(struct s_client));
462#ifdef CS_ANTICASC
463          if( cfg->ac_enabled )
464          {
465            client[i].ac_idx = ac_idx;
466            client[i].ac_limit = ac_limit;
467            client[i].ac_penalty = ac_penalty;
468            strcpy(client[i].usr, usr);
469          }
470#endif
471          client[i].au=(-1);
472        }
473      }
474  return;
475}
476
477int cs_fork(in_addr_t ip, in_port_t port)
478{
479  int i;
480  pid_t pid;
481  for (i=1; (i<CS_MAXPID) && (client[i].pid); i++);
482  if (i<CS_MAXPID)
483  {
484    int fdp[2];
485    memset(&client[i], 0, sizeof(struct s_client));
486    client[i].au=(-1);
487    if (pipe(fdp))
488    {
489      cs_log("Cannot create pipe (errno=%d)", errno);
490      cs_exit(1);
491    }
492    switch(pid=fork())
493    {
494      case -1:
495        cs_log("PANIC: Cannot fork() (errno=%d)", errno);
496        cs_exit(1);
497      case  0:                  // HERE is client
498        alarm(0);
499        set_signal_handler(SIGALRM, 0, cs_alarm);
500        set_signal_handler(SIGCHLD, 1, SIG_IGN);
501        set_signal_handler(SIGHUP , 1, SIG_IGN);
502        set_signal_handler(SIGINT , 1, SIG_IGN);
503        set_signal_handler(SIGUSR1, 1, cs_debug_level);
504        is_server=((ip) || (port<90)) ? 1 : 0;
505        fd_m2c=fdp[0];
506        close(fdp[1]);
507        close(mfdr);
508        if( port!=97 ) cs_close_log();
509        mfdr=0;
510        cs_ptyp=D_CLIENT;
511        cs_idx=i;
512#ifndef CS_NOSHM
513        shmid=0;
514#endif
515        break;
516      default:                  // HERE is master
517        client[i].fd_m2c=fdp[1];
518        client[i].dbglvl=cs_dblevel;
519        close(fdp[0]);
520        if (ip)
521        {
522          client[i].typ='c';            // dynamic client
523          client[i].ip=ip;
524          client[i].port=port;
525          cs_log("client(%d) connect from %s (pid=%d, pipfd=%d)",
526                  i-cdiff, cs_inet_ntoa(ip), pid, client[i].fd_m2c);
527        }
528        else
529        {
530          client[i].stat=1;
531          switch(port)
532          {
533            case 99: client[i].typ='r';     // reader
534                     client[i].sidtabok=reader[ridx].sidtabok;
535                     client[i].sidtabno=reader[ridx].sidtabno;
536                     reader[ridx].fd=client[i].fd_m2c;
537                     reader[ridx].cs_idx=i;
538                     if (reader[ridx].r_port)
539                       cs_log("proxy started (pid=%d, server=%s)",
540                              pid, reader[ridx].device);
541                     else
542                     {
543                       if (reader[ridx].typ==R_MOUSE || reader[ridx].typ==R_SMART)
544                         cs_log("reader started (pid=%d, device=%s, detect=%s%s, mhz=%d)",
545                                pid, reader[ridx].device,
546                                reader[ridx].detect&0x80 ? "!" : "",
547                                RDR_CD_TXT[reader[ridx].detect&0x7f],
548                                reader[ridx].mhz);
549                            else
550                         cs_log("reader started (pid=%d, device=%s)",
551                                pid, reader[ridx].device);
552                       client[i].ip=client[0].ip;
553                       strcpy(client[i].usr, client[0].usr);
554                     }
555                     cdiff=i;
556                     break;
557            case 98: client[i].typ='n';     // resolver
558                     client[i].ip=client[0].ip;
559                     strcpy(client[i].usr, client[0].usr);
560                     cs_log("resolver started (pid=%d, delay=%d sec)",
561                             pid, cfg->resolvedelay);
562                     cdiff=i;
563                     break;
564            case 97: client[i].typ='l';     // logger
565                     client[i].ip=client[0].ip;
566                     strcpy(client[i].usr, client[0].usr);
567                     cs_log("logger started (pid=%d)", pid);
568                     cdiff=i;
569                     break;
570#ifdef CS_ANTICASC
571            case 96: client[i].typ='a';
572                     client[i].ip=client[0].ip;
573                     strcpy(client[i].usr, client[0].usr);
574                     cs_log("anticascader started (pid=%d, delay=%d min)", 
575                            pid, cfg->ac_stime);
576                     cdiff=i;
577                     break;
578#endif
579            default: client[i].typ='c';     // static client
580                     client[i].ip=client[0].ip;
581                     client[i].ctyp=port;
582                     cs_log("%s: initialized (pid=%d%s)", ph[port].desc,
583                            pid, ph[port].logtxt ? ph[port].logtxt : "");
584                     break;
585          }
586        }
587        client[i].login=client[i].last=time((time_t *)0);
588        client[i].pid=pid;      // MUST be last -> wait4master()
589        cs_last_idx=i;
590        i=0;
591    }
592  }
593  else
594  {
595    cs_log("max connections reached -> reject client %s", cs_inet_ntoa(ip));
596    i=(-1);
597  }
598  return(i);
599}
600
601static void init_signal()
602{
603  int i;
604  for (i=1; i<NSIG; i++)
605    set_signal_handler(i, 3, cs_exit);
606  set_signal_handler(SIGWINCH, 1, SIG_IGN);
607//  set_signal_handler(SIGPIPE , 0, SIG_IGN);
608  set_signal_handler(SIGPIPE , 0, cs_sigpipe);
609//  set_signal_handler(SIGALRM , 0, cs_alarm);
610  set_signal_handler(SIGALRM , 0, cs_master_alarm);
611  set_signal_handler(SIGCHLD , 1, cs_child_chk);
612//  set_signal_handler(SIGHUP  , 1, cs_accounts_chk);
613  set_signal_handler(SIGHUP , 1, cs_sighup);
614  set_signal_handler(SIGUSR1, 1, cs_debug_level);
615  set_signal_handler(SIGUSR2, 1, cs_card_info);
616  set_signal_handler(SIGCONT, 1, SIG_IGN);
617  cs_log("signal handling initialized (type=%s)",
618#ifdef CS_SIGBSD
619         "bsd"
620#else
621         "sysv"
622#endif
623        );
624  return;
625}
626
627static void init_shm()
628{
629#ifdef CS_NOSHM
630  //int i, fd;
631  char *buf;
632  if ((shmid=open(cs_memfile, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR))<0)
633  {
634    fprintf(stderr, "Cannot create mmaped file (errno=%d)", errno);
635    cs_exit(1);
636  }
637
638  buf=(char *)malloc(shmsize);
639  memset(buf, 0, shmsize);
640  write(shmid, buf, shmsize);
641  free(buf);
642
643  ecmcache=(struct s_ecm *)mmap((void *)0, (size_t) shmsize, 
644                                PROT_READ|PROT_WRITE, MAP_SHARED, shmid, 0);
645#else
646  struct shmid_ds sd;
647  char *shmerr_txt="Cannot %s shared memory (errno=%d)\n";
648  if ((shmid=shmget(IPC_PRIVATE, shmsize, IPC_CREAT | 0600))<0)
649  {
650    fprintf(stderr, shmerr_txt, "create", errno);
651    shmid=0;
652    cs_exit(1);
653  }
654  if ((ecmcache=(struct s_ecm *)shmat(shmid, 0, 0))==(void *)(-1))
655  {
656    fprintf(stderr, shmerr_txt, "attach", errno);
657    cs_exit(1);
658  }
659  memset(ecmcache, 0, shmsize);
660  shmctl(shmid, IPC_RMID, &sd);
661#endif
662#ifdef CS_ANTICASC
663  acasc=(struct s_acasc_shm *)&ecmcache[CS_ECMCACHESIZE];
664  ecmidx=(int *)&acasc[CS_MAXPID];
665#else
666  ecmidx=(int *)&ecmcache[CS_ECMCACHESIZE];
667#endif
668  mcl=(int *)((void *)ecmidx+sizeof(int));
669  logidx=(int *)((void *)mcl+sizeof(int));
670  c_start=(int *)((void *)logidx+sizeof(int));
671  log_fd=(int *)((void *)c_start+sizeof(int));
672  oscam_sem=(int *)((void *)log_fd+sizeof(int));
673  client=(struct s_client *)((void *)oscam_sem+sizeof(int));
674  reader=(struct s_reader *)&client[CS_MAXPID];
675#ifdef CS_WITH_GBOX
676  Cards=(struct card_struct*)&reader[CS_MAXREADER];
677  IgnoreList=(unsigned long*)&Cards[CS_MAXCARDS];
678  idstore=(struct idstore_struct*)&IgnoreList[CS_MAXIGNORE];
679  cfg=(struct s_config *)&idstore[CS_MAXPID];
680#else
681  cfg=(struct s_config *)&reader[CS_MAXREADER];
682#endif
683#ifdef CS_LOGHISTORY
684  loghistidx=(int *)((void *)cfg+sizeof(struct s_config));
685  loghist=(char *)((void *)loghistidx+sizeof(int));
686#endif
687
688#ifdef DEBUG_SHM_POINTER
689  printf("SHM ALLOC: %x\n", shmsize);
690  printf("SHM START: %p\n", (void *) ecmcache);
691  printf("SHM ST1: %p %x (%x)\n", (void *) ecmidx, ((void *) ecmidx) - ((void *) ecmcache), CS_ECMCACHESIZE*(sizeof(struct s_ecm)));
692  printf("SHM ST2: %p %x (%x)\n", (void *) oscam_sem, ((void *) oscam_sem) - ((void *) ecmidx), sizeof(int));
693  printf("SHM ST3: %p %x (%x)\n", (void *) client, ((void *) client) - ((void *) oscam_sem), sizeof(int));
694  printf("SHM ST4: %p %x (%x)\n", (void *) reader, ((void *) reader) - ((void *) client), CS_MAXPID*(sizeof(struct s_client)));
695  printf("SHM ST5: %p %x (%x)\n", (void *) cfg, ((void *) cfg) - ((void *) reader), CS_MAXREADER*(sizeof(struct s_reader)));
696  printf("SHM ST6: %p %x (%x)\n", ((void *) cfg)+sizeof(struct s_config), sizeof(struct s_config), sizeof(struct s_config));
697  printf("SHM ENDE: %p\n", ((void *) cfg)+sizeof(struct s_config));
698  printf("SHM SIZE: %x\n", ((void *) cfg)-((void *) ecmcache) + sizeof(struct s_config));
699  fflush(stdout);
700#endif
701
702  *ecmidx=0;
703  *logidx=0;
704  *oscam_sem=0;
705  client[0].pid=getpid();
706  client[0].login=time((time_t *)0);
707  client[0].ip=cs_inet_addr("127.0.0.1");
708  client[0].typ='s';
709  client[0].au=(-1);
710  client[0].dbglvl=cs_dblevel;
711  strcpy(client[0].usr, "root");
712#ifdef CS_LOGHISTORY
713  *loghistidx=0;
714  memset(loghist, 0, CS_MAXLOGHIST*CS_LOGHISTSIZE);
715#endif
716}
717
718static int start_listener(struct s_module *ph, int port_idx)
719{
720  int ov=1, timeout, is_udp, i;
721  char ptxt[2][32];
722  //struct   hostent   *ptrh;     /* pointer to a host table entry */
723  struct   protoent  *ptrp;     /* pointer to a protocol table entry */
724  struct   sockaddr_in sad;     /* structure to hold server's address */
725
726  ptxt[0][0]=ptxt[1][0]='\0';
727  if (!ph->ptab->ports[port_idx].s_port)
728  {
729    cs_log("%s: disabled", ph->desc);
730    return(0);
731  }
732  is_udp=(ph->type==MOD_CONN_UDP);
733
734  memset((char  *)&sad,0,sizeof(sad)); /* clear sockaddr structure   */
735  sad.sin_family = AF_INET;            /* set family to Internet     */
736  if (!ph->s_ip)
737    ph->s_ip=cfg->srvip;
738  if (ph->s_ip)
739  {
740    sad.sin_addr.s_addr=ph->s_ip;
741    sprintf(ptxt[0], ", ip=%s", inet_ntoa(sad.sin_addr));
742  }
743  else
744    sad.sin_addr.s_addr=INADDR_ANY;
745  timeout=cfg->bindwait;
746  //ph->fd=0;
747  ph->ptab->ports[port_idx].fd = 0;
748
749  if (ph->ptab->ports[port_idx].s_port > 0)   /* test for illegal value    */
750    sad.sin_port = htons((u_short)ph->ptab->ports[port_idx].s_port);
751  else
752  {
753    cs_log("%s: Bad port %d", ph->desc, ph->ptab->ports[port_idx].s_port);
754    return(0);
755  }
756
757  /* Map transport protocol name to protocol number */
758
759  if( (ptrp=getprotobyname(is_udp ? "udp" : "tcp")) )
760    ov=ptrp->p_proto;
761  else
762    ov=(is_udp) ? 17 : 6;   // use defaults on error
763
764  if ((ph->ptab->ports[port_idx].fd=socket(PF_INET,is_udp ? SOCK_DGRAM : SOCK_STREAM, ov))<0)
765  {
766    cs_log("%s: Cannot create socket (errno=%d)", ph->desc, errno);
767    return(0);
768  }
769
770  ov=1;
771  if (setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_REUSEADDR, (void *)&ov, sizeof(ov))<0)
772  {
773    cs_log("%s: setsockopt failed (errno=%d)", ph->desc, errno);
774    close(ph->ptab->ports[port_idx].fd);
775    return(ph->ptab->ports[port_idx].fd=0);
776  }
777
778#ifdef SO_REUSEPORT
779  setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_REUSEPORT, (void *)&ov, sizeof(ov));
780#endif
781
782#ifdef SO_PRIORITY
783  if (cfg->netprio)
784    if (!setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_PRIORITY, (void *)&cfg->netprio, sizeof(ulong)))
785      sprintf(ptxt[1], ", prio=%ld", cfg->netprio);
786#endif
787
788  if( !is_udp )
789  {
790    ulong keep_alive = 1;
791    setsockopt(ph->ptab->ports[port_idx].fd, SOL_SOCKET, SO_KEEPALIVE, 
792               (void *)&keep_alive, sizeof(ulong));
793  }
794 
795  while (timeout--)
796  {
797    if (bind(ph->ptab->ports[port_idx].fd, (struct sockaddr *)&sad, sizeof (sad))<0)
798    {
799      if (timeout)
800      {
801        cs_log("%s: Bind request failed, waiting another %d seconds",
802               ph->desc, timeout);
803        sleep(1);
804      }
805      else
806      {
807        cs_log("%s: Bind request failed, giving up", ph->desc);
808        close(ph->ptab->ports[port_idx].fd);
809        return(ph->ptab->ports[port_idx].fd=0);
810      }
811    }
812    else timeout=0;
813  }
814
815  if (!is_udp)
816    if (listen(ph->ptab->ports[port_idx].fd, CS_QLEN)<0)
817    {
818      cs_log("%s: Cannot start listen mode (errno=%d)", ph->desc, errno);
819      close(ph->ptab->ports[port_idx].fd);
820      return(ph->ptab->ports[port_idx].fd=0);
821    }
822
823  cs_log("%s: initialized (fd=%d, port=%d%s%s%s)",
824         ph->desc, ph->ptab->ports[port_idx].fd,
825         ph->ptab->ports[port_idx].s_port,
826         ptxt[0], ptxt[1], ph->logtxt ? ph->logtxt : "");
827
828  for( i=0; i<ph->ptab->ports[port_idx].ftab.nfilts; i++ ) {
829    int j;
830    cs_log("CAID: %04X", ph->ptab->ports[port_idx].ftab.filts[i].caid );
831    for( j=0; j<ph->ptab->ports[port_idx].ftab.filts[i].nprids; j++ )
832      cs_log("provid #%d: %06X", j, ph->ptab->ports[port_idx].ftab.filts[i].prids[j]);
833  }
834  return(ph->ptab->ports[port_idx].fd);
835}
836
837static void *cs_client_resolve(void *dummy)
838{
839  while (1)
840  {
841    struct hostent *rht;
842    struct s_auth *account;
843    struct sockaddr_in udp_sa;
844
845    for (account=cfg->account; account; account=account->next)
846      if (account->dyndns[0])
847      {
848        if (rht=gethostbyname((const char *)account->dyndns))
849        {
850          memcpy(&udp_sa.sin_addr, rht->h_addr, sizeof(udp_sa.sin_addr));
851          account->dynip=cs_inet_order(udp_sa.sin_addr.s_addr);
852        }
853        else
854          cs_log("can't resolve hostname %s (user: %s)", account->dyndns, account->usr);
855        client[cs_idx].last=time((time_t)0);
856      }
857    sleep(cfg->resolvedelay);
858  }
859}
860
861static void start_client_resolver()
862{
863  int i;
864  pthread_t tid;
865
866  if (i=pthread_create(&tid, (pthread_attr_t *)0, cs_client_resolve, (void *) 0))
867    cs_log("ERROR: can't create resolver-thread (err=%d)", i);
868  else
869  {
870    cs_log("resolver thread started");
871    pthread_detach(tid);
872  }
873}
874
875void cs_resolve()
876{
877  int i, idx;
878  struct hostent *rht;
879  struct s_auth *account;
880  for (i=0; i<CS_MAXREADER; i++)
881    if ((idx=reader[i].cs_idx) && (reader[i].typ & R_IS_NETWORK))
882    {
883      client[cs_idx].last=time((time_t)0);
884      if (rht=gethostbyname(reader[i].device))
885      {
886        memcpy(&client[idx].udp_sa.sin_addr, rht->h_addr,
887               sizeof(client[idx].udp_sa.sin_addr));
888        client[idx].ip=cs_inet_order(client[idx].udp_sa.sin_addr.s_addr);
889      }
890      else
891        cs_log("can't resolve %s", reader[i].device);
892      client[cs_idx].last=time((time_t)0);
893    }
894}
895
896#ifdef USE_PTHREAD
897static void *cs_logger(void *dummy)
898#else
899static void cs_logger(void)
900#endif
901{
902  *log_fd=client[cs_idx].fd_m2c;
903  while(1)
904  {
905    uchar *ptr;
906    //struct timeval tv;
907    fd_set fds;
908
909    FD_ZERO(&fds);
910    FD_SET(fd_m2c, &fds);
911    select(fd_m2c+1, &fds, 0, 0, 0);
912#ifndef USE_PTHREAD
913    if (master_pid!=getppid())
914      cs_exit(0);
915#endif
916    if (FD_ISSET(fd_m2c, &fds))
917    {
918      int n;
919//    switch(n=read_from_pipe(fd_m2c, &ptr, 1))
920      n=read_from_pipe(fd_m2c, &ptr, 1);
921//if (n!=PIP_ID_NUL) printf("received %d bytes\n", n); fflush(stdout);
922      switch(n)
923      {
924        case PIP_ID_LOG:
925          cs_write_log(ptr);
926          break;
927      }
928    }
929  }
930}
931
932static void start_resolver()
933{
934  int i;
935#ifdef USE_PTHREAD
936  pthread_t tid;
937  if (i=pthread_create(&tid, (pthread_attr_t *)0, cs_logger, (void *) 0))
938    cs_log("ERROR: can't create logging-thread (err=%d)", i);
939  else
940  {
941    cs_log("logging thread started");
942    pthread_detach(tid);
943  }
944#endif
945  sleep(1); // wait for reader
946  while(1)
947  {
948    if (master_pid!=getppid())
949      cs_exit(0);
950    cs_resolve();
951    for (i=0; i<cfg->resolvedelay; i++)
952      if (master_pid!=getppid())
953        cs_exit(0);
954      else
955        sleep(1);
956//        sleep(cfg->resolvedelay);
957  }
958}
959
960#ifdef CS_ANTICASC
961static void start_anticascader()
962{
963  int i;
964
965  use_ac_log=1;
966  set_signal_handler(SIGHUP, 1, ac_init_stat);
967 
968  ac_init_stat(0);
969  while(1)
970  {
971    for( i=0; i<cfg->ac_stime*60; i++ )
972      if( master_pid!=getppid() )
973        cs_exit(0);
974      else
975        sleep(1);
976
977    if (master_pid!=getppid())
978      cs_exit(0);
979
980    ac_do_stat();
981  }
982}
983#endif
984
985static void init_cardreader()
986{
987  for (ridx=0; ridx<CS_MAXREADER; ridx++)
988    if (reader[ridx].device[0])
989      switch(cs_fork(0, 99))
990      {
991        case -1:
992          cs_exit(1);
993        case  0:
994          break;
995        default:
996          wait4master();
997          start_cardreader();
998      }
999}
1000
1001static void init_service(int srv)
1002{
1003#ifdef USE_PTHREAD
1004   uchar dummy[1]={0x00};
1005#endif
1006
1007  switch(cs_fork(0, srv))
1008  {
1009    case -1:
1010      cs_exit(1);
1011    case  0:
1012      break;
1013    default:
1014      wait4master();
1015      switch(srv)
1016      {
1017#ifdef CS_ANTICASC
1018        case 96: start_anticascader();
1019#endif
1020#ifdef USE_PTHREAD
1021        case 97: cs_logger(dummy);
1022#else
1023        case 97: cs_logger();
1024#endif
1025        case 98: start_resolver();
1026      }
1027  }
1028}
1029
1030void wait4master()
1031{
1032  int i;
1033  for (i=0; (i<1000) && (client[cs_idx].pid!=getpid()); i++)
1034    usleep(1000L);
1035  if (client[cs_idx].pid!=getpid())
1036  {
1037    cs_log("PANIC: client not found in shared memory");
1038    cs_exit(1);
1039  }
1040  cs_debug("starting client %d with ip %s",
1041            cs_idx-cdiff, cs_inet_ntoa(client[cs_idx].ip));
1042}
1043
1044static void cs_fake_client(char *usr, int uniq, in_addr_t ip)
1045{
1046    /* - Uniq = 1: only one connection per user
1047     * - Uniq = 2: set user only to fake if source ip is different (e.g. for
1048     *             newcamd clients with different CAID's -> Ports)
1049    */
1050
1051    int i;
1052
1053    for (i=cdiff+1; i<CS_MAXPID; i++) {
1054        if (client[i].pid
1055                && (client[i].typ == 'c')
1056                && !client[i].dup
1057                && !strcmp(client[i].usr, usr)
1058                && ((uniq == 1)  || (client[i].ip != ip)))
1059        {
1060            client[cs_idx].dup = 1;
1061            client[cs_idx].au = -1;
1062            cs_log("client(%d) duplicate user '%s' from %s set to fake (uniq=%d)", cs_idx-cdiff, usr, cs_inet_ntoa(ip), uniq);
1063            break;
1064        }
1065    }
1066}
1067
1068int cs_auth_client(struct s_auth *account, char *e_txt)
1069{
1070  int rc=0;
1071  char buf[16];
1072  char *t_crypt="encrypted";
1073  char *t_plain="plain";
1074  char *t_grant=" granted";
1075  char *t_reject=" rejected";
1076  char *t_msg[]= { buf, "invalid access", "invalid ip", "unknown reason" };
1077  client[cs_idx].grp=0xffffffff;
1078  client[cs_idx].au=(-1);
1079  switch((long)account)
1080  {
1081    case -2:                        // gbx-dummy
1082      client[cs_idx].dup=0;
1083      break;
1084    case 0:                     // reject access
1085      rc=1;
1086      cs_log("%s %s-client %s%s (%s)",
1087             client[cs_idx].crypted ? t_crypt : t_plain,
1088             ph[client[cs_idx].ctyp].desc,
1089             client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1090             client[cs_idx].ip ? t_reject : t_reject+1,
1091             e_txt ? e_txt : t_msg[rc]);
1092      break;
1093    default:                        // grant/check access
1094      if (client[cs_idx].ip && account->dyndns[0])
1095        if (client[cs_idx].ip != account->dynip)
1096          rc=2;
1097      if (!rc)
1098      {
1099        client[cs_idx].dup=0;
1100        if (client[cs_idx].typ=='c')
1101        {
1102          client[cs_idx].grp=account->grp;
1103          client[cs_idx].au=account->au;
1104          client[cs_idx].tosleep=(60*account->tosleep);
1105          memcpy(&client[cs_idx].ctab, &account->ctab, sizeof(client[cs_idx].ctab));
1106          if (account->uniq)
1107            cs_fake_client(account->usr, account->uniq, client[cs_idx].ip);
1108          client[cs_idx].ftab  = account->ftab;   // IDENT filter
1109          client[cs_idx].cltab = account->cltab;  // CLASS filter
1110          client[cs_idx].fchid = account->fchid;  // CHID filter
1111          client[cs_idx].sidtabok= account->sidtabok;   // services
1112          client[cs_idx].sidtabno= account->sidtabno;   // services
1113          client[cs_idx].pcrc  = crc32(0L, MD5((uchar *)account->pwd, strlen(account->pwd), NULL), 16);
1114          memcpy(&client[cs_idx].ttab, &account->ttab, sizeof(client[cs_idx].ttab));
1115#ifdef CS_ANTICASC
1116          ac_init_client(account);
1117#endif
1118        }
1119      }
1120      client[cs_idx].monlvl=account->monlvl;
1121      strcpy(client[cs_idx].usr, account->usr);
1122    case -1:                        // anonymous grant access
1123      if (rc)
1124        t_grant=t_reject;
1125      else
1126      {
1127        if (client[cs_idx].typ=='m')
1128          sprintf(t_msg[0], "lvl=%d", client[cs_idx].monlvl);
1129        else
1130          sprintf(t_msg[0], "au=%d", client[cs_idx].au+1);
1131      }
1132
1133      if(client[cs_idx].ncd_server)
1134      {
1135        cs_log("%s %s:%d-client %s%s (%s, %s)",
1136             client[cs_idx].crypted ? t_crypt : t_plain,
1137             e_txt ? e_txt : ph[client[cs_idx].ctyp].desc,
1138             cfg->ncd_ptab.ports[client[cs_idx].port_idx].s_port,
1139             client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1140             client[cs_idx].ip ? t_grant : t_grant+1,   
1141             username(cs_idx), t_msg[rc]);
1142      }
1143      else
1144      {
1145        cs_log("%s %s-client %s%s (%s, %s)",
1146             client[cs_idx].crypted ? t_crypt : t_plain,
1147             e_txt ? e_txt : ph[client[cs_idx].ctyp].desc,         
1148             client[cs_idx].ip ? cs_inet_ntoa(client[cs_idx].ip) : "",
1149             client[cs_idx].ip ? t_grant : t_grant+1,
1150             username(cs_idx), t_msg[rc]);
1151      }
1152
1153      break;
1154  }
1155  return(rc);
1156}
1157
1158void cs_disconnect_client(void)
1159{
1160  char buf[32]={0};
1161  if (client[cs_idx].ip)
1162    sprintf(buf, " from %s", cs_inet_ntoa(client[cs_idx].ip));
1163  cs_log("%s disconnected%s", username(cs_idx), buf);
1164  cs_exit(0);
1165}
1166
1167int check_ecmcache(ECM_REQUEST *er, ulong grp)
1168{
1169  int i;
1170// cs_ddump(ecmd5, CS_ECMSTORESIZE, "ECM search");
1171//cs_log("cache CHECK: grp=%lX", grp);
1172  for(i=0; i<CS_ECMCACHESIZE; i++)
1173    if ((grp & ecmcache[i].grp) &&
1174        (!memcmp(ecmcache[i].ecmd5, er->ecmd5, CS_ECMSTORESIZE)))
1175    {
1176//cs_log("cache found: grp=%lX cgrp=%lX", grp, ecmcache[i].grp);
1177      memcpy(er->cw, ecmcache[i].cw, 16);
1178      return(1);
1179    }
1180  return(0);
1181}
1182
1183static void store_ecm(ECM_REQUEST *er)
1184{
1185//cs_log("store ecm from reader %d", er->reader[0]);
1186  memcpy(ecmcache[*ecmidx].ecmd5, er->ecmd5, CS_ECMSTORESIZE);
1187  memcpy(ecmcache[*ecmidx].cw, er->cw, 16);
1188  ecmcache[*ecmidx].caid=er->caid;
1189  ecmcache[*ecmidx].prid=er->prid;
1190  ecmcache[*ecmidx].grp =reader[er->reader[0]].grp;
1191// cs_ddump(ecmcache[*ecmidx].ecmd5, CS_ECMSTORESIZE, "ECM stored (idx=%d)", *ecmidx);
1192  *ecmidx=(*ecmidx+1) % CS_ECMCACHESIZE;
1193}
1194
1195void store_logentry(char *txt)
1196{
1197#ifdef CS_LOGHISTORY
1198  char *ptr;
1199  ptr=(char *)(loghist+(*loghistidx*CS_LOGHISTSIZE));
1200  ptr[0]='\1';      // make username unusable
1201  ptr[1]='\0';
1202  if ((client[cs_idx].typ=='c') || (client[cs_idx].typ=='m'))
1203    strncpy(ptr, client[cs_idx].usr, 31);
1204  strncpy(ptr+32, txt, CS_LOGHISTSIZE-33);
1205  *loghistidx=(*loghistidx+1) % CS_MAXLOGHIST;
1206#endif
1207}
1208
1209/*
1210 * write_to_pipe():
1211 * write all kind of data to pipe specified by fd
1212 */
1213int write_to_pipe(int fd, int id, uchar *data, int n)
1214{
1215  uchar buf[1024+3+sizeof(int)];
1216
1217//printf("WRITE_START pid=%d", getpid()); fflush(stdout);
1218  if ((id<0) || (id>PIP_ID_MAX))
1219    return(PIP_ID_ERR);
1220  memcpy(buf, PIP_ID_TXT[id], 3);
1221  memcpy(buf+3, &n, sizeof(int));
1222  memcpy(buf+3+sizeof(int), data, n);
1223  n+=3+sizeof(int);
1224//n=write(fd, buf, n);
1225//printf("WRITE_END pid=%d", getpid()); fflush(stdout);
1226//return(n);
1227  if( !fd )
1228    cs_log("write_to_pipe: fd==0");
1229  return(write(fd, buf, n));
1230}
1231
1232/*
1233 * read_from_pipe():
1234 * read all kind of data from pipe specified by fd
1235 * special-flag redir: if set AND data is ECM: this will redirected to appr. client
1236 */
1237int read_from_pipe(int fd, uchar **data, int redir)
1238{
1239  int rc;
1240  static int hdr=0;
1241  static uchar buf[1024+1+3+sizeof(int)];
1242
1243  *data=(uchar *)0;
1244  rc=PIP_ID_NUL;
1245
1246  if (!hdr)
1247  {
1248    if (bytes_available(fd))
1249    {
1250      if (read(fd, buf, 3+sizeof(int))==3+sizeof(int))
1251        memcpy(&hdr, buf+3, sizeof(int));
1252      else
1253        cs_log("WARNING: pipe header to small !");
1254    }
1255  }
1256  if (hdr)
1257  {
1258    int l;
1259    for (l=0; (rc<0) && (PIP_ID_TXT[l]); l++)
1260      if (!memcmp(buf, PIP_ID_TXT[l], 3))
1261        rc=l;
1262
1263    if (rc<0)
1264    {
1265      fprintf(stderr, "WARNING: pipe garbage");
1266      fflush(stderr);
1267      cs_log("WARNING: pipe garbage");
1268      rc=PIP_ID_ERR;
1269    }
1270    else
1271    {
1272      l=hdr;
1273      if ((l+3-1+sizeof(int))>sizeof(buf))
1274      {
1275        cs_log("WARNING: packet size (%d) to large", l);
1276        l=sizeof(buf)+3-1+sizeof(int);
1277      }
1278      if (!bytes_available(fd))
1279        return(PIP_ID_NUL);
1280      hdr=0;
1281      if (read(fd, buf+3+sizeof(int), l)==l)
1282        *data=buf+3+sizeof(int);
1283      else
1284      {
1285        cs_log("WARNING: pipe data to small !");
1286        return(PIP_ID_ERR);
1287      }
1288      buf[l+3+sizeof(int)]=0;
1289      if ((redir) && (rc==PIP_ID_ECM))
1290      {
1291        //int idx;
1292        ECM_REQUEST *er;
1293        er=(ECM_REQUEST *)(buf+3+sizeof(int));
1294        if( er->cidx && client[er->cidx].fd_m2c )
1295            if (!write(client[er->cidx].fd_m2c, buf, l+3+sizeof(int))) cs_exit(1);
1296        rc=PIP_ID_DIR;
1297      }
1298    }
1299  }
1300  return(rc);
1301}
1302
1303/*
1304 * write_ecm_request():
1305 */
1306int write_ecm_request(int fd, ECM_REQUEST *er)
1307{
1308  return(write_to_pipe(fd, PIP_ID_ECM, (uchar *) er, sizeof(ECM_REQUEST)));
1309}
1310
1311int write_ecm_DCW(int fd, ECM_REQUEST *er)
1312{
1313  return(write_to_pipe(fd, PIP_ID_DCW, (uchar *) er, sizeof(ECM_REQUEST)));
1314}
1315
1316void logCWtoFile(ECM_REQUEST *er)
1317{
1318    /* This function writes the current CW from ECM struct to a cwl file.
1319       The filename is re-calculated and file re-opened every time.
1320       This will consume a bit cpu time, but nothing has to be stored between
1321       each call. If not file exists, a header is prepended */
1322
1323    FILE *pfCWL;
1324    char srvname[23];
1325    /* %s / %s   _I  %04X  _  %s  .cwl  */
1326    char buf[sizeof(cfg->cwlogdir)+1+6+2+4+1+sizeof(srvname)+5];
1327    char date[7];
1328    unsigned char  i, parity, writeheader = 0;
1329    time_t t;
1330    struct tm *timeinfo;
1331    struct s_srvid *this;
1332
1333    if (cfg->cwlogdir[0])     /* CWL logging only if cwlogdir is set in config */
1334    {
1335        /* search service name for that id and change characters
1336           causing problems in file name */
1337        srvname[0] = 0;
1338        for (this=cfg->srvid; this; this=this->next) {
1339            if (this->srvid==er->srvid) {
1340                strncpy(srvname, this->name, sizeof(srvname));
1341                srvname[sizeof(srvname)-1] = 0;
1342                for (i=0;srvname[i];i++)
1343                    if (srvname[i]==' ') srvname[i]='_';
1344                break;
1345            }
1346        }
1347
1348        /* calc log file name */
1349        time(&t);
1350        timeinfo = localtime(&t);
1351        strftime(date,sizeof(date),"%y%m%d",timeinfo);
1352        sprintf(buf, "%s/%s_I%04X_%s.cwl", cfg->cwlogdir, date, er->srvid, srvname);
1353
1354        if((pfCWL=fopen(buf,"r")) == NULL)
1355        {
1356            /* open failed, assuming file does not exist, yet */
1357            writeheader = 1;
1358        } else
1359        {
1360            /* we need to close the file if it was opened correctly */
1361            fclose(pfCWL);
1362        }
1363
1364        if ((pfCWL=fopen(buf, "a+")) == NULL)
1365        {
1366            /* maybe this fails because the subdir does not exist. Is there a common function to create it? */
1367            /* for the moment do not print to log on every ecm
1368               cs_log(""error opening cw logfile for writing: %s (errno %d)", buf, errno); */
1369            return;
1370        }
1371        if (writeheader)
1372        {
1373            /* no global macro for cardserver name :( */
1374            fprintf(pfCWL, "# OSCam cardserver v%s - http://streamboard.gmc.to:8001/oscam/wiki\n", CS_VERSION_X); 
1375            fprintf(pfCWL, "# control word log file for use with tsdec offline decrypter\n");
1376            strftime(buf,sizeof(buf),"DATE %Y-%m-%d, TIME %H:%M:%S, TZ %Z\n",timeinfo);
1377            fprintf(pfCWL, "# %s",buf);
1378            fprintf(pfCWL, "# CAID 0x%04X, SID 0x%04X, SERVICE \"%s\"\n", er->caid, er->srvid, srvname);
1379        }
1380
1381        parity = er->ecm[0]&1;
1382        fprintf(pfCWL, "%d ",parity);
1383        for (i=parity*8; i<8+parity*8; i++)
1384            fprintf(pfCWL, "%02X ",er->cw[i]);
1385        /* better use incoming time er->tps rather than current time? */
1386        strftime(buf,sizeof(buf),"%H:%M:%S\n",timeinfo);
1387        fprintf(pfCWL, "# %s",buf);
1388        fflush(pfCWL);
1389        fclose(pfCWL);
1390    } /* if (cfg->pidfile[0]) */
1391}
1392
1393int write_ecm_answer(int fd, ECM_REQUEST *er)
1394{
1395  int i, f;
1396  uchar c;
1397  for (i=f=0; i<16; i+=4)
1398  {
1399    c=((er->cw[i]+er->cw[i+1]+er->cw[i+2]) & 0xff);
1400    if (er->cw[i+3]!=c)
1401    {
1402      f=1;
1403      er->cw[i+3]=c;
1404    }
1405  }
1406  if (f)
1407    cs_debug("notice: changed dcw checksum bytes");
1408
1409  er->reader[0]=ridx;
1410//cs_log("answer from reader %d (rc=%d)", er->reader[0], er->rc);
1411  er->caid=er->ocaid;
1412  if (er->rc==1||(er->gbxRidx&&er->rc==0)){
1413    store_ecm(er);
1414    logCWtoFile(er);
1415  } 
1416 
1417  return(write_ecm_request(fd, er));
1418}
1419
1420static int cs_read_timer(int fd, uchar *buf, int l, int msec)
1421{
1422  struct timeval tv;
1423  fd_set fds;
1424  int rc;
1425
1426  if (!fd) return(-1);
1427  tv.tv_sec = msec / 1000;
1428  tv.tv_usec = (msec % 1000) * 1000;
1429  FD_ZERO(&fds);
1430  FD_SET(pfd, &fds);
1431
1432  select(fd+1, &fds, 0, 0, &tv);
1433
1434  rc=0;
1435  if (FD_ISSET(pfd, &fds))
1436    if (!(rc=read(fd, buf, l)))
1437      rc=-1;
1438
1439  return(rc);
1440}
1441
1442ECM_REQUEST *get_ecmtask()
1443{
1444  int i, n;
1445  ECM_REQUEST *er=0;
1446
1447  if (!ecmtask)
1448  {
1449    n=(ph[client[cs_idx].ctyp].multi)?CS_MAXPENDING:1;
1450    if( (ecmtask=(ECM_REQUEST *)malloc(n*sizeof(ECM_REQUEST))) )
1451      memset(ecmtask, 0, n*sizeof(ECM_REQUEST));
1452  }
1453
1454  n=(-1);
1455  if (!ecmtask)
1456  {
1457    cs_log("Cannot allocate memory (errno=%d)", errno);
1458    n=(-2);
1459  }
1460  else
1461    if (ph[client[cs_idx].ctyp].multi)
1462    {
1463      for (i=0; (n<0) && (i<CS_MAXPENDING); i++)
1464        if (ecmtask[i].rc<100)
1465          er=&ecmtask[n=i];
1466    }
1467    else
1468      er=&ecmtask[n=0];
1469
1470  if (n<0)
1471    cs_log("WARNING: ecm pending table overflow !");
1472  else
1473  {
1474    memset(er, 0, sizeof(ECM_REQUEST));
1475    er->rc=100;
1476    er->cpti=n;
1477    er->cidx=cs_idx;
1478    cs_ftime(&er->tps);
1479  }
1480  return(er);
1481}
1482
1483int send_dcw(ECM_REQUEST *er)
1484{
1485  static char *stxt[]={"found", "cache1", "cache2", "emu",
1486                       "not found", "timeout", "sleeping",
1487                       "fake", "invalid", "corrupt"};
1488  static char *stxtEx[]={"", "group", "caid", "ident", "class", "chid", "queue"};
1489  static char *stxtWh[]={"", "user ", "reader ", "server ", "lserver "};
1490  char sby[32]="";
1491  char erEx[32]="";
1492  char uname[38]="";
1493  struct timeb tpe;
1494  ushort lc, *lp;
1495  for (lp=(ushort *)er->ecm+(er->l>>2), lc=0; lp>=(ushort *)er->ecm; lp--)
1496    lc^=*lp;
1497  cs_ftime(&tpe);
1498  if(er->gbxFrom)
1499    snprintf(uname,sizeof(uname)-1, "%s(%04X)", username(cs_idx), er->gbxFrom);
1500  else
1501    snprintf(uname,sizeof(uname)-1, "%s", username(cs_idx));
1502  if (er->rc==0)
1503  {
1504    if(reader[er->reader[0]].typ==R_GBOX)
1505      snprintf(sby, sizeof(sby)-1, " by %s(%04X)", reader[er->reader[0]].label,er->gbxCWFrom);
1506    else
1507      snprintf(sby, sizeof(sby)-1, " by %s", reader[er->reader[0]].label);
1508  }
1509  if (er->rc<4) er->rcEx=0;
1510  if (er->rcEx)
1511    snprintf(erEx, sizeof(erEx)-1, "rejected %s%s", stxtWh[er->rcEx>>4],
1512             stxtEx[er->rcEx&0xf]);
1513  cs_log("%s (%04X&%06X/%04X/%02X:%04X): %s (%d ms)%s",
1514         uname, er->caid, er->prid, er->srvid, er->l, lc, 
1515         er->rcEx?erEx:stxt[er->rc],
1516         1000*(tpe.time-er->tps.time)+tpe.millitm-er->tps.millitm, sby);
1517  er->caid=er->ocaid;
1518  switch(er->rc)
1519  {
1520    case  2:
1521    case  1: client[cs_idx].cwcache++;
1522    case  3:
1523    case  0: client[cs_idx].cwfound++;   break;
1524    default: client[cs_idx].cwnot++;
1525             if (er->rc>5)
1526               client[cs_idx].cwcache++;
1527  }
1528#ifdef CS_ANTICASC
1529  ac_chk(er, 1);
1530#endif
1531
1532  if( cfg->show_ecm_dw && !client[cs_idx].dbglvl )
1533    cs_dump(er->cw, 16, 0);
1534  if (er->rc==7) er->rc=0;
1535  ph[client[cs_idx].ctyp].send_dcw(er);
1536  return 0;
1537}
1538
1539static void chk_dcw(int fd)
1540{
1541  ECM_REQUEST *er, *ert;
1542  if (read_from_pipe(fd, (uchar **)&er, 0)!=PIP_ID_ECM)
1543    return;
1544  //cs_log("dcw check from reader %d for idx %d (rc=%d)", er->reader[0], er->cpti, er->rc);
1545  ert=&ecmtask[er->cpti];
1546  if (ert->rc<100)
1547    return; // already done
1548  if( (er->caid!=ert->caid) || memcmp(er->ecm , ert->ecm , sizeof(er->ecm)) )
1549    return; // obsolete
1550  ert->rcEx=er->rcEx;
1551  if (er->rc>0) // found
1552  {
1553    ert->rc=(er->rc==2)?2:0;
1554    ert->rcEx=0;
1555    ert->reader[0]=er->reader[0];
1556    memcpy(ert->cw , er->cw , sizeof(er->cw));
1557    ert->gbxCWFrom=er->gbxCWFrom;
1558  }
1559  else      // not found (from ONE of the readers !)
1560  {
1561    int i;
1562    ert->reader[er->reader[0]]=0;
1563    for (i=0; (ert) && (i<CS_MAXREADER); i++)
1564      if (ert->reader[i])   // we have still another chance
1565        ert=(ECM_REQUEST *)0;
1566    if (ert) ert->rc=4;
1567  }
1568  if (ert) send_dcw(ert);
1569  return;
1570}
1571
1572ulong chk_provid(uchar *ecm, ushort caid)
1573{
1574  int i;
1575  ulong provid=0;
1576  switch(caid)
1577  {
1578    case 0x100:         // seca
1579      provid=b2i(2, ecm+3);
1580      break;
1581    case 0x500:         // viaccess
1582      i=(ecm[4]==0xD2) ? ecm[5] + 2 : 0;    // skip d2 nano
1583      if ((ecm[5+i]==3) && ((ecm[4+i]==0x90) || (ecm[4+i]==0x40)))
1584        provid=(b2i(3, ecm+6+i) & 0xFFFFF0);
1585    default:
1586      // cryptoworks ?
1587      if( caid&0x0d00 && ecm[8]==0x83 && ecm[9]==1 )
1588        provid=(ulong)ecm[10];
1589  }
1590  return(provid);
1591}
1592
1593/*
1594void guess_irdeto(ECM_REQUEST *er)
1595{
1596  uchar  b3;
1597  int    b47;
1598  //ushort chid;
1599  struct s_irdeto_quess *ptr;
1600
1601  b3  = er->ecm[3];
1602  ptr = cfg->itab[b3];
1603  if( !ptr ) {
1604    cs_debug("unknown irdeto byte 3: %02X", b3);
1605    return;
1606  }
1607  b47  = b2i(4, er->ecm+4);
1608  //chid = b2i(2, er->ecm+6);
1609  //cs_debug("ecm: b47=%08X, ptr->b47=%08X, ptr->caid=%04X", b47, ptr->b47, ptr->caid);
1610  while( ptr )
1611  {
1612    if( b47==ptr->b47 )
1613    {
1614      if( er->srvid && (er->srvid!=ptr->sid) )
1615      {
1616        cs_debug("sid mismatched (ecm: %04X, guess: %04X), wrong oscam.ird file?",
1617                  er->srvid, ptr->sid);
1618        return;
1619      }
1620      er->caid=ptr->caid;
1621      er->srvid=ptr->sid;
1622      er->chid=(ushort)ptr->b47;
1623//      cs_debug("quess_irdeto() found caid=%04X, sid=%04X, chid=%04X",
1624//               er->caid, er->srvid, er->chid);
1625      return;
1626    }
1627    ptr=ptr->next;
1628  }
1629}
1630*/
1631
1632void guess_cardsystem(ECM_REQUEST *er)
1633{
1634  ushort last_hope=0;
1635
1636  // viaccess - check by provid-search
1637  if( (er->prid=chk_provid(er->ecm, 0x500)) )
1638    er->caid=0x500;
1639
1640  // nagra
1641  // is ecm[1] always 0x30 ?
1642  // is ecm[3] always 0x07 ?
1643  if ((er->ecm[6]==1) && (er->ecm[4]==er->ecm[2]-2))
1644    er->caid=0x1801;
1645
1646  // seca2 - very poor
1647  if ((er->ecm[8]==0x10) && ((er->ecm[9]&0xF1)==1))
1648    last_hope=0x100;
1649
1650  // is cryptoworks, but which caid ?
1651  if ((er->ecm[3]==0x81) && (er->ecm[4]==0xFF) &&
1652      (!er->ecm[5]) && (!er->ecm[6]) && (er->ecm[7]==er->ecm[2]-5))
1653    last_hope=0xd00;
1654
1655/*
1656  if (!er->caid && er->ecm[2]==0x31 && er->ecm[0x0b]==0x28)
1657    guess_irdeto(er);
1658*/
1659
1660  if (!er->caid)        // guess by len ..
1661    er->caid=len4caid[er->ecm[2]+3];
1662
1663  if (!er->caid)
1664    er->caid=last_hope;
1665}
1666
1667void request_cw(ECM_REQUEST *er, int flag, int reader_types)
1668{
1669  int i;
1670  if ((reader_types == 0) || (reader_types == 2))
1671    er->level=flag;
1672  flag=(flag)?3:1;      // flag specifies with/without fallback-readers
1673  for (i=0; i<CS_MAXREADER; i++)
1674  {
1675      switch (reader_types)
1676      {
1677          // network and local cards
1678          default:
1679          case 0: 
1680              if (er->reader[i]&flag)
1681                  write_ecm_request(reader[i].fd, er);
1682              break;
1683              // only local cards 
1684          case 1: 
1685              if (!(reader[i].typ & R_IS_NETWORK))
1686                  if (er->reader[i]&flag)
1687                      write_ecm_request(reader[i].fd, er);
1688              break;
1689              // only network
1690          case 2: 
1691              if ((reader[i].typ & R_IS_NETWORK))
1692                  if (er->reader[i]&flag)
1693                      write_ecm_request(reader[i].fd, er);
1694              break;
1695      }
1696  }
1697}
1698
1699void get_cw(ECM_REQUEST *er)
1700{
1701  int i, j, m, rejected;
1702  //uchar orig_caid[sizeof(er->caid)];
1703  time_t now;
1704//test the guessing ...
1705//cs_log("caid should be %04X, provid %06X", er->caid, er->prid);
1706//er->caid=0;
1707
1708  client[cs_idx].lastecm=time((time_t)0);
1709 
1710  if (!er->caid)
1711    guess_cardsystem(er);
1712
1713  if( (er->caid & 0xFF00)==0x600 && !er->chid )
1714    er->chid = (er->ecm[6]<<8)|er->ecm[7];
1715
1716  if (!er->prid)
1717    er->prid=chk_provid(er->ecm, er->caid);
1718
1719// quickfix for 0100:000065
1720  if (er->caid == 0x100 && er->prid == 0x65 && er->srvid == 0)
1721    er->srvid = 0x0642;
1722
1723  if( (!er->prid) && client[cs_idx].ncd_server )
1724  {
1725    int pi = client[cs_idx].port_idx;
1726    if( pi>=0 && cfg->ncd_ptab.nports && cfg->ncd_ptab.nports >= pi )
1727      er->prid = cfg->ncd_ptab.ports[pi].ftab.filts[0].prids[0];
1728  }
1729
1730//cs_log("caid IS NOW .. %04X, provid %06X", er->caid, er->prid);
1731
1732  rejected=0;
1733  if (er->rc>99)        // rc<100 -> ecm error
1734  {
1735    now=time((time_t *) 0);
1736    m=er->caid;
1737    er->ocaid=er->caid;
1738
1739    i=er->srvid;
1740    if ((i!=client[cs_idx].last_srvid) || (!client[cs_idx].lastswitch))
1741      client[cs_idx].lastswitch=now;
1742    if ((client[cs_idx].tosleep) &&
1743        (now-client[cs_idx].lastswitch>client[cs_idx].tosleep))
1744      er->rc=6; // sleeping
1745    client[cs_idx].last_srvid=i;
1746    client[cs_idx].last_caid=m;
1747
1748    for (j=0; (j<6) && (er->rc>99); j++)
1749      switch(j) 
1750      {
1751        case 0: if (client[cs_idx].dup)
1752                  er->rc=7; // fake
1753                break;
1754        case 1: if (!chk_bcaid(er, &client[cs_idx].ctab)) 
1755                {
1756//                  cs_log("chk_bcaid failed");
1757                  er->rc=8; // invalid
1758                  er->rcEx=E2_CAID;
1759                }
1760                break;
1761        case 2: if (!chk_srvid(er, cs_idx))
1762                  er->rc=8;
1763                break;
1764        case 3: if (!chk_ufilters(er))
1765                  er->rc=8;
1766                break;
1767        case 4: if (!chk_sfilter(er, ph[client[cs_idx].ctyp].ptab))
1768                  er->rc=8;
1769                break;
1770        case 5: if( (i=er->l-(er->ecm[2]+3)) )
1771                {
1772                  if (i>0)
1773                  {
1774                    cs_debug("warning: ecm size adjusted from 0x%X to 0x%X", 
1775                      er->l, er->ecm[2]+3);
1776                    er->l=(er->ecm[2]+3);
1777                  }
1778                  else
1779                    er->rc=9;   // corrupt
1780                }
1781                break;
1782      }
1783
1784    if (&client[cs_idx].ttab)  // Betatunneling
1785    // moved behind the check routines, because newcamd-ECM will fail if ecm is converted before
1786    {
1787      int n;
1788      ulong mask_all=0xFFFF;
1789      TUNTAB *ttab;
1790      ttab=&client[cs_idx].ttab;
1791      for (n=0; (n<CS_MAXTUNTAB); n++)
1792      if ((er->caid==ttab->bt_caidfrom[n]) && ((er->srvid==ttab->bt_srvid[n]) || (ttab->bt_srvid[n])==mask_all))
1793      {
1794        int l;
1795        char hack_n3[13]={0x70, 0x51, 0xc7, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x87, 0x12, 0x07};
1796        char hack_n2[13]={0x70, 0x51, 0xc9, 0x00, 0x00, 0x00, 0x01, 0x10, 0x10, 0x00, 0x48, 0x12, 0x07};
1797        er->caid=ttab->bt_caidto[n];
1798        er->prid=0;
1799        er->l=(er->ecm[2]+3);
1800        memmove(er->ecm+14, er->ecm+4, er->l-1);
1801        if (er->l > 0x88)
1802        {
1803           memcpy(er->ecm+1, hack_n3, 13);
1804           if (er->ecm[0]==0x81) er->ecm[12]+= 1;
1805        }
1806        else memcpy(er->ecm+1, hack_n2, 13);
1807        er->l+=10;
1808        er->ecm[2]=er->l-3;
1809        cs_debug("ecm converted from: 0x%X to betacrypt: 0x%X for service id:0x%X",
1810                 ttab->bt_caidfrom[n], ttab->bt_caidto[n], ttab->bt_srvid[n]);
1811      }
1812    }
1813
1814    memcpy(er->ecmd5, MD5(er->ecm, er->l, NULL), CS_ECMSTORESIZE);
1815
1816    if (check_ecmcache(er, client[cs_idx].grp))
1817      er->rc=1; // cache1
1818
1819#ifdef CS_ANTICASC
1820    ac_chk(er, 0);
1821#endif
1822    if( er->rc<100 && er->rc!=1 )
1823      rejected=1;
1824  }
1825
1826  if( !rejected && er->rc!=1 )
1827  {
1828    for (i=m=0; i<CS_MAXREADER; i++)
1829      if (matching_reader(er, &reader[i])&&(i!=ridx))
1830        m|=er->reader[i]=(reader[i].fallback)?2:1;
1831
1832    switch(m)
1833    {
1834      case 0: er->rc=4;                         // no reader -> not found
1835              if (!er->rcEx) er->rcEx=E2_GROUP; 
1836              break;                           
1837      case 2: for (i=0; i<CS_MAXREADER; i++)    // fallbacks only, switch them.
1838                er->reader[i]>>=1;
1839    }
1840  }
1841  if (er->rc<100)
1842  {
1843    if (cfg->delay) usleep(cfg->delay);
1844    send_dcw(er);
1845    return;
1846  }
1847
1848  er->rcEx=0; 
1849  request_cw(er, 0, cfg->preferlocalcards ? 1 : 0);
1850}
1851
1852void log_emm_request(int auidx)
1853{
1854//  cs_log("%s send emm-request (reader=%s, caid=%04X)",
1855//         cs_inet_ntoa(client[cs_idx].ip), reader[auidx].label, reader[auidx].caid[0]);
1856  cs_log("%s emm-request sent (reader=%s, caid=%04X)",
1857         username(cs_idx), reader[auidx].label, reader[auidx].caid[0]);
1858}
1859
1860void do_emm(EMM_PACKET *ep)
1861{
1862  int au;//, ephs;
1863  au=client[cs_idx].au;
1864
1865  if ((au<0) || (au>=CS_MAXREADER))
1866    return;
1867  client[cs_idx].lastemm=time((time_t)0);
1868  cs_ddump(reader[au].hexserial, 8, "reader serial:");
1869  cs_ddump(ep->hexserial, 8, "emm SA:");
1870//  if ((!reader[au].fd) || (reader[au].b_nano[ep->emm[3]])) // blocknano is obsolete
1871  if ((!reader[au].fd) ||               // reader has no fd
1872      (reader[au].caid[0]!=b2i(2,ep->caid)) ||      // wrong caid
1873      (memcmp(reader[au].hexserial, ep->hexserial, 8))) // wrong serial
1874    return;
1875
1876  ep->cidx=cs_idx;
1877  write_to_pipe(reader[au].fd, PIP_ID_EMM, (uchar *) ep, sizeof(EMM_PACKET));
1878}
1879
1880static int comp_timeb(struct timeb *tpa, struct timeb *tpb)
1881{
1882  if (tpa->time>tpb->time) return(1);
1883  if (tpa->time<tpb->time) return(-1);
1884  if (tpa->millitm>tpb->millitm) return(1);
1885  if (tpa->millitm<tpb->millitm) return(-1);
1886  return(0);
1887}
1888
1889static void build_delay(struct timeb *tpe, struct timeb *tpc)
1890{
1891  if (comp_timeb(tpe, tpc)>0)
1892  {
1893    tpe->time=tpc->time;
1894    tpe->millitm=tpc->millitm;
1895  }
1896}
1897
1898struct timeval *chk_pending(struct timeb tp_ctimeout)
1899{
1900  int i;
1901  ulong td;
1902  struct timeb tpn, tpe, tpc;   // <n>ow, <e>nd, <c>heck
1903  static struct timeval tv;
1904
1905  ECM_REQUEST *er;
1906  cs_ftime(&tpn);
1907  tpe=tp_ctimeout;      // latest delay -> disconnect
1908
1909  if (ecmtask)
1910    i=(ph[client[cs_idx].ctyp].multi)?CS_MAXPENDING:1;
1911  else
1912    i=0;
1913//cs_log("num pend=%d", i);
1914  for (--i; i>=0; i--)
1915    if (ecmtask[i].rc>=100) // check all pending ecm-requests
1916    {
1917      int act, j;
1918      er=&ecmtask[i];
1919      tpc=er->tps;
1920      tpc.millitm += (er->stage) ? cfg->ctimeout : cfg->ftimeout;
1921      tpc.time += tpc.millitm / 1000;
1922      tpc.millitm = tpc.millitm % 1000;
1923      if (!er->stage)
1924      {
1925        for (j=0, act=1; (act) && (j<CS_MAXREADER); j++)
1926        {
1927            if (cfg->preferlocalcards && !er->locals_done)
1928            {
1929                if ((er->reader[j]&1) && !(reader[j].typ & R_IS_NETWORK))
1930                    act=0;
1931            }
1932            else if (cfg->preferlocalcards && er->locals_done)
1933            {
1934                if ((er->reader[j]&1) && (reader[j].typ & R_IS_NETWORK))
1935                    act=0;
1936            }
1937            else
1938            {
1939                if (er->reader[j]&1)
1940                    act=0;
1941            }
1942        }
1943//cs_log("stage 0, act=%d r0=%d, r1=%d, r2=%d, r3=%d, r4=%d r5=%d", act,
1944//      er->reader[0], er->reader[1], er->reader[2],
1945//      er->reader[3], er->reader[4], er->reader[5]);
1946        if (act)
1947        {
1948          int inc_stage = 1;
1949
1950          if (cfg->preferlocalcards && !er->locals_done)
1951          {
1952              int i;
1953
1954              er->locals_done = 1;
1955              for (i = 0; i < CS_MAXREADER; i++)
1956              {
1957                  if (reader[i].typ & R_IS_NETWORK)
1958                  {
1959                      inc_stage = 0;
1960                  }
1961              }
1962          }
1963          if (!inc_stage)
1964          {
1965              request_cw(er, er->stage, 2);
1966              tpc.millitm += 1000 * (tpn.time - er->tps.time) + tpn.millitm - er->tps.millitm;
1967              tpc.time += tpc.millitm / 1000;
1968              tpc.millitm = tpc.millitm % 1000;
1969          }
1970          else
1971          {
1972              er->locals_done = 0;
1973              er->stage++;
1974              request_cw(er, er->stage, cfg->preferlocalcards ? 1 : 0); 
1975
1976              tpc.millitm += (cfg->ctimeout-cfg->ftimeout);
1977              tpc.time += tpc.millitm / 1000;
1978              tpc.millitm = tpc.millitm % 1000;
1979          }
1980        }
1981      }
1982      if (comp_timeb(&tpn, &tpc)>0) // action needed
1983      {
1984//cs_log("Action now %d.%03d", tpn.time, tpn.millitm);
1985//cs_log("           %d.%03d", tpc.time, tpc.millitm);
1986        if (er->stage)
1987        {
1988          er->rc=5; // timeout
1989          send_dcw(er);
1990          continue;
1991        }
1992        else
1993        {
1994          er->stage++;
1995          request_cw(er, er->stage, 0);
1996          tpc.millitm += (cfg->ctimeout-cfg->ftimeout);
1997          tpc.time += tpc.millitm / 1000;
1998          tpc.millitm = tpc.millitm % 1000;
1999        }
2000      }
2001      build_delay(&tpe, &tpc);
2002    }
2003  td=(tpe.time-tpn.time)*1000+(tpe.millitm-tpn.millitm)+5;
2004  tv.tv_sec = td/1000;
2005  tv.tv_usec = (td%1000)*1000;
2006//cs_log("delay %d.%06d", tv.tv_sec, tv.tv_usec);
2007  return(&tv);
2008}
2009
2010int process_input(uchar *buf, int l, int timeout)
2011{
2012  int rc;
2013  fd_set fds;
2014  struct timeb tp;
2015
2016  if (master_pid!=getppid()) cs_exit(0);
2017  if (!pfd) return(-1);
2018  cs_ftime(&tp);
2019  tp.time+=timeout;
2020  if (ph[client[cs_idx].ctyp].watchdog)
2021      alarm(cfg->cmaxidle + (cfg->ctimeout + 500) / 1000 + 1);
2022  while (1)
2023  {
2024    FD_ZERO(&fds);
2025    FD_SET(pfd, &fds);
2026    FD_SET(fd_m2c, &fds);
2027
2028    rc=select(((pfd>fd_m2c)?pfd:fd_m2c)+1, &fds, 0, 0, chk_pending(tp));
2029    if (master_pid!=getppid()) cs_exit(0);
2030    if (rc<0) 
2031    {
2032      if (errno==EINTR) continue;
2033      else return(0);
2034    }
2035
2036    if (FD_ISSET(fd_m2c, &fds))     // read from pipe
2037      chk_dcw(fd_m2c);
2038
2039    if (FD_ISSET(pfd, &fds))        // read from client
2040    {
2041      rc=ph[client[cs_idx].ctyp].recv(buf, l);
2042      break;
2043    }
2044    if (tp.time<=time((time_t *)0)) // client maxidle reached
2045    {
2046      rc=(-9);
2047      break;
2048    }
2049  }
2050  if (ph[client[cs_idx].ctyp].watchdog)
2051      alarm(cfg->cmaxidle + (cfg->ctimeout + 500) / 1000 + 1);
2052  return(rc);
2053}
2054
2055static void process_master_pipe()
2056{
2057  int n;
2058  uchar *ptr;
2059
2060  switch(n=read_from_pipe(mfdr, &ptr, 1))
2061  {
2062    case PIP_ID_LOG:
2063      cs_write_log(ptr);
2064      break;
2065    case PIP_ID_HUP:
2066      cs_accounts_chk();
2067      break;
2068  }
2069}
2070
2071void cs_log_config()
2072{
2073  uchar buf[2048];
2074
2075  if (cfg->nice!=99)
2076    sprintf((char *)buf, ", nice=%d", cfg->nice);
2077  else
2078    buf[0]='\0';
2079  cs_log("version=%s, system=%s%s", CS_VERSION_X, cs_platform((char *)buf+64), buf);
2080  cs_log("max. clients=%d, client max. idle=%d sec",
2081#ifdef CS_ANTICASC
2082         CS_MAXPID-3, cfg->cmaxidle);
2083#else
2084         CS_MAXPID-2, cfg->cmaxidle);
2085#endif
2086  if( cfg->max_log_size )
2087    sprintf((char *)buf, "%d Kb", cfg->max_log_size);
2088  else
2089    strcpy((char *)buf, "unlimited");
2090  cs_log("max. logsize=%s", buf);
2091  cs_log("client timeout=%lu ms, fallback timeout=%lu ms, cache delay=%d ms",
2092         cfg->ctimeout, cfg->ftimeout, cfg->delay);
2093#ifdef CS_NOSHM
2094  cs_log("shared memory initialized (size=%d, fd=%d)", shmsize, shmid);
2095#else
2096  cs_log("shared memory initialized (size=%d, id=%d)", shmsize, shmid);
2097#endif
2098}
2099
2100int main (int argc, char *argv[])
2101{
2102  struct   sockaddr_in cad;     /* structure to hold client's address */
2103  int      scad;                /* length of address */
2104  //int      fd;                  /* socket descriptors */
2105  int      i, j, n;
2106  int      bg=0;
2107  int      gfd; //nph,
2108  int      fdp[2];
2109  uchar    buf[2048];
2110  void (*mod_def[])(struct s_module *)=
2111  {
2112           module_monitor,
2113           module_camd33,
2114           module_camd35,
2115           module_camd35_tcp,
2116           module_newcamd,
2117#ifdef CS_WITH_GBOX
2118           module_gbox,
2119#endif
2120           module_radegast,
2121           module_oscam_ser,
2122           0
2123  };
2124
2125  while ((i=getopt(argc, argv, "bc:d:hm:"))!=EOF)
2126  {
2127    switch(i)
2128    {
2129      case 'b': bg=1;
2130                break;
2131      case 'c': strncpy(cs_confdir, optarg, sizeof(cs_confdir)-1);
2132                break;
2133      case 'd': cs_dblevel=atoi(optarg);
2134                break;
2135      case 'm':
2136#ifdef CS_NOSHM
2137                strncpy(cs_memfile, optarg, sizeof(cs_memfile)-1);
2138                break;
2139#endif
2140      case 'h':
2141      default : usage();
2142    }
2143  }
2144  if (cs_confdir[strlen(cs_confdir)]!='/') strcat(cs_confdir, "/");
2145  init_shm();
2146  init_config();
2147  for (i=0; mod_def[i]; i++)    // must be later BEFORE init_config()
2148  {
2149    memset(&ph[i], 0, sizeof(struct s_module));
2150    mod_def[i](&ph[i]);
2151  }
2152
2153  cs_log("auth size=%d", sizeof(struct s_auth));
2154  //cs_log_config();
2155  cfg->delay*=1000;
2156  init_sidtab();
2157  init_readerdb();
2158  init_userdb();
2159  init_signal();
2160  cs_set_mloc(30, "init");
2161  init_srvid();
2162  init_len4caid();
2163  //init_irdeto_guess_tab();
2164  cs_init_statistics(cfg->usrfile);
2165
2166  if (pipe(fdp))
2167  {
2168    cs_log("Cannot create pipe (errno=%d)", errno);
2169    cs_exit(1);
2170  }
2171  mfdr=fdp[0];
2172  fd_c2m=fdp[1];
2173  gfd=mfdr+1;
2174
2175#ifdef OS_MACOSX
2176  if (bg && daemon_compat(1,0))
2177#else
2178  if (bg && daemon(1,0))
2179#endif
2180  {
2181    cs_log("Error starting in background (errno=%d)", errno);
2182    cs_exit(1);
2183  }
2184  master_pid=client[0].pid=getpid();
2185  if (cfg->pidfile[0])
2186  {
2187    FILE *fp;
2188    if (!(fp=fopen(cfg->pidfile, "w")))
2189    {
2190      cs_log("Cannot open pid-file (errno=%d)", errno);
2191      cs_exit(1);
2192    }
2193    fprintf(fp, "%d\n", getpid());
2194    fclose(fp);
2195  }
2196
2197  for (i=0; i<CS_MAX_MOD; i++)
2198    if( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
2199      for(j=0; j<ph[i].ptab->nports; j++) 
2200      {
2201        start_listener(&ph[i], j);
2202        if( ph[i].ptab->ports[j].fd+1>gfd )
2203          gfd=ph[i].ptab->ports[j].fd+1;
2204      }
2205
2206  start_client_resolver();
2207  init_service(97); // logger
2208  init_service(98); // resolver
2209  init_cardreader();
2210 
2211  if (cfg->waitforcards)
2212  {
2213      int card_init_done;
2214
2215      cs_log("Waiting for local card init ....");
2216
2217      sleep(3);  // short sleep for card detect to work proberly
2218
2219      for(;;)
2220      {
2221          card_init_done = 1;
2222
2223          for (i = 0; i < CS_MAXREADER; i++)
2224          {
2225              if (!reader[i].online && reader[i].card_status)
2226              {
2227                  if (!(reader[i].card_status & CARD_FAILURE))
2228                  {
2229                      card_init_done = 0;
2230                      break;
2231                  }
2232              }
2233          }
2234
2235          if (card_init_done)
2236              break;
2237
2238          cs_sleepms(300);              // wait a little bit
2239
2240          alarm(cfg->cmaxidle + cfg->ctimeout / 1000 + 1); 
2241      }
2242
2243      cs_log("Init for all local cards done !");
2244  }
2245 
2246
2247#ifdef CS_ANTICASC
2248  if( !cfg->ac_enabled )
2249    cs_log("anti cascading disabled");
2250  else 
2251  {
2252    init_ac();
2253    init_service(96);
2254  }
2255#endif
2256
2257  for (i=0; i<CS_MAX_MOD; i++)
2258    if (ph[i].type & MOD_CONN_SERIAL)       // for now: oscam_ser only
2259      if (ph[i].s_handler)
2260        ph[i].s_handler(i);
2261
2262  cs_close_log();
2263  *mcl=1;
2264  while (1)
2265  {
2266    fd_set fds;
2267
2268    do
2269    {
2270      FD_ZERO(&fds);
2271      FD_SET(mfdr, &fds);
2272      for (i=0; i<CS_MAX_MOD; i++)
2273        if ( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
2274          for (j=0; j<ph[i].ptab->nports; j++)
2275            if (ph[i].ptab->ports[j].fd)
2276              FD_SET(ph[i].ptab->ports[j].fd, &fds);
2277      errno=0;
2278      cs_set_mloc(0, "before select");
2279      select(gfd, &fds, 0, 0, 0);
2280      cs_set_mloc(60, "after select");
2281    } while (errno==EINTR);
2282    cs_set_mloc(-1, "event (global)");
2283
2284    client[0].last=time((time_t *)0);
2285    scad = sizeof(cad);
2286    if (FD_ISSET(mfdr, &fds))
2287    {
2288      cs_set_mloc(-1, "event: master-pipe");
2289      process_master_pipe();
2290    }
2291    for (i=0; i<CS_MAX_MOD; i++)
2292    {
2293      if( (ph[i].type & MOD_CONN_NET) && ph[i].ptab )
2294      {
2295        for( j=0; j<ph[i].ptab->nports; j++ )
2296        {
2297          if( ph[i].ptab->ports[j].fd && FD_ISSET(ph[i].ptab->ports[j].fd, &fds) )
2298          {
2299            if (ph[i].type==MOD_CONN_UDP)
2300            {
2301              cs_set_mloc(-1, "event: udp-socket");
2302              if ((n=recvfrom(ph[i].ptab->ports[j].fd, buf+3, sizeof(buf)-3, 0, (struct sockaddr *)&cad, (socklen_t *)&scad))>0)
2303              {
2304                int idx;
2305                idx=idx_from_ip(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port));
2306                if (!idx)
2307                {
2308                  if (pipe(fdp))
2309                  {
2310                    cs_log("Cannot create pipe (errno=%d)", errno);
2311                    cs_exit(1);
2312                  }
2313                  switch(cs_fork(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port)))
2314                  {
2315                  case -1:
2316                    close(fdp[0]);
2317                    close(fdp[1]);
2318                    break;
2319                  case  0:
2320                    client[idx=cs_last_idx].ufd=fdp[1];
2321                    close(fdp[0]);
2322                    break;
2323                  default:
2324//                    close(fdp[1]);    // now used to simulate event
2325                    pfd=fdp[0];
2326                    wait4master();
2327                    client[cs_idx].ctyp=i;
2328                    client[cs_idx].port_idx=j; 
2329                    client[cs_idx].udp_fd=ph[i].ptab->ports[j].fd;
2330                    client[cs_idx].udp_sa=cad;
2331                    if (ph[client[cs_idx].ctyp].watchdog)
2332                        alarm(cfg->cmaxidle + cfg->ctimeout / 1000 + 1);
2333                    ph[i].s_handler(cad);       // never return
2334                  }
2335                }
2336                if (idx)
2337                {
2338                  unsigned short rl;
2339                  rl=n;
2340                  buf[0]='U';
2341                  memcpy(buf+1, &rl, 2);
2342                  if (!write(client[idx].ufd, buf, n+3)) cs_exit(1);
2343                }
2344              }
2345            }
2346            else
2347            {
2348              cs_set_mloc(-1, "event: tcp-socket");
2349              if ((pfd=accept(ph[i].ptab->ports[j].fd, (struct sockaddr *)&cad, (socklen_t *)&scad))>0)
2350              {
2351                switch(cs_fork(cs_inet_order(cad.sin_addr.s_addr), ntohs(cad.sin_port)))
2352                {
2353                case -1:
2354                case  0:
2355                  close(pfd);
2356                  break;
2357                default:
2358                  wait4master();
2359                  client[cs_idx].ctyp=i;
2360                  client[cs_idx].udp_fd=pfd;
2361                  client[cs_idx].port_idx=j; 
2362                  if (ph[client[cs_idx].ctyp].watchdog)
2363                      alarm(cfg->cmaxidle + cfg->ctimeout / 1000 + 1);
2364                  ph[i].s_handler();
2365                }
2366              }
2367            }
2368          }
2369        }
2370      } // if (ph[i].type & MOD_CONN_NET)
2371    }
2372  }
2373  cs_exit(1);
2374}
Note: See TracBrowser for help on using the repository browser.