summaryrefslogtreecommitdiff
path: root/event.c
diff options
context:
space:
mode:
Diffstat (limited to 'event.c')
-rw-r--r--event.c303
1 files changed, 258 insertions, 45 deletions
diff --git a/event.c b/event.c
index 69700cd..43ef7e7 100644
--- a/event.c
+++ b/event.c
@@ -5,10 +5,11 @@
*
*/
+#include <ctype.h>
+#include <vdr/status.h>
#include "event.h"
+#include "setup.h"
-#include "common.h"
-#include <ctype.h>
char* cEventBlock::duptolower(const char *s) {
char *c = strdup(s);
@@ -18,19 +19,7 @@ char* cEventBlock::duptolower(const char *s) {
return c;
}
-char* cEventBlock::getTimeStamp()
-//Attention: this one will not return the exact UNIX time!
-//Some internal cast seems to blur the word length here.
-//For use in the block plugin this implementation however
-//suffices because it returns something in the millisecond
-//range. If you want to improve please send me an email ;)
-{
- char *dummy;
- asprintf(&dummy, "%jd", (intmax_t)time_ms());
- return dummy;
-}
-
-const char* cEventBlock::LastTitle="block_dummy_title3";
+const char* cEventBlock::LastTitle="just initialized";
const bool* cEventBlock::ReplayingRecording=false;
cEventsBlock EventsBlock;
@@ -38,7 +27,8 @@ cEventsBlock EventsBlock;
cEventBlock::cEventBlock(void):
mRegularExp(false),
mIgnoreCase(false),
- mCompiled(false)
+ mCompiled(false),
+ whitelisted(false)
{
strncpy(mPattern, tr("New Entry"), sizeof(mPattern));
}
@@ -46,7 +36,8 @@ cEventBlock::cEventBlock(void):
cEventBlock::cEventBlock(const char *Pattern):
mRegularExp(false),
mIgnoreCase(false),
- mCompiled(false)
+ mCompiled(false),
+ whitelisted(false)
{
strncpy(mPattern, Pattern, sizeof(mPattern));
}
@@ -62,46 +53,104 @@ cEventBlock &cEventBlock::operator=(const cEventBlock &Src)
strcpy(mPattern, Src.mPattern);
mRegularExp = Src.mRegularExp;
mIgnoreCase = Src.mIgnoreCase;
+ whitelisted = Src.whitelisted;
mCompiled = false;
Compile();
return *this;
}
+/*
+bool cEventBlock::operator==(const cEventBlock Src) //include whitelisting?
+{
+ bool b1=(strcmp(duptolower(mPattern),duptolower(Src.mPattern))==0);
+ bool b2=(mRegularExp==Src.mRegularExp);
+ bool b3=(mIgnoreCase==Src.mIgnoreCase);
+ return b1&&b2&&b3;
+}
+*/
+
cEventBlock::~cEventBlock()
{
if (mRegularExp)
regfree(&mExpression);
}
-bool cEventBlock::Acceptable(const char *Event) const
-{
+
+bool cEventBlock::doesMatch(const char *Event) const
+{//in fact here we only check if the current event has any match in the list
+ //of course Event is examined according to the rules defined in the blacklist
if (mRegularExp)
- return regexec(&mExpression, Event, 0, NULL, 0) != 0;
- else if (mIgnoreCase) {
+ return !(regexec(&mExpression, Event, 0, NULL, 0) != 0);
+ if (strlen(mPattern)==0) //workaround for empty patterns
+ {
+ return (strlen(Event)==0);
+ }
+ if (mIgnoreCase)
+ {
char *ev = cEventBlock::duptolower(Event);
char *pa = cEventBlock::duptolower(mPattern);
printf("check for %s in %s\n", pa, ev);
bool res = strstr(ev, pa) == NULL;
free(ev); free(pa);
- return res;
+ return !res;
} else
- return strstr(Event, mPattern) == NULL;
+ return !(strstr(Event, mPattern) == NULL);
}
-bool cEventBlock::Parse(char *s) {
- char *patternbuf = NULL;
- int fields = sscanf(s, "%d:%d:%a[^\n]", &mRegularExp, &mIgnoreCase, &patternbuf);
-
- if (fields == 3) {
- strncpy(mPattern, skipspace(stripspace(patternbuf)), sizeof(mPattern));
- free(patternbuf);
- } else { // backward compatibility
- strncpy(mPattern, skipspace(stripspace(s)), sizeof(mPattern));
- mRegularExp = false;
- mIgnoreCase = false;
- }
-
- return Compile();
+bool cEventBlock::Parse(char *s)
+{
+ char *patternbuf=NULL;
+ int fields=sscanf(s,"%d:%d:%a[^\n]", &mRegularExp, &mIgnoreCase, &patternbuf);
+
+ if (fields==3)
+ {
+ strncpy(mPattern,patternbuf,sizeof(mPattern));
+ char c=NULL;
+ int fields2=0;
+
+ if (strcmp(patternbuf,"-:")==0)//workaround if pattern empty
+ {
+ fields2=2;
+ c='-';
+ patternbuf=(char*)"";
+ }
+ else
+ {
+ if (strcmp(patternbuf,"+:")==0)
+ {
+ fields2=2;
+ c='+';
+ patternbuf=(char*)"";
+ } //end of workaround
+ else
+ {
+ free(patternbuf); //normal entry handling
+ fields2=sscanf(mPattern,"%1c:%a[^\n]",&c,&patternbuf);
+ }
+ }
+
+ if (fields2==2)
+ {
+ if(c=='+')
+ {
+ whitelisted=true;
+ }
+ else whitelisted=false;
+ strncpy(mPattern,skipspace(stripspace(patternbuf)),sizeof(mPattern));
+ }
+ else
+ {
+ whitelisted=false;
+ }
+ }
+ else
+ { // old taste backward compatibility
+ strncpy(mPattern, skipspace(stripspace(s)), sizeof(mPattern));
+ mRegularExp = false;
+ mIgnoreCase = false;
+ whitelisted = false;
+ }
+ return Compile();
}
bool cEventBlock::Compile(void) {
@@ -117,27 +166,191 @@ bool cEventBlock::Compile(void) {
}
bool cEventBlock::Save(FILE *f) {
- return fprintf(f, "%d:%d:%s\n", mRegularExp, mIgnoreCase, mPattern) > 0;
+ char c='c';
+ if (whitelisted) c='+';
+ else c='-';
+ return fprintf(f, "%d:%d:%c:%s\n", mRegularExp, mIgnoreCase, c, mPattern) > 0;
}
-bool cEventsBlock::Acceptable(const char *Event) {
- const cEventBlock *event = First();
- while (event != NULL) {
- if (!event->Acceptable(Event))
- return false;
- event = Next(event);
+
+bool cEventsBlock::Acceptable(const char *src)
+{
+ cVector<cEventBlock*> temp_vec (5);
+ cEventBlock stringmatch=*(new cEventBlock("nostringmatch"));
+
+ ListMatches(src,&temp_vec,stringmatch);
+ if(strcmp(stringmatch.Pattern(),"nostringmatch")!=0)
+ {
+#ifdef LOGGING
+ dsyslog("plugin-block: exact string match found %s: ",stringmatch.Pattern());
+#endif
+ if (stringmatch.isWhitelisted())
+ {
+#ifdef LOGGING
+ dsyslog("plugin-block: string match entry is whitelisted - returning acceptable");
+#endif
+ cSetupBlock::LastAcceptableChannel=cDevice::CurrentChannel();
+ return true;
}
+#ifdef LOGGING
+ dsyslog("plugin-block: string match entry is not whitelisted - returning not acceptable");
+#endif
+ return false;
+ }
+
+ int vec_size=temp_vec.Size();
+ if (vec_size<1)
+ {
+#ifdef LOGGING
+ dsyslog("plugin-block: no matching pattern found at all - returning acceptable");
+#endif
+ cSetupBlock::LastAcceptableChannel=cDevice::CurrentChannel();
return true;
+ }
+
+ bool b=temp_vec.At(0)->isWhitelisted();
+ int count=1;
+ for(;count<vec_size;count++)
+ {
+ if (temp_vec.At(count)->isWhitelisted()!=b)
+ {
+#ifdef LOGGING
+ dsyslog("plugin-block: Contradictory rules detected - returning fuzzy fallback: %d",cSetupBlock::FuzzyFallback);
+#endif
+ b=cSetupBlock::FuzzyFallback;
+ if (b) cSetupBlock::LastAcceptableChannel=cDevice::CurrentChannel();
+ return b;
+ }
+ }
+#ifdef LOGGING
+ dsyslog("plugin-block: Acceptable returning: %d",b);
+#endif
+ if (b) cSetupBlock::LastAcceptableChannel=cDevice::CurrentChannel();
+ return b;
}
+
+
cEventsBlock &cEventsBlock::operator=(const cEventsBlock &Source) {
cList<cEventBlock>::Clear();
const cEventBlock *event = Source.First();
while (event != NULL) {
- printf("transfering %p\n", event);
+ printf("transferring %p\n", event);
Add(new cEventBlock(*event));
event = Source.Next(event);
}
return *this;
}
+
+void cEventsBlock::ListMatches(const char *title, cVector <cEventBlock*> *match_vec, cEventBlock &stringmatch)
+{
+ cEventBlock *event = First();
+ char* temp_title=strdup(title);
+ char* temp_pattern=NULL;
+ while (event != NULL) {
+ if (event->doesMatch(title)) //doesMatch examines if there is a match according to all properties of the blacklist entry
+ {
+ #ifdef LOGGING
+ char *condition=(char*)(event->isWhitelisted() ? "positive" : "negative");
+ dsyslog("plugin-block: Matching rule detected - Pattern: '%s' (%s)",event->Pattern(),condition);
+ #endif
+ match_vec->Append(event); //put match in the vector; of course there could be more than one match
+ //lets say you would block everything containing the word 'Judge'
+ //but 'Judge Dredd' also has an explicit entry
+ //in case Judge Dredd is the current show then both entries would match
+ //therefore it is necessary to do further analysis of the type of the matches
+ //or the according rules and priorities respectively
+
+ if (event->IgnoreCase())//now we check if there the current match is also a stringmatching entry
+ //first check if ignore case is set
+ //if so replace the strings to be compared by their lower case pendants
+ //so next we only have to do one comparison
+ {
+ temp_title=cEventBlock::duptolower(temp_title);
+ temp_pattern=cEventBlock::duptolower(event->Pattern());
+ }
+ else
+ {
+ temp_pattern=(char*)event->Pattern();
+ }
+ if (strcmp(temp_title,temp_pattern)==0) //check for stringmatch
+ {
+#ifdef LOGGING
+ dsyslog("plugin-block: ListMatches: stringmatch found '%s'",event->Pattern());
+#endif
+ stringmatch=*event;
+ }
+ }
+ event = Next(event);
+ }
+}
+
+void cEventsBlock::ListMatches(const char *title, cVector <cEventBlock*> *match_vec)
+{
+ cEventBlock *event = First();
+ while (event != NULL) {
+ if (event->doesMatch(title))
+ {
+ match_vec->Append(event);
+ }
+ event = Next(event);
+ }
+}
+
+
+cEventBlock* cEventsBlock::hasStringMatch(const char* src, bool ignorecase)
+{
+ //TODO check if there is a better way to check for matches and stringmatches
+ //which avoids redundant walks through the blacklist
+ cEventBlock *event_ptr=First();
+ char *low_src=cEventBlock::duptolower(src);
+ while (event_ptr!=NULL)
+ {
+ if (event_ptr->IgnoreCase() || ignorecase)
+ {
+ char *low_pattern=cEventBlock::duptolower(event_ptr->Pattern());
+ if (strcmp(low_src,low_pattern)==0)
+ {
+ return event_ptr;
+ }
+ }
+ else
+ {
+ if (strcmp(src,event_ptr->Pattern())==0)
+ {
+ return event_ptr;
+ }
+ }
+ event_ptr=Next(event_ptr);
+ }
+ return NULL;
+}
+
+
+int cEventsBlock::getIndexOf(cEventBlock *src)
+{
+ //TODO make this a recursive method taking a list pointer and lets begin search in the middle of the list
+ //(middle->Previous() and middle->Next())
+ //find out if the first char of Pattern is less or higher than src.char etc
+ //once the first char of src matches begin search there straight forward
+ //this might speedup setting cursor to the right position (New entry) in the OSD
+ //NO: it turned out that the Get method of cListBase will have a serious impact on this solution
+ //maybe a major rewrite and/or use of STL implementations of lists or vectors etc would be a better alternative
+
+ cEventBlock* listptr=First();
+ int list_count=0;
+ const char* src_pattern=src->Pattern();
+
+ while(listptr!=NULL)
+ {
+ if (strcmp(src_pattern,listptr->Pattern())==0)
+ {
+ return list_count;
+ }
+ list_count+=1;
+ listptr=Next(listptr);
+ }
+ return -1;
+}
+ \ No newline at end of file