⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 3 页
字号:
void cScSetup::Check(void){  if(AutoUpdate==0)    PRINTF(L_GEN_WARN,"Keys updates (AU) are disabled.");  for(int i=0; i<MAXSCCAPS; i++)    if(ScCaps[i]>=16) {      PRINTF(L_GEN_WARN,"ScCaps contains unusual value. Check your config! (You can ignore this message if you have more than 16 dvb cards in your system ;)");      break;      }  PRINTF(L_CORE_LOAD,"** Plugin config:");  PRINTF(L_CORE_LOAD,"** Key updates (AU) are %s",AutoUpdate?(AutoUpdate==1?"enabled (active CAIDs)":"enabled (all CAIDs)"):"DISABLED");  PRINTF(L_CORE_LOAD,"** Local systems %stake priority over cached remote",LocalPriority?"":"DON'T ");  PRINTF(L_CORE_LOAD,"** Concurrent FF recordings are %sallowed",ConcurrentFF?"":"NOT ");  PRINTF(L_CORE_LOAD,"** %sorce transfermode with digital auido",ForceTransfer?"F":"DON'T f");  LBSTART(L_CORE_LOAD);  LBPUT("** ScCaps are"); for(int i=0; i<MAXSCCAPS ; i++) LBPUT(" %d",ScCaps[i]);  LBFLUSH();  LBPUT("** Ignored CAIDs"); for(int i=0; i<MAXCAIGN ; i++) LBPUT(" %04X",CaIgnore[i]);  LBEND();}void cScSetup::Store(bool AsIs){  if(ScOpts) ScOpts->Store(AsIs);  cSystems::ConfigStore(AsIs);  if(LogOpts) LogOpts->Store(AsIs);  cLineBuff lb(128);  if(cLogging::GetConfig(&lb))    ScPlugin->SetupStore("LogConfig",lb.Line());}bool cScSetup::CapCheck(int n){  for(int j=0; j<MAXSCCAPS; j++)    if(ScCaps[j] && ScCaps[j]==n+1) return true;  return false;}bool cScSetup::Ignore(unsigned short caid){  for(int i=0; i<MAXCAIGN; i++)    if(CaIgnore[i]==caid) return true;  return false;}// --- cSoftCAM ---------------------------------------------------------------bool cSoftCAM::Load(const char *cfgdir){  ecmcache.Load();  if(Feature.KeyFile() && !keys.Load(cfgdir))     PRINTF(L_GEN_ERROR,"no keys loaded for softcam!");  if(!cSystems::Init(cfgdir)) return false;  if(Feature.SmartCard()) smartcards.LoadData(cfgdir);  cLoaders::LoadCache(cfgdir);  cLoaders::SaveCache();  return true;}void cSoftCAM::Shutdown(void){  cSystems::Clean();  smartcards.Shutdown();  keys.Clear();}char *cSoftCAM::CurrKeyStr(int CardNum, int num){  cScDvbDevice *dev=dynamic_cast<cScDvbDevice *>(cDevice::GetDevice(CardNum));  char *str=0;  if(dev) {    if(dev->Cam()) str=dev->Cam()->CurrentKeyStr(num);    if(!str && num==0 && ScSetup.CapCheck(CardNum)) str=strdup(tr("(none)"));    }  return str;}bool cSoftCAM::Active(void){  for(int n=cDevice::NumDevices(); --n>=0;) {    cScDvbDevice *dev=dynamic_cast<cScDvbDevice *>(cDevice::GetDevice(n));    if(dev && dev->Cam() && dev->Cam()->Active()) return true;    }  return false;}void cSoftCAM::SetLogStatus(int CardNum, const cEcmInfo *ecm, bool on){  cScDvbDevice *dev=dynamic_cast<cScDvbDevice *>(cDevice::GetDevice(CardNum));  if(dev && dev->Cam()) dev->Cam()->LogEcmStatus(ecm,on);}void cSoftCAM::AddHook(int CardNum, cLogHook *hook){  cScDvbDevice *dev=dynamic_cast<cScDvbDevice *>(cDevice::GetDevice(CardNum));  if(dev && dev->Cam()) dev->Cam()->AddHook(hook);}bool cSoftCAM::TriggerHook(int CardNum, int id){  cScDvbDevice *dev=dynamic_cast<cScDvbDevice *>(cDevice::GetDevice(CardNum));  return dev && dev->Cam() && dev->Cam()->TriggerHook(id);}#ifndef STATICBUILD// --- cScDll ------------------------------------------------------------------class cScDll : public cSimpleItem {private:  char *fileName;  void *handle;public:  cScDll(const char *FileName);  ~cScDll();  bool Load(void);  };cScDll::cScDll(const char *FileName){  fileName=strdup(FileName);  handle=0;}cScDll::~cScDll(){  if(handle) dlclose(handle);  free(fileName);}bool cScDll::Load(void){  char *base=rindex(fileName,'/');  if(!base) base=fileName;  PRINTF(L_CORE_DYN,"loading library: %s",base);  if(!handle) {    handle=dlopen(fileName,RTLD_NOW|RTLD_LOCAL);    if(handle) return true;    PRINTF(L_GEN_ERROR,"dload: %s: %s",base,dlerror());    }  return false;}// --- cScDlls -----------------------------------------------------------------#define LIBSC_PREFIX  "libsc-"#define SO_INDICATOR   ".so."class cScDlls : public cSimpleList<cScDll> {private:  void *handle;public:  cScDlls(void);  ~cScDlls();  bool Load(void);  };cScDlls::cScDlls(void){  handle=0;}cScDlls::~cScDlls(){  Clear();  if(handle) dlclose(handle);  PRINTF(L_CORE_DYN,"unload done");}bool cScDlls::Load(void){  Dl_info info;  static int marker=0;  if(!dladdr((void *)&marker,&info)) {    PRINTF(L_GEN_ERROR,"dladdr: %s",dlerror());    return false;    }  // we have to re-dlopen our selfs as VDR doesn't use RTLD_GLOBAL  // but our symbols have to be available to the sub libs.  handle=dlopen(info.dli_fname,RTLD_NOW|RTLD_GLOBAL);  if(!handle) {    PRINTF(L_GEN_ERROR,"dlopen myself: %s",dlerror());    return false;    }  char *path=strdup(info.dli_fname);  char *p;  if((p=rindex(path,'/'))) *p=0;  PRINTF(L_CORE_DYN,"library path %sn",path);  char pat[32];  snprintf(pat,sizeof(pat),"%s*-%d%s%s",LIBSC_PREFIX,SCAPIVERS,SO_INDICATOR,APIVERSION);  bool res=true;  cReadDir dir(path);  struct dirent *e;  while((e=dir.Next())) {    if(!fnmatch(pat,e->d_name,FNM_PATHNAME|FNM_NOESCAPE)) {      cScDll *dll=new cScDll(AddDirectory(path,e->d_name));      if(dll) {        if(!dll->Load()) res=false;        Ins(dll);        }      }    }  free(path);  return res;}#endif// --- cScPlugin ---------------------------------------------------------------class cScPlugin : public cPlugin {private:  tI18nPhrase *phrases;#ifndef STATICBUILD  cScDlls dlls;#endifpublic:  cScPlugin(void);  virtual ~cScPlugin();  virtual const char *Version(void);  virtual const char *Description(void);  virtual const char *CommandLineHelp(void);  virtual bool ProcessArgs(int argc, char *argv[]);  virtual bool Initialize(void);  virtual bool Start(void);  virtual void Stop(void);  virtual void Housekeeping(void);  virtual cMenuSetupPage *SetupMenu(void);  virtual bool SetupParse(const char *Name, const char *Value);  virtual const char **SVDRPHelpPages(void);  virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);  };cScPlugin::cScPlugin(void){  static const char *logg[] = { "off","active CAIDs","all CAIDs" };  ScOpts=new cOpts(0,6);  ScOpts->Add(new cOptSel  ("AutoUpdate"   ,"Update keys (AU)"     ,&ScSetup.AutoUpdate,3,logg));  ScOpts->Add(new cOptBool ("ConcurrentFF" ,"Concurrent FF streams",&ScSetup.ConcurrentFF));  ScOpts->Add(new cOptBool ("ForceTranfer" ,"Force TransferMode"   ,&ScSetup.ForceTransfer));  ScOpts->Add(new cOptBool ("LocalPriority","Prefer local systems" ,&ScSetup.LocalPriority));  ScOpts->Add(new cOptMInt ("ScCaps"       ,"Active on DVB card"   , ScSetup.ScCaps,MAXSCCAPS,0));  ScOpts->Add(new cOptMInt ("CaIgnore"     ,"Ignore CAID"          , ScSetup.CaIgnore,MAXCAIGN,2));  LogOpts=new cOpts(0,4);  LogOpts->Add(new cOptBool ("LogConsole"  ,"Log to console"      ,&logcfg.logCon));  LogOpts->Add(new cOptBool ("LogFile"     ,"Log to file"         ,&logcfg.logFile));  LogOpts->Add(new cOptStr  ("LogFileName" ,"Filename"            ,logcfg.logFilename,sizeof(logcfg.logFilename),FileNameChars));  LogOpts->Add(new cOptBool ("LogSyslog"   ,"Log to syslog"       ,&logcfg.logSys));  phrases=0;#ifndef STATICBUILD  dlls.Load();#endif  cScDvbDevice::Capture();}cScPlugin::~cScPlugin(){  delete ScOpts;  delete LogOpts;}bool cScPlugin::Initialize(void){  PRINTF(L_GEN_INFO,"SC version %s initializing",ScVersion);  return cScDvbDevice::Initialize();}bool cScPlugin::Start(void){  PRINTF(L_GEN_INFO,"SC version %s starting",ScVersion);  if(APIVERSNUM<MINAPIVERSNUM) {    PRINTF(L_GEN_ERROR,"SC plugin needs at least VDR API version %d.%d.%d",MIN_VERS,MIN_MAJOR,MIN_MINOR);    return false;    }  if(sizeof(int)!=4) {    PRINTF(L_GEN_ERROR,"compiled with 'int' as %d bit. Only supporting 32 bit.",(int)sizeof(int)*8);    return false;    }  if(sizeof(long long)!=8) {    PRINTF(L_GEN_ERROR,"compiled with 'long long' as %d bit. Only supporting 64 bit.",(int)sizeof(long long)*8);    return false;    }      ScPlugin=this;  Feature.AddPhrases(ScPhrases);  RegisterI18n((phrases=Feature.GetPhrases()));  filemaps.SetCfgDir(ConfigDirectory());  ScSetup.Check();  if(!cSoftCAM::Load(ConfigDirectory())) return false;  if(Feature.SmartCard()) {#ifdef DEFAULT_PORT    smartcards.AddPort(DEFAULT_PORT);#endif    smartcards.LaunchWatcher();    }  cScDvbDevice::Startup();  return true;}void cScPlugin::Stop(void){  cScDvbDevice::Shutdown();  LogStatsDown();  cSoftCAM::Shutdown();  RegisterI18n(NULL); free(phrases);  PRINTF(L_GEN_DEBUG,"SC cleanup done");}const char *cScPlugin::Version(void){  return ScVersion;}const char *cScPlugin::Description(void){  return tr("A software emulated CAM");}const char *cScPlugin::CommandLineHelp(void){  static char *help_str=0;    free(help_str);    //                                     for easier orientation, this is column 80|  asprintf(&help_str,"  -B N      --budget=N     forces DVB device N to budget mode (using FFdecsa)\n"                     "  -I        --inverse-cd   use inverse CD detection for the next serial device\n"                     "  -R        --inverse-rst  use inverse RESET for the next serial device\n"                     "  -C FREQ   --clock=FREQ   use FREQ as clock for the card reader on the next\n"                     "                           serial device (rather than 3.5712 MHz\n"                     "  -s DEV,   --serial=DEV   activate Phoenix ISO interface on serial device DEV\n"                     "                           (default: %s)\n"                     "  -d CMD,   --dialup=CMD   call CMD to start/stop dialup-network\n"                     "                           (default: %s)\n"                     "  -t SECS,  --timeout=SECS shutdown timeout for dialup-network\n"                     "                           (default: %d secs)\n",                     "none","none",netTimeout/1000                     );  return help_str;}bool cScPlugin::ProcessArgs(int argc, char *argv[]){  static struct option long_options[] = {      { "serial",      required_argument, NULL, 's' },      { "inverse-cd",  no_argument,       NULL, 'I' },      { "inverse-rst", no_argument,       NULL, 'R' },      { "clock",       required_argument, NULL, 'C' },      { "dialup",      required_argument, NULL, 'd' },      { "external-au", required_argument, NULL, 'E' },      { "budget",      required_argument, NULL, 'B' },      { NULL }    };  int c, option_index=0;  bool invCD=false, invRST=false;  int clock=0;  while((c=getopt_long(argc,argv,"d:s:t:B:C:E:IR",long_options,&option_index))!=-1) {    switch (c) {      case 'I': invCD=true; break;      case 'R': invRST=true; break;      case 'C': clock=atoi(optarg); break;      case 's': smartcards.AddPort(optarg,invCD,invRST,clock); invCD=false; invRST=false; clock=0; break;      case 'd': netscript=optarg; break;      case 't': netTimeout=atoi(optarg)*1000; break;      case 'E': externalAU=optarg; break;      case 'B': cScDvbDevice::SetForceBudget(atoi(optarg)); break;      default:  return false;      }    }  return true;}cMenuSetupPage *cScPlugin::SetupMenu(void){  return new cMenuSetupSc(ConfigDirectory());}bool cScPlugin::SetupParse(const char *Name, const char *Value){  if((ScOpts && ScOpts->Parse(Name,Value)) ||     (LogOpts && LogOpts->Parse(Name,Value)) ||     cSystems::ConfigParse(Name,Value)) ;  else if(!strcasecmp(Name,"LogConfig")) cLogging::ParseConfig(Value);  else return false;  return true;}void cScPlugin::Housekeeping(void){  for(int n=cDevice::NumDevices(); --n>=0;) {    cScDvbDevice *dev=dynamic_cast<cScDvbDevice *>(cDevice::GetDevice(n));    if(dev && dev->Cam()) dev->Cam()->HouseKeeping();    }  if(Feature.KeyFile()) keys.HouseKeeping();}const char **cScPlugin::SVDRPHelpPages(void){  static const char *HelpPages[] = {    "RELOAD\n"    "    Reload all configuration files.",    "LOG <on|off> <class>[,<class>...]\n"    "    Turn the given message class(es) on or off.",    "LOGCFG\n"    "    Display available message classes and their status.",    NULL    };  return HelpPages;}cString cScPlugin::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode){  if(!strcasecmp(Command,"RELOAD")) {    if(cSoftCAM::Active()) {      ReplyCode=550;      return "Softcam active. Can't reload files now";      }    else {      if(cSoftCAM::Load(ConfigDirectory()))        return "Files reloaded successfully";      else {        ReplyCode=901;        return "Reloading files not entirely successfull";        }      }    }  else if(!strcasecmp(Command,"LOG")) {    if(Option && *Option) {      char *opt=strdup(Option);      opt=skipspace(opt);      bool mode;      if(!strncasecmp(opt,"ON ",3)) { mode=true; opt+=3; }      else if(!strncasecmp(opt,"OFF ",4)) { mode=false; opt+=4; }      else { ReplyCode=501; return "Bad mode, valid: on off"; }      do {        char *s=index(opt,',');        if(s) *s++=0;        int c=cLogging::GetClassByName(opt);        if(c>=0) cLogging::SetModuleOption(c,mode);        else { ReplyCode=501; return "Unknown message class"; }        opt=s;        } while(opt);      ScSetup.Store(true);      Setup.Save();      return "Done";      }    else { ReplyCode=501; return "Missing args"; }    }  else if(!strcasecmp(Command,"LOGCFG")) {    cLineBuff lb(256);    for(int m=1; m<LMOD_MAX; m++) {      const char *name=cLogging::GetModuleName(LCLASS(m,0));      if(name) {        int o=cLogging::GetModuleOptions(LCLASS(m,0));        if(o>=0) {          for(int i=0; i<LOPT_NUM; i++) {            const char *opt;            if(i==0) opt="enable";            else opt=cLogging::GetOptionName(LCLASS(m,1<<i));            if(opt)              lb.Printf("%s.%s %s\n",name,opt,(o&(1<<i))?"on":"off");            }          }        }      }    if(lb.Length()>0) return lb.Line();    ReplyCode=901; return "No config available";    }  return NULL;}VDRPLUGINCREATOR(cScPlugin); // Don't touch this!

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -