cEcmCache ecmcache;
cEcmCache::cEcmCache(void)
-:cStructList<cEcmData>("ecm cache",ECMCACHE_FILE,SL_READWRITE|SL_MISSINGOK)
+:cStructListPlain<cEcmData>("ecm cache",ECMCACHE_FILE,SL_READWRITE|SL_MISSINGOK)
{}
void cEcmCache::New(cEcmInfo *e)
ListLock(true);
cEcmData *dat;
if(!(dat=Exists(e))) {
- ListUnlock();
- AutoGenWarn();
dat=new cEcmData(e);
- AddItem(dat,0,0);
+ Add(dat);
+ Modified();
PRINTF(L_CORE_ECM,"cache add prgId=%d source=%x transponder=%x ecm=%x/%x",e->prgId,e->source,e->transponder,e->ecm_pid,e->ecm_table);
}
else {
}
if(dat->Update(e))
Modified();
- ListUnlock();
}
+ ListUnlock();
e->SetCached();
}
ListUnlock();
}
-cStructItem *cEcmCache::ParseLine(char *line)
+bool cEcmCache::ParseLinePlain(char *line)
{
cEcmData *dat=new cEcmData;
- if(dat && dat->Parse(line) && !Exists(dat)) return dat;
+ if(dat && dat->Parse(line) && !Exists(dat)) { Add(dat); return true; }
delete dat;
- return 0;
+ return false;
}
// -- cEcmSys ------------------------------------------------------------------
}
}
-void cStructLoader::AutoGenWarn(void)
-{
- if(Count()==0) {
- cStructItem *n=new cCommentItem;
- n->SetComment("## This is a generated file. DO NOT EDIT!!");
- cStructItem *n2=new cCommentItem;
- n2->SetComment("## This file will be OVERWRITTEN WITHOUT WARNING!!");
- ListLock(true);
- Add(n);
- Add(n2);
- ListUnlock();
- }
-}
-
void cStructLoader::SetCfgDir(const char *cfgdir)
{
free(path);
return st.st_mtime;
}
+void cStructLoader::CheckAccess(void)
+{
+ 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);
+ SL_CLRFLAG(SL_READWRITE);
+ }
+}
+
void cStructLoader::Load(bool reload)
{
if(SL_TSTFLAG(SL_DISABLED) || (reload && !SL_TSTFLAG(SL_WATCH))) return;
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);
- SL_CLRFLAG(SL_READWRITE);
- }
-
+ CheckAccess();
SL_SETFLAG(SL_LOADED);
ListLock(true);
bool doload=false;
void cStructLoader::Purge(void)
{
- if(!SL_TSTFLAG(SL_DISABLED)) {
+ if(!SL_TSTFLAG(SL_DISABLED) && !SL_TSTFLAG(SL_NOPURGE)) {
ListLock(true);
for(cStructItem *it=First(); it;) {
cStructItem *n=Next(it);
}
}
+// -- cStructLoaderPlain -------------------------------------------------------
+
+cStructLoaderPlain::cStructLoaderPlain(const char *Type, const char *Filename, int Flags)
+:cStructLoader(Type,Filename,Flags)
+{}
+
+void cStructLoaderPlain::Load(bool reload)
+{
+ if(SL_TSTFLAG(SL_DISABLED) || reload) return;
+ FILE *f=fopen(path,"r");
+ if(f) {
+ CheckAccess();
+ SL_SETFLAG(SL_LOADED);
+ ListLock(true);
+ Clear(); Modified(false);
+ PRINTF(L_GEN_INFO,"loading %s from %s",type,path);
+ int lineNum=0;
+ char buff[4096];
+ while(fgets(buff,sizeof(buff),f)) {
+ lineNum++;
+ if(!index(buff,'\n') && !feof(f)) {
+ PRINTF(L_GEN_ERROR,"file %s readbuffer overflow line#%d",path,lineNum);
+ SL_CLRFLAG(SL_LOADED);
+ break;
+ }
+ bool hasContent=false;
+ char *ls;
+ for(ls=buff; *ls; ls++) {
+ if(*ls==';' || *ls=='#') break;
+ if(*ls>' ') hasContent=true;
+ }
+ if(hasContent) {
+ *ls=0;
+ if(!ParseLinePlain(buff))
+ PRINTF(L_GEN_ERROR,"file %s has error in line #%d",path,lineNum);
+ }
+ }
+ PostLoad();
+ ListUnlock();
+ fclose(f);
+ }
+ else {
+ if(SL_TSTFLAG(SL_VERBOSE))
+ PRINTF(L_GEN_ERROR,"failed open %s: %s",path,strerror(errno));
+ if(SL_TSTFLAG(SL_MISSINGOK)) SL_SETFLAG(SL_LOADED);
+ else SL_CLRFLAG(SL_LOADED);
+ }
+ if(!SL_TSTFLAG(SL_LOADED))
+ PRINTF(L_CORE_LOAD,"loading %s terminated with error. Changes will not be saved!",path);
+}
+
+void cStructLoaderPlain::Save(void)
+{
+ if(!SL_TSTFLAG(SL_DISABLED) && SL_TSTFLAG(SL_READWRITE) && SL_TSTFLAG(SL_LOADED) && IsModified()) {
+ cSafeFile f(path);
+ if(f.Open()) {
+ ListLock(false);
+ PreSave(f);
+ for(cStructItem *it=First(); it; it=Next(it))
+ if(!it->Deleted() && !it->Save(f)) break;
+ PostSave(f);
+ f.Close();
+ Modified(false);
+ ListUnlock();
+ PRINTF(L_CORE_LOAD,"saved %s to %s",type,path);
+ }
+ }
+}
+
+void cStructLoaderPlain::PreSave(FILE *f)
+{
+ fprintf(f,"## This is a generated file. DO NOT EDIT!!\n"
+ "## This file will be OVERWRITTEN WITHOUT WARNING!!\n");
+}
+
+
// -- cStructLoaders -----------------------------------------------------------
#define RELOAD_TIMEOUT 20000
#define SL_MISSINGOK 2
#define SL_WATCH 4
#define SL_VERBOSE 8
+#define SL_NOPURGE 16
#define SL_CUSTOMMASK 0xFF
#define SL_LOADED 0x100
#define SL_MODIFIED 0x200
-#define SL_DISABLED 0x300
+#define SL_DISABLED 0x400
#define SL_SETFLAG(x) flags|=(x)
#define SL_CLRFLAG(x) flags&=~(x)
char *path;
time_t mtime;
//
+ void CheckAccess(void);
+ time_t MTime(void);
+ //
virtual cStructItem *ParseLine(char *line)=0;
void Modified(bool mod=true) { if(mod) SL_SETFLAG(SL_MODIFIED); else SL_CLRFLAG(SL_MODIFIED); }
bool IsModified(void) const { return SL_TSTFLAG(SL_MODIFIED); }
void ListLock(bool rw) { lock.Lock(rw); }
void ListUnlock(void) { lock.Unlock(); }
- void AutoGenWarn(void);
virtual void PostLoad(void) {}
- time_t MTime(void);
public:
cStructLoader(const char *Type, const char *Filename, int Flags);
virtual ~cStructLoader();
void SetCfgDir(const char *cfgdir);
virtual void Load(bool reload);
virtual void Save(void);
- virtual void Purge(void);
+ void Purge(void);
void Disable(void) { SL_SETFLAG(SL_DISABLED); }
};
class cStructLoaderPlain : public cStructLoader {
protected:
+ virtual cStructItem *ParseLine(char *line) { return 0; }
+ virtual bool ParseLinePlain(char *line)=0;
public:
cStructLoaderPlain(const char *Type, const char *Filename, int Flags);
virtual void Load(bool reload);
virtual void Save(void);
- virtual void Purge(void);
+ virtual void PreSave(FILE *f);
+ virtual void PostSave(FILE *f) {};
};
//--------------------------------------------------------------