📄 data.c
字号:
cStructLoader *cStructLoaders::first=0;cTimeMs cStructLoaders::lastReload;cTimeMs cStructLoaders::lastPurge;cTimeMs cStructLoaders::lastSave;void cStructLoaders::Register(cStructLoader *ld){ PRINTF(L_CORE_DYN,"structloaders: registering loader %s",ld->type); ld->next=first; first=ld;}void cStructLoaders::SetCfgDir(const char *cfgdir){ for(cStructLoader *ld=first; ld; ld=ld->next) ld->SetCfgDir(cfgdir);}void cStructLoaders::Load(bool reload){ if(!reload || lastReload.TimedOut()) { for(cStructLoader *ld=first; ld; ld=ld->next) ld->Load(reload); lastReload.Set(RELOAD_TIMEOUT); }}void cStructLoaders::Save(bool force){ if(force || lastSave.TimedOut()) { for(cStructLoader *ld=first; ld; ld=ld->next) ld->Save(); lastSave.Set(SAVE_TIMEOUT); }}void cStructLoaders::Purge(void){ if(lastPurge.TimedOut()) { for(cStructLoader *ld=first; ld; ld=ld->next) ld->Purge(); lastPurge.Set(PURGE_TIMEOUT); }}// -- 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;}bool cEcmInfo::Compare(const cEcmInfo *e){ return prgId==e->prgId && source==e->source && transponder==e->transponder && caId==e->caId && ecm_pid==e->ecm_pid && provId==e->provId;}bool cEcmInfo::Update(const cEcmInfo *e){ return (e->data && (!data || e->dataLen!=dataLen)) ? AddData(e->data,e->dataLen) : false;}void cEcmInfo::SetSource(int PrgId, int Source, int Transponder){ prgId=PrgId; source=Source; transponder=Transponder;}void cEcmInfo::ClearData(void){ free(data); data=0;}bool cEcmInfo::AddData(const unsigned char *Data, int DataLen){ ClearData(); data=MALLOC(unsigned char,DataLen); if(data) { memcpy(data,Data,DataLen); dataLen=DataLen; } else PRINTF(L_GEN_ERROR,"malloc failed in cEcmInfo::AddData()"); return (data!=0);}void cEcmInfo::SetName(const char *Name){ free(name); name=strdup(Name);}// -- cPlainKey ----------------------------------------------------------------cPlainKey::cPlainKey(bool CanSupersede){ super=CanSupersede;}bool cPlainKey::Set(int Type, int Id, int Keynr, void *Key, int Keylen){ type=Type; id=Id; keynr=Keynr; return SetKey(Key,Keylen);}cString cPlainKey::PrintKeyNr(void){ return cString::sprintf("%02X",keynr);}int cPlainKey::IdSize(void){ return id>0xFF ? (id>0xFFFF ? 6 : 4) : 2;}cString cPlainKey::ToString(bool hide){ return cString::sprintf(hide ? "%c %.*X %s %.4s..." : "%c %.*X %s %s",type,IdSize(),id,*PrintKeyNr(),*Print());}// -- cMutableKey --------------------------------------------------------------cMutableKey::cMutableKey(bool Super):cPlainKey(Super){ real=0;}cMutableKey::~cMutableKey(){ delete real;}bool cMutableKey::SetKey(void *Key, int Keylen){ delete real; return (real=Alloc()) && real->SetKey(Key,Keylen);}bool cMutableKey::SetBinKey(unsigned char *Mem, int Keylen){ delete real; return (real=Alloc()) && real->SetBinKey(Mem,Keylen);}int cMutableKey::Size(void){ return real->Size();}bool cMutableKey::Cmp(cPlainKey *k){ cMutableKey *mk=dynamic_cast<cMutableKey *>(k); // high magic ;) return real->Cmp(mk ? mk->real : k);}void cMutableKey::Get(void *mem){ real->Get(mem);}cString cMutableKey::Print(void){ return real->Print();}// ----------------------------------------------------------------class cPlainKeyDummy : public cPlainKey {private: char *str; int len;protected: virtual cString Print(void); virtual cString PrintKeyNr(void) { return ""; }public: cPlainKeyDummy(void); ~cPlainKeyDummy(); virtual bool Parse(const char *line); virtual bool Cmp(cPlainKey *k) { return false; } virtual void Get(void *mem) {} virtual int Size(void) { return len; } virtual bool SetKey(void *Key, int Keylen); virtual bool SetBinKey(unsigned char *Mem, int Keylen); };cPlainKeyDummy::cPlainKeyDummy(void):cPlainKey(false){ str=0;}cPlainKeyDummy::~cPlainKeyDummy(){ free(str);}bool cPlainKeyDummy::SetKey(void *Key, int Keylen){ len=Keylen; free(str); str=MALLOC(char,len+1); if(str) strn0cpy(str,(char *)Key,len+1); return str!=0;}bool cPlainKeyDummy::SetBinKey(unsigned char *Mem, int Keylen){ return SetKey(Mem,Keylen);}cString cPlainKeyDummy::Print(void){ return str;}bool cPlainKeyDummy::Parse(const char *line){ unsigned char sid[3]; int len; if(GetChar(line,&type,1) && (len=GetHex(line,sid,3,false))) { type=toupper(type); id=Bin2Int(sid,len); char *l=strdup(line); line=skipspace(stripspace(l)); SetKey((void *)line,strlen(line)); free(l); return true; } return false;}// -- cPlainKeyTypeDummy -------------------------------------------------------class cPlainKeyTypeDummy : public cPlainKeyType {public: cPlainKeyTypeDummy(int Type):cPlainKeyType(Type,false) {} virtual cPlainKey *Create(void) { return new cPlainKeyDummy; } };// -- cPlainKeyType ------------------------------------------------------------cPlainKeyType::cPlainKeyType(int Type, bool Super){ type=Type; cPlainKeys::Register(this,Super);}// -- cLastKey -----------------------------------------------------------------cLastKey::cLastKey(void){ lastType=lastId=lastKeynr=-1;}bool cLastKey::NotLast(int Type, int Id, int Keynr){ if(lastType!=Type || lastId!=Id || lastKeynr!=Keynr) { lastType=Type; lastId=Id; lastKeynr=Keynr; return true; } return false;}// -- cPlainKeys ---------------------------------------------------------------const char *externalAU=0;cPlainKeys keys;cPlainKeyType *cPlainKeys::first=0;cPlainKeys::cPlainKeys(void):cStructList<cPlainKey>("keys",KEY_FILE,SL_READWRITE|SL_MISSINGOK|SL_WATCH|SL_VERBOSE){}void cPlainKeys::Register(cPlainKeyType *pkt, bool Super){ PRINTF(L_CORE_DYN,"registering key type %c%s",pkt->type,Super?" (super)":""); pkt->next=first; first=pkt;}void cPlainKeys::Trigger(int Type, int Id, int Keynr){ if(lastkey.NotLast(Type,Id,Keynr)) PRINTF(L_CORE_AUEXTERN,"triggered from findkey (%s)",*KeyString(Type,Id,Keynr)); ExternalUpdate();}cPlainKey *cPlainKeys::FindKey(int Type, int Id, int Keynr, int Size, cPlainKey *key){ key=FindKeyNoTrig(Type,Id,Keynr,Size,key); if(!key) Trigger(Type,Id,Keynr); return key;}cPlainKey *cPlainKeys::FindKeyNoTrig(int Type, int Id, int Keynr, int Size, cPlainKey *key){ ListLock(false); for(key=key?Next(key):First(); key; key=Next(key)) if(key->type==Type && key->id==Id && key->keynr==Keynr && (Size<0 || key->Size()==Size)) break; ListUnlock(); return key;}cPlainKey *cPlainKeys::NewFromType(int type){ cPlainKeyType *pkt; for(pkt=first; pkt; pkt=pkt->next) if(pkt->type==type) return pkt->Create(); PRINTF(L_CORE_LOAD,"unknown key type '%c', adding dummy",type); pkt=new cPlainKeyTypeDummy(type); return pkt->Create();}bool cPlainKeys::AddNewKey(cPlainKey *nk, const char *reason){ cPlainKey *k; for(k=0; (k=FindKeyNoTrig(nk->type,nk->id,nk->keynr,-1,k)); ) if(k->CmpExtId(nk) && k->Cmp(nk)) return false; cPlainKey *ref=0; cString ks=nk->ToString(true); PRINTF(L_GEN_INFO,"key update for ID %s",*ks); ums.Queue("%s %s",tr("Key update"),*ks); for(k=0; (k=FindKeyNoTrig(nk->type,nk->id,nk->keynr,nk->Size(),k)); ) { if(!k->CmpExtId(nk)) continue; if(nk->CanSupersede()) { PRINTF(L_GEN_INFO,"supersedes key: %s",*k->ToString(true)); DelItem(k,ScSetup.SuperKeys==0); } if(!ref) ref=k; } char stamp[32], com[256]; time_t tt=time(0); struct tm tm_r; strftime(stamp,sizeof(stamp),"%d.%m.%Y %T",localtime_r(&tt,&tm_r)); snprintf(com,sizeof(com)," ; %s %s",reason,stamp); AddItem(nk,com,ref); return true;}bool cPlainKeys::NewKey(int Type, int Id, int Keynr, void *Key, int Keylen){ cPlainKey *nk=NewFromType(Type); if(nk) { nk->Set(Type,Id,Keynr,Key,Keylen); return AddNewKey(nk,"from AU"); } return false;}bool cPlainKeys::NewKeyParse(char *line, const char *reason){ cPlainKey *nk=ParseLine(line); return nk && AddNewKey(nk,reason);}cPlainKey *cPlainKeys::ParseLine(char *line){ char *s=skipspace(line); cPlainKey *k=NewFromType(toupper(*s)); if(k && !k->Parse(line)) { delete k; k=0; } return k;}cString cPlainKeys::KeyString(int Type, int Id, int Keynr){ cPlainKey *pk=NewFromType(Type); char *s; if(pk) { pk->type=Type; pk->id=Id; pk->keynr=Keynr; asprintf(&s,"%c %.*X %s",Type,pk->IdSize(),Id,*pk->PrintKeyNr()); delete pk; } else s=strdup("unknown"); return cString(s,true);}void cPlainKeys::PostLoad(void){ ListLock(false); if(Count() && LOG(L_CORE_KEYS)) { for(cPlainKey *dat=First(); dat; dat=Next(dat)) PRINTF(L_CORE_KEYS,"keys %s",*dat->ToString(false)); } ListUnlock();}void cPlainKeys::HouseKeeping(void){ if(trigger.TimedOut()) { trigger.Set(EXT_AU_INT); if(externalAU) PRINTF(L_CORE_AUEXTERN,"triggered from housekeeping"); ExternalUpdate(); }}void cPlainKeys::ExternalUpdate(void){ if(externalAU && ScSetup.AutoUpdate>0) { if(last.TimedOut()) { Lock(); if(!Active()) Start(); else PRINTF(L_CORE_AUEXTERN,"still running"); Unlock(); } else PRINTF(L_CORE_AUEXTERN,"denied, min. timeout not expired"); }}void cPlainKeys::Action(void){ last.Set(EXT_AU_MIN); PRINTF(L_CORE_AUEXTERN,"starting..."); cTimeMs start; cPipe pipe; if(pipe.Open(externalAU,"r")) { char buff[1024]; while(fgets(buff,sizeof(buff),pipe)) { char *line=skipspace(stripspace(buff)); if(line[0]==0 || line[0]==';' || line[0]=='#') continue; NewKeyParse(line,"from ExtAU"); } } pipe.Close(); PRINTF(L_CORE_AUEXTERN,"done (elapsed %d)",(int)start.Elapsed());}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -