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

📄 data.c

📁 这是一个LINUX环境的 VDR 插件源代码,可支持Irdeto, Seca, Viaccess, Nagra, Conax & Cryptoworks等CA系统的读卡、共享等操作。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Softcam plugin to VDR (C++) * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This code is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Or, point your browser to http://www.gnu.org/copyleft/gpl.html */#include <ctype.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <sys/mman.h>#include <sys/stat.h>#include <vdr/tools.h>#include "data.h"#include "misc.h"#include "scsetup.h"#include "log-core.h"#define KEY_FILE     "SoftCam.Key"#define CACACHE_FILE "ca.cache"#define EXT_AU_INT   (15*60*1000) // ms interval for external AU#define EXT_AU_MIN   ( 2*60*1000) // ms min. interval for external AU// -- cFileMap -----------------------------------------------------------------cFileMap::cFileMap(const char *Filename, bool Rw){  filename=strdup(Filename);  rw=Rw;  fd=-1; count=len=0; addr=0; failed=false;}cFileMap::~cFileMap(){  Clean();  free(filename);}bool cFileMap::IsFileMap(const char *Name, bool Rw){  return (!strcmp(Name,filename) && (!Rw || rw));}void cFileMap::Clean(void){  if(addr) { munmap(addr,len); addr=0; len=0; }  if(fd>=0) { close(fd); fd=-1; }}bool cFileMap::Map(void){  cMutexLock lock(this);  if(addr) { count++; return true; }  if(!failed) {    struct stat64 ds;    if(!stat64(filename,&ds)) {      if(S_ISREG(ds.st_mode)) {        fd=open(filename,rw ? O_RDWR : O_RDONLY);        if(fd>=0) {          unsigned char *map=(unsigned char *)mmap(0,ds.st_size,rw ? (PROT_READ|PROT_WRITE):(PROT_READ),MAP_SHARED,fd,0);          if(map!=MAP_FAILED) {            addr=map; len=ds.st_size; count=1;            return true;            }          else PRINTF(L_GEN_ERROR,"mapping failed on %s: %s",filename,strerror(errno));          close(fd); fd=-1;          }        else PRINTF(L_GEN_ERROR,"error opening filemap %s: %s",filename,strerror(errno));        }      else PRINTF(L_GEN_ERROR,"filemap %s is not a regular file",filename);      }    else PRINTF(L_GEN_ERROR,"can't stat filemap %s: %s",filename,strerror(errno));    failed=true; // don't try this one over and over again    }  return false;}bool cFileMap::Unmap(void){  cMutexLock lock(this);  if(addr) {    if(!(--count)) { Clean(); return true; }    else Sync();    }  return false;}void cFileMap::Sync(void){  cMutexLock lock(this);  if(addr) msync(addr,len,MS_ASYNC);}// -- cFileMaps ----------------------------------------------------------------cFileMaps filemaps;cFileMaps::cFileMaps(void){  cfgDir=0;}cFileMaps::~cFileMaps(){  Clear();  free(cfgDir);}void cFileMaps::SetCfgDir(const char *CfgDir){  free(cfgDir);  cfgDir=strdup(CfgDir);}cFileMap *cFileMaps::GetFileMap(const char *name, const char *domain, bool rw){  cMutexLock lock(this);  char path[256];  snprintf(path,sizeof(path),"%s/%s/%s",cfgDir,domain,name);  cFileMap *fm=First();  while(fm) {    if(fm->IsFileMap(path,rw)) return fm;    fm=Next(fm);    }  fm=new cFileMap(path,rw);  Add(fm);  return fm;  }// -- cConfRead ----------------------------------------------------------------bool cConfRead::ConfRead(const char *type, const char *filename){  bool res=false;  FILE *f=fopen(filename,"r");  if(f) {    res=true;    PRINTF(L_GEN_INFO,"loading %s from %s",type,filename);    char buff[1024];    while(fgets(buff,sizeof(buff),f)) {      if(!index(buff,'\n') && !feof(f))        PRINTF(L_GEN_ERROR,"confread %s fgets readbuffer overflow",type);      char *line=skipspace(stripspace(buff));      if(line[0]==0 || line[0]==';' || line[0]=='#') continue; // skip empty & comment lines      if(!ParseLine(line,false)) {        PRINTF(L_GEN_ERROR,"file '%s' has error in line '%s'",filename,buff);        res=false;        }      }    fclose(f);    }  else PRINTF(L_GEN_ERROR,"Failed to open file '%s': %s",filename,strerror(errno));  return res;}// -- cLineDummy ---------------------------------------------------------------class cLineDummy : public cSimpleItem {private:  char *store;public:  cLineDummy(void);  ~cLineDummy();  bool Parse(const char *line);  bool Save(FILE *f);  };cLineDummy::cLineDummy(void){  store=0;}cLineDummy::~cLineDummy(){  free(store);}bool cLineDummy::Parse(const char *line){  free(store);  store=strdup(line);  return store!=0;}bool cLineDummy::Save(FILE *f){  fprintf(f,"%s",store);  return ferror(f)==0;}// -- cLoaderDummy -------------------------------------------------------------class cLoaderDummy : public cSimpleList<cLineDummy>, public cLoader {public:  cLoaderDummy(const char *Id);  virtual bool ParseLine(const char *line, bool fromCache);  virtual bool Save(FILE *f);  };cLoaderDummy::cLoaderDummy(const char *id):cLoader(id){}bool cLoaderDummy::ParseLine(const char *line, bool fromCache){  if(fromCache) {    cLineDummy *k=new cLineDummy;    if(k) {      if(k->Parse(line)) Add(k);      else delete k;      return true;      }    PRINTF(L_GEN_ERROR,"not enough memory for %s loader dummy!",Id());    }  return false;}bool cLoaderDummy::Save(FILE *f){  bool res=true;  for(cLineDummy *k=First(); k; k=Next(k))    if(!k->Save(f)) { res=false; break; }  Modified(!res);  return res;}// -- cLoader ------------------------------------------------------------------cLoader::cLoader(const char *Id){  id=Id; modified=false;  cLoaders::Register(this);}// -- cLoaders -----------------------------------------------------------------cLoader *cLoaders::first=0;cMutex cLoaders::lock;char *cLoaders::cacheFile=0;void cLoaders::Register(cLoader *ld){  PRINTF(L_CORE_DYN,"loaders: registering loader %s",ld->id);  ld->next=first;  first=ld;}void cLoaders::LoadCache(const char *cfgdir){  lock.Lock();  cacheFile=strdup(AddDirectory(cfgdir,CACACHE_FILE));  if(access(cacheFile,F_OK)==0) {    PRINTF(L_GEN_INFO,"loading ca cache from %s",cacheFile);    FILE *f=fopen(cacheFile,"r");    if(f) {      char buf[512];      cLoader *ld=0;      while(fgets(buf,sizeof(buf),f)) {        if(!index(buf,'\n'))          PRINTF(L_GEN_ERROR,"loaders fgets readbuffer overflow");        if(buf[0]=='#') continue;        if(!strncmp(buf,":::",3)) { // new loader section          ld=FindLoader(stripspace(&buf[3]));          if(!ld) {            PRINTF(L_CORE_LOAD,"unknown loader section '%s', adding dummy",&buf[3]);            ld=new cLoaderDummy(strdup(&buf[3]));            }          }        else if(ld) {          if(!ld->ParseLine(buf,true)) {            PRINTF(L_CORE_LOAD,"loader '%s' failed on line '%s'",ld->Id(),buf);            }          }        }      fclose(f);      }    else LOG_ERROR_STR(cacheFile);    }  lock.Unlock();}void cLoaders::SaveCache(void){  lock.Lock();  if(cacheFile && IsModified()) {    cSafeFile f(cacheFile);    if(f.Open()) {      fprintf(f,"## This is a generated file. DO NOT EDIT!!\n"                "## This file will be OVERWRITTEN WITHOUT WARNING!!\n");      cLoader *ld=first;      while(ld) {        fprintf(f,":::%s\n",ld->Id());        if(!ld->Save(f)) break;        ld=ld->next;        }      f.Close();      PRINTF(L_CORE_LOAD,"saved cache to file");      }    }  lock.Unlock();}bool cLoaders::IsModified(void){  bool res=false;  lock.Lock();  cLoader *ld=first;  while(ld) {    if(ld->IsModified()) {       res=true; break;      }    ld=ld->next;    }  lock.Unlock();  return res;}cLoader *cLoaders::FindLoader(const char *id){  lock.Lock();  cLoader *ld=first;  while(ld) {    if(!strcmp(id,ld->Id())) break;    ld=ld->next;    }  lock.Unlock();  return ld;}// -- cPid ---------------------------------------------------------------------cPid::cPid(int Pid, int Section, int Mask, int Mode){  pid=Pid;  sct=Section;  mask=Mask;  mode=Mode;  filter=0;}// -- cPids --------------------------------------------------------------------void cPids::AddPid(int Pid, int Section, int Mask, int Mode){  if(!HasPid(Pid,Section,Mask,Mode)) {    cPid *pid=new cPid(Pid,Section,Mask,Mode);    Add(pid);    }}bool cPids::HasPid(int Pid, int Section, int Mask, int Mode){  for(cPid *pid=First(); pid; pid=Next(pid))    if(pid->pid==Pid && pid->sct==Section && pid->mask==Mask && pid->mode==Mode)      return true;  return false;}// -- cEcmInfo -----------------------------------------------------------------cEcmInfo::cEcmInfo(void){  Setup();}cEcmInfo::cEcmInfo(const cEcmInfo *e){  Setup(); SetName(e->name);  ecm_pid=e->ecm_pid;  ecm_table=e->ecm_table;  caId=e->caId;  emmCaId=e->emmCaId;  provId=e->provId;  Update(e);  prgId=e->prgId;  source=e->source;  transponder=e->transponder;}cEcmInfo::cEcmInfo(const char *Name, int Pid, int CaId, int ProvId){  Setup(); SetName(Name);  ecm_pid=Pid;  caId=CaId;  provId=ProvId;}cEcmInfo::~cEcmInfo(){  ClearData();  free(name);}void cEcmInfo::Setup(void){  cached=failed=false;  name=0; data=0;  prgId=source=transponder=-1;  ecm_table=0x80; emmCaId=0;}

⌨️ 快捷键说明

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