From e444bb578ac637b8820cc31be78b62da5086e9d0 Mon Sep 17 00:00:00 2001 From: mirv Date: Thu, 3 Jan 2008 15:12:52 +0100 Subject: [PATCH] save keys back to SoftCam.Key. ca.cache will die --- cam.c | 4 +- cam.h | 2 +- data.c | 480 +++++++++++++++++++++++++++++++++++++++++---------------- data.h | 107 +++++++++++-- sc.c | 32 ++-- sc.h | 3 +- 6 files changed, 463 insertions(+), 165 deletions(-) diff --git a/cam.c b/cam.c index fbe81db..0474603 100644 --- a/cam.c +++ b/cam.c @@ -1444,12 +1444,12 @@ char *cCam::CurrentKeyStr(int num) return 0; } -bool cCam::Active(void) +bool cCam::Active(bool log) { cMutexLock lock(this); for(cEcmHandler *handler=handlerList.First(); handler; handler=handlerList.Next(handler)) if(!handler->IsIdle()) { - PRINTF(L_GEN_INFO,"handler %s on card %d is not idle",handler->Id(),cardNum); + if(log) PRINTF(L_GEN_INFO,"handler %s on card %d is not idle",handler->Id(),cardNum); return true; } return false; diff --git a/cam.h b/cam.h index 3471872..18e6b88 100644 --- a/cam.h +++ b/cam.h @@ -127,7 +127,7 @@ public: void AddHook(cLogHook *hook); bool TriggerHook(int id); // Plugin API - bool Active(void); + bool Active(bool log); void HouseKeeping(void); void Tune(const cChannel *channel); void PostTune(void); diff --git a/data.c b/data.c index 84cce8f..2b6a777 100644 --- a/data.c +++ b/data.c @@ -20,12 +20,11 @@ #include #include #include +#include #include #include #include -#include - #include "data.h" #include "misc.h" #include "scsetup.h" @@ -142,6 +141,278 @@ cFileMap *cFileMaps::GetFileMap(const char *name, const char *domain, bool rw) return fm; } +// -- cStructItem -------------------------------------------------------------- + +cStructItem::cStructItem(void) +{ + comment=0; deleted=special=false; +} + +cStructItem::~cStructItem() +{ + free(comment); +} + +void cStructItem::SetComment(const char *com) +{ + free(comment); + comment=strdup(com); +} + +bool cStructItem::Save(FILE *f) +{ + fprintf(f,"%s%s\n",*ToString(false),comment?comment:""); + return ferror(f)==0; +} + +// -- cCommentItem ------------------------------------------------------------- + +class cCommentItem : public cStructItem { +public: + cCommentItem(void); + virtual cString ToString(bool hide=false) { return ""; } + }; + +cCommentItem::cCommentItem(void) +{ + SetSpecial(); +} + +// -- cStructLoader ------------------------------------------------------------ + +cStructLoader::cStructLoader(const char *Type, const char *Filename, bool rw, bool miok, bool wat, bool verb) +:lock(true) +{ + path=0; mtime=0; modified=loaded=disabled=false; + type=Type; filename=Filename; + readwrite=rw; missingok=miok; watch=wat; verbose=verb; + cStructLoaders::Register(this); +} + +cStructLoader::~cStructLoader() +{ + free(path); +} + +void cStructLoader::AddItem(cStructItem *n, const char *com, cStructItem *ref) +{ + n->SetComment(com); + ListLock(true); + cStructItem *a=0; + if(ref) { // insert before reference + for(a=First(); a; a=Next(a)) + if(Next(a)==ref) break; + } + if(!a) { // insert before first non-special + for(a=First(); a;) { + cStructItem *nn=Next(a); + if(nn && !nn->Special()) break; + a=nn; + } + } + Add(n,a); + Modified(); + ListUnlock(); +} + +void cStructLoader::DelItem(cStructItem *d, bool keep) +{ + if(d) { + d->Delete(); + if(keep) { + cStructItem *n=new cCommentItem; + n->SetComment(cString::sprintf(";%s%s",*d->ToString(false),d->Comment()?d->Comment():"")); + Add(n,d); + } + Modified(); + } +} + +void cStructLoader::SetCfgDir(const char *cfgdir) +{ + free(path); + path=strdup(AddDirectory(cfgdir,filename)); +} + +time_t cStructLoader::MTime(void) +{ + struct stat64 st; + if(stat64(path,&st)!=0) { + PRINTF(L_GEN_ERROR,"failed fstat %s: %s",path,strerror(errno)); + PRINTF(L_GEN_WARN,"automatic reload of %s disabled",path); + st.st_mtime=0; + } + return st.st_mtime; +} + +bool cStructLoader::Load(bool reload) +{ + if(reload && !watch) return true; + FILE *f=fopen(path,"r"); + if(f) { + int curr_mtime=MTime(); + if(access(path,R_OK|W_OK)!=0) { + if(errno!=EACCES) + PRINTF(L_GEN_ERROR,"failed access %s: %s",path,strerror(errno)); + PRINTF(L_GEN_WARN,"no write permission on %s. Changes will not be saved!",path); + readwrite=false; + } + + loaded=true; + ListLock(true); + bool doload=false; + if(!reload) { + Clear(); Modified(false); + mtime=curr_mtime; + doload=true; + } + else if(mtime && mtimebuff && ls[-1]<=' ') ls--; // search back to non-whitespace + break; + } + if(*ls>' ') hasContent=true; // line contains something usefull + } + cStructItem *it=0; + if(hasContent) { + char save=*ls; + *ls=0; it=ParseLine(buff); *ls=save; + if(!it) { + PRINTF(L_GEN_ERROR,"file %s has error in line #%d",path,lineNum); + ls=buff; + } + else num++; + } + else ls=buff; + if(!it) it=new cCommentItem; + if(it) { + it->SetComment(ls); + Add(it); + } + else { + PRINTF(L_GEN_ERROR,"out of memory loading file %s",path); + loaded=false; + break; + } + } + PRINTF(L_CORE_LOAD,"loaded %d %s from %s",num,type,path); + PostLoad(); + } + ListUnlock(); + + fclose(f); + } + else { + if(verbose) PRINTF(L_GEN_ERROR,"failed open %s: %s",path,strerror(errno)); + loaded=missingok; + } + if(!loaded) PRINTF(L_CORE_LOAD,"loading %s terminated with error. Changes will not be saved!",path); + return loaded; +} + +void cStructLoader::Purge(void) +{ + ListLock(true); + for(cStructItem *it=First(); it;) { + cStructItem *n=Next(it); + if(it->Deleted()) Del(it); + it=n; + } + ListUnlock(); +} + +void cStructLoader::Save(void) +{ + ListLock(false); + if(readwrite && loaded && IsModified()) { + cSafeFile f(path); + if(f.Open()) { + for(cStructItem *it=First(); it; it=Next(it)) + if(!it->Deleted() && !it->Save(f)) break; + f.Close(); + mtime=MTime(); + PRINTF(L_CORE_LOAD,"saved %s to %s",type,path); + Modified(false); + } + } + ListUnlock(); +} + +// -- cStructLoaders ----------------------------------------------------------- + +#define RELOAD_TIMEOUT 20000 +#define PURGE_TIMEOUT 60000 +#define SAVE_TIMEOUT 5000 + +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) + if(!ld->disabled) ld->Load(reload); + lastReload.Set(RELOAD_TIMEOUT); + } +} + +void cStructLoaders::Save(void) +{ + if(lastSave.TimedOut()) { + for(cStructLoader *ld=first; ld; ld=ld->next) + if(!ld->disabled) ld->Save(); + lastSave.Set(SAVE_TIMEOUT); + } +} + +void cStructLoaders::Purge(void) +{ + if(lastPurge.TimedOut()) { + for(cStructLoader *ld=first; ld; ld=ld->next) + if(!ld->disabled) ld->Purge(); + lastPurge.Set(PURGE_TIMEOUT); + } +} + // -- cConfRead ---------------------------------------------------------------- bool cConfRead::ConfRead(const char *type, const char *filename, bool missingok) @@ -460,7 +731,6 @@ void cEcmInfo::SetName(const char *Name) cPlainKey::cPlainKey(bool CanSupersede) { - au=del=false; super=CanSupersede; } @@ -480,12 +750,6 @@ int cPlainKey::IdSize(void) return id>0xFF ? (id>0xFFFF ? 6 : 4) : 2; } -bool cPlainKey::Save(FILE *f) -{ - fprintf(f,"%s\n",*ToString(false)); - return ferror(f)==0; -} - cString cPlainKey::ToString(bool hide) { return cString::sprintf(hide ? "%c %.*X %s %.4s..." : "%c %.*X %s %s",type,IdSize(),id,*PrintKeyNr(),*Print()); @@ -654,11 +918,8 @@ cPlainKeys keys; cPlainKeyType *cPlainKeys::first=0; cPlainKeys::cPlainKeys(void) -:cLoader("KEY") -//,cThread("ExternalAU") -{ - mark=0; -} +:cStructList("keys",KEY_FILE,true,true,true,true) +{} void cPlainKeys::Register(cPlainKeyType *pkt, bool Super) { @@ -683,81 +944,91 @@ cPlainKey *cPlainKeys::FindKey(int Type, int Id, int Keynr, int Size, cPlainKey cPlainKey *cPlainKeys::FindKeyNoTrig(int Type, int Id, int Keynr, int Size, cPlainKey *key) { - Lock(); - if(key) key=Next(key); else key=First(); - while(key) { - if(!key->IsInvalid() && key->type==Type && key->id==Id && key->keynr==Keynr && (Size<0 || key->Size()==Size)) break; - key=Next(key); - } - Unlock(); + ListLock(false); + for(key=key?Next(key):First(); key; key=Next(key)) + if(key->Valid() && key->type==Type && key->id==Id && key->keynr==Keynr && (Size<0 || key->Size()==Size)) + break; + ListUnlock(); return key; } -bool cPlainKeys::NewKey(int Type, int Id, int Keynr, void *Key, int Keylen) +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=0; - while((k=FindKeyNoTrig(Type,Id,Keynr,-1,k))) - if(k->Cmp(Key,Keylen)) return false; + cPlainKey *k; + for(k=0; (k=FindKeyNoTrig(nk->type,nk->id,nk->keynr,-1,k)); ) + if(k->Cmp(nk)) return false; + cPlainKey *ref=0; + PRINTF(L_GEN_INFO,"key update for ID %s",*nk->ToString(true)); + for(k=0; (k=FindKeyNoTrig(nk->type,nk->id,nk->keynr,nk->Size(),k)); ) { + if(nk->CanSupersede()) { + PRINTF(L_GEN_INFO,"supersedes key: %s",*k->ToString(true)); + DelItem(k,true); + } + 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); - AddNewKey(nk,2,true); - return true; + return AddNewKey(nk,"from AU"); } - else PRINTF(L_GEN_ERROR,"no memory for new key ID %c %.2x!",Type,Id); return false; } -void cPlainKeys::AddNewKey(cPlainKey *nk, int mode, bool log) +bool cPlainKeys::NewKeyParse(char *line, const char *reason) { - if(mode>=1) { - nk->SetAuto(); - if(log) PRINTF(L_GEN_INFO,"key update for ID %s",*nk->ToString(true)); - if(nk->CanSupersede()) { - cPlainKey *k=0; - while((k=FindKeyNoTrig(nk->type,nk->id,nk->keynr,nk->Size(),k))) { - if(!k->IsInvalid()) { - k->SetInvalid(); - if(k->IsAuto()) Modified(); - if(log) PRINTF(L_GEN_INFO,"supersedes key: %s%s",*k->ToString(true),k->IsAuto()?" (auto)":""); - } - } - } - } - Lock(); - switch(mode) { - case 0: Add(nk); break; - case 1: if(!mark) Ins(nk); else Add(nk,mark); - mark=nk; - break; - case 2: Ins(nk); Modified(); break; - } - Unlock(); -} - -bool cPlainKeys::Load(const char *cfgdir) -{ - Lock(); - Clear(); mark=0; - cString cname=AddDirectory(cfgdir,KEY_FILE); - ConfRead("keys",cname); - int n=Count(); - PRINTF(L_CORE_LOAD,"loaded %d keys from %s",n,*cname); - if(n && LOG(L_CORE_KEYS)) { - cPlainKey *dat=First(); - while(dat) { - if(!dat->IsInvalid()) PRINTF(L_CORE_KEYS,"keys %s",*dat->ToString(false)); - dat=Next(dat); - } + 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); + if(pk) { + pk->type=Type; pk->id=Id; pk->keynr=Keynr; + return cString::sprintf("%c %.*X %s",Type,pk->IdSize(),Id,*pk->PrintKeyNr()); } - Unlock(); - return (n!=0); + return "unknown"; +} + +void cPlainKeys::PostLoad(void) +{ + if(Count() && LOG(L_CORE_KEYS)) + for(cPlainKey *dat=First(); dat; dat=Next(dat)) + if(dat->Valid()) PRINTF(L_CORE_KEYS,"keys %s",*dat->ToString(false)); } void cPlainKeys::HouseKeeping(void) { - cLoaders::SaveCache(); if(trigger.TimedOut()) { trigger.Set(EXT_AU_INT); if(externalAU) PRINTF(L_CORE_AUEXTERN,"triggered from housekeeping"); @@ -779,21 +1050,6 @@ void cPlainKeys::ExternalUpdate(void) } } -bool cPlainKeys::NewKeyParse(const char *line) -{ - cPlainKey *nk=NewFromType(toupper(line[0])); - if(nk && nk->Parse(line)) { - cPlainKey *k=0; - while((k=FindKeyNoTrig(nk->type,nk->id,nk->keynr,-1,k))) - if(k->Cmp(nk)) break; - if(!k) { - AddNewKey(nk,2,true); - return true; - } - } - return false; -} - void cPlainKeys::Action(void) { last.Set(EXT_AU_MIN); @@ -805,59 +1061,9 @@ void cPlainKeys::Action(void) while(fgets(buff,sizeof(buff),pipe)) { char *line=skipspace(stripspace(buff)); if(line[0]==0 || line[0]==';' || line[0]=='#') continue; - NewKeyParse(line); + NewKeyParse(line,"from ExtAU"); } } pipe.Close(); PRINTF(L_CORE_AUEXTERN,"done (elapsed %d)",(int)start.Elapsed()); } - -cPlainKey *cPlainKeys::NewFromType(int type) -{ - cPlainKeyType *pkt=first; - while(pkt) { - if(pkt->type==type) return pkt->Create(); - pkt=pkt->next; - } - PRINTF(L_CORE_LOAD,"unknown key type '%c', adding dummy",type); - pkt=new cPlainKeyTypeDummy(type); - return pkt->Create(); -} - -cString cPlainKeys::KeyString(int Type, int Id, int Keynr) -{ - cPlainKey *pk=NewFromType(Type); - if(pk) { - pk->type=Type; pk->id=Id; pk->keynr=Keynr; - return cString::sprintf("%c %.*X %s",Type,pk->IdSize(),Id,*pk->PrintKeyNr()); - } - return "unknown"; -} - -bool cPlainKeys::ParseLine(const char *line, bool fromCache) -{ - char *s=skipspace(line); - cPlainKey *k=NewFromType(toupper(*s)); - if(k) { - if(k->Parse((char *)line)) AddNewKey(k,fromCache?1:0,false); - else delete k; - return true; - } - return false; -} - -bool cPlainKeys::Save(FILE *f) -{ - bool res=true; - Lock(); - cPlainKey *dat=First(); - while(dat) { - if(dat->IsAuto() && !dat->IsInvalid()) { - if(!dat->Save(f)) { res=false; break; } - } - dat=Next(dat); - } - Modified(!res); - Unlock(); - return res; -} diff --git a/data.h b/data.h index 34bc84a..1dbaadb 100644 --- a/data.h +++ b/data.h @@ -22,8 +22,10 @@ #include #include + #include "misc.h" +class cStructLoaders; class cLoaders; class cPidFilter; class cPlainKeys; @@ -65,6 +67,88 @@ public: extern cFileMaps filemaps; +//-------------------------------------------------------------- + +class cStructItem : public cSimpleItem { +private: + char *comment; + bool deleted, special; +protected: + void SetSpecial(void) { special=true; } +public: + cStructItem(void); + virtual ~cStructItem(); + virtual cString ToString(bool hide=false)=0; + bool Save(FILE *f); + // + void SetComment(const char *com); + const char *Comment(void) const { return comment; } + void Delete(void) { deleted=true; } + bool Deleted(void) const { return deleted; } + bool Special(void) const { return special; } + bool Valid(void) const { return !deleted && !special; } + }; + +//-------------------------------------------------------------- + +class cStructLoader : public cSimpleList { +friend class cStructLoaders; +private: + cStructLoader *next; + // + cRwLock lock; + const char *type, *filename; + char *path; + time_t mtime; + bool modified, readwrite, missingok, loaded, disabled, watch, verbose; + // + time_t MTime(void); +protected: + virtual cStructItem *ParseLine(char *line)=0; + void Modified(bool mod=true) { modified=mod; } + bool IsModified(void) const { return modified; } + void ListLock(bool rw) { lock.Lock(rw); } + void ListUnlock(void) { lock.Unlock(); } + virtual void PostLoad(void) {} +public: + cStructLoader(const char *Type, const char *Filename, bool rw, bool miok, bool wat, bool verb); + virtual ~cStructLoader(); + void AddItem(cStructItem *n, const char *com, cStructItem *ref); + void DelItem(cStructItem *d, bool keep=false); + // + void SetCfgDir(const char *cfgdir); + bool Load(bool reload); + void Save(void); + void Purge(void); + void Disable(void) { disabled=true; } + }; + +//-------------------------------------------------------------- + +template class cStructList : public cStructLoader { +public: + cStructList(const char *Type, const char *Filename, bool rw, bool miok, bool wat, bool verb):cStructLoader(Type,Filename,rw,miok,wat,verb) {} + T *First(void) const { return (T *)cStructLoader::First(); } + T *Last(void) const { return (T *)cStructLoader::Last(); } + T *Next(const T *item) const { return (T *)cStructLoader::Next(item); } + }; + +//-------------------------------------------------------------- + +class cStructLoaders { +friend class cStructLoader; +private: + static cStructLoader *first; + static cTimeMs lastReload, lastPurge, lastSave; + // + static void Register(cStructLoader *ld); +public: + static void SetCfgDir(const char *cfgdir); + static void Load(bool reload); + static void Save(void); + static void Purge(void); + }; + // ---------------------------------------------------------------- class cConfRead { @@ -166,16 +250,12 @@ public: class cMutableKey; -class cPlainKey : public cSimpleItem { +class cPlainKey : public cStructItem { friend class cPlainKeys; friend class cMutableKey; private: - bool au, del, super; + bool super; protected: - void SetInvalid(void) { del=true; } - void SetAuto(void) { au=true; } - bool IsAuto(void) const { return au; } - bool IsInvalid(void) const { return del; } void SetSupersede(bool val) { super=val; } bool CanSupersede(void) const { return super; } virtual int IdSize(void); @@ -187,8 +267,7 @@ public: // cPlainKey(bool CanSupersede); virtual bool Parse(const char *line)=0; - bool Save(FILE *f); - cString ToString(bool hide=false); + virtual cString ToString(bool hide=false); virtual bool Cmp(void *Key, int Keylen)=0; virtual bool Cmp(cPlainKey *k)=0; virtual void Get(void *mem)=0; @@ -252,31 +331,29 @@ public: extern const char *externalAU; -class cPlainKeys : public cLoader, private cConfRead, private cThread, public cSimpleList { +class cPlainKeys : private cThread, public cStructList { friend class cPlainKeyType; private: static cPlainKeyType *first; - cPlainKey *mark; cTimeMs trigger, last; cLastKey lastkey; // static void Register(cPlainKeyType *pkt, bool Super); cPlainKey *NewFromType(int type); - void AddNewKey(cPlainKey *nk, int mode, bool log); + bool AddNewKey(cPlainKey *nk, const char *reason); void ExternalUpdate(void); protected: virtual void Action(void); + virtual void PostLoad(void); public: cPlainKeys(void); - bool Load(const char *cfgdir); - virtual bool Save(FILE *f); - virtual bool ParseLine(const char *line, bool Au); + virtual cPlainKey *ParseLine(char *line); cPlainKey *FindKey(int Type, int Id, int Keynr, int Size, cPlainKey *key=0); cPlainKey *FindKeyNoTrig(int Type, int Id, int Keynr, int Size, cPlainKey *key=0); void Trigger(int Type, int Id, int Keynr); cString KeyString(int Type, int Id, int Keynr); bool NewKey(int Type, int Id, int Keynr, void *Key, int Keylen); - bool NewKeyParse(const char *line); + bool NewKeyParse(char *line, const char *reason); void HouseKeeping(void); }; diff --git a/sc.c b/sc.c index 8909394..d2c0a07 100644 --- a/sc.c +++ b/sc.c @@ -911,7 +911,7 @@ eOSState cMenuSetupSc::ProcessKey(eKeys Key) case osUser9: state=osContinue; - if(!cSoftCAM::Active()) { + if(!cSoftCAM::Active(true)) { if(Interface->Confirm(tr("Really reload files?"))) { Store(); cSoftCAM::Load(cfgdir); @@ -1007,8 +1007,11 @@ bool cScSetup::Ignore(unsigned short caid) bool cSoftCAM::Load(const char *cfgdir) { ecmcache.Load(); - if(Feature.KeyFile() && !keys.Load(cfgdir)) + if(!Feature.KeyFile()) keys.Disable(); + cStructLoaders::Load(false); + if(Feature.KeyFile() && keys.Count()<1) PRINTF(L_GEN_ERROR,"no keys loaded for softcam!"); + if(!cSystems::Init(cfgdir)) return false; if(Feature.SmartCard()) smartcards.LoadData(cfgdir); cLoaders::LoadCache(cfgdir); @@ -1016,6 +1019,15 @@ bool cSoftCAM::Load(const char *cfgdir) return true; } +void cSoftCAM::HouseKeeping(void) +{ + cLoaders::SaveCache(); + if(Feature.KeyFile()) keys.HouseKeeping(); + if(!Active(false)) cStructLoaders::Purge(); + cStructLoaders::Load(true); + cStructLoaders::Save(); +} + void cSoftCAM::Shutdown(void) { cSystems::Clean(); @@ -1034,11 +1046,11 @@ char *cSoftCAM::CurrKeyStr(int CardNum, int num) return str; } -bool cSoftCAM::Active(void) +bool cSoftCAM::Active(bool log) { for(int n=cDevice::NumDevices(); --n>=0;) { cScDvbDevice *dev=dynamic_cast(cDevice::GetDevice(n)); - if(dev && dev->Cam() && dev->Cam()->Active()) return true; + if(dev && dev->Cam() && dev->Cam()->Active(log)) return true; } return false; } @@ -1247,9 +1259,11 @@ bool cScPlugin::Start(void) #if APIVERSNUM < 10507 RegisterI18n(ScPhrases); #endif - filemaps.SetCfgDir(ConfigDirectory(cfgsub)); + const char *cfgdir=ConfigDirectory(cfgsub); + filemaps.SetCfgDir(cfgdir); + cStructLoaders::SetCfgDir(cfgdir); ScSetup.Check(); - if(!cSoftCAM::Load(ConfigDirectory(cfgsub))) return false; + if(!cSoftCAM::Load(cfgdir)) return false; if(Feature.SmartCard()) { #ifdef DEFAULT_PORT smartcards.AddPort(DEFAULT_PORT); @@ -1359,7 +1373,7 @@ void cScPlugin::Housekeeping(void) cScDvbDevice *dev=dynamic_cast(cDevice::GetDevice(n)); if(dev && dev->Cam()) dev->Cam()->HouseKeeping(); } - if(Feature.KeyFile()) keys.HouseKeeping(); + cSoftCAM::HouseKeeping(); } const char **cScPlugin::SVDRPHelpPages(void) @@ -1383,7 +1397,7 @@ const char **cScPlugin::SVDRPHelpPages(void) cString cScPlugin::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) { if(!strcasecmp(Command,"RELOAD")) { - if(cSoftCAM::Active()) { + if(cSoftCAM::Active(true)) { ReplyCode=550; return "Softcam active. Can't reload files now"; } @@ -1398,7 +1412,7 @@ cString cScPlugin::SVDRPCommand(const char *Command, const char *Option, int &Re } else if(!strcasecmp(Command,"KEY")) { if(Option && *Option) { - if(keys.NewKeyParse(skipspace(Option))) + if(keys.NewKeyParse(skipspace(Option),"from SVDR")) return "Key update successfull"; else { ReplyCode=901; diff --git a/sc.h b/sc.h index dcdcf4d..da6f862 100644 --- a/sc.h +++ b/sc.h @@ -28,9 +28,10 @@ class cLogHook; class cSoftCAM { public: static bool Load(const char *cfgdir); + static void HouseKeeping(void); static void Shutdown(void); // - static bool Active(void); + static bool Active(bool log); static char *CurrKeyStr(int CardNum, int num); static void SetLogStatus(int CardNum, const cEcmInfo *ecm, bool on); static void AddHook(int CardNum, cLogHook *hook); -- 2.39.5