/* This file is part of vdr-filebrowser. vdr-filebrowser 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 3 of the License, or (at your option) any later version. vdr-filebrowser 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 Foobar. If not, see . */ #include #include #include "tools.h" /* Implementation cStringContainerList */ bool cStringContainerList::Contains(const char* String) { for(cStringContainer *i = First(); i; i=Next(i)) { if(strcmp(i->GetObject(), String)==0) { return true; } } return false; } void cStringContainerList::Remove(const char* String) { for(cStringContainer *i = First(); i!=NULL; i=Next(i)) { if(strcmp(i->GetObject(), String)==0) { Del(i); break; } } } /* Implementation of cConfigReader */ cConfigReader::cConfigReader(cFilebrowserStatebag* Statebag, const char* Filename) { char* Name=(char*)malloc(strlen(Statebag->ConfigDirectory) + strlen(Filename) + 2); sprintf(Name, "%s/%s", *(Statebag->ConfigDirectory), Filename); File=fopen(Name, "r"); D(fprintf(stderr, "open file %s %s, handle is %X\n", Name, File ? "succeeded" : "failed", File)); free(Name); Reader=new cReadLine(); } cConfigReader::~cConfigReader() { D(fprintf(stderr, "cConfigReader destructor called [Handle: %X]\n", File)); if(File) fclose(File); if(Reader) delete(Reader); D(fprintf(stderr, "cConfigReader destructor finished\n")); } char* cConfigReader::Read() { if(!File) { return NULL; } char *line; do { line = Reader->Read(File); StripComment(line); } while ((line != NULL) && IsBlank(line)); return line; } void cConfigReader::StripComment(char* string) { if (string) { char *commentPosition = strchr(string, '#'); if (commentPosition) { *commentPosition = 0; } } } bool cConfigReader::IsBlank(const char* string) { bool blank = true; if (string != NULL) { int len = strlen(string); for (int i = 0; i < len; i++) { if (!isspace(string[i])) { blank = false; break; } } } return blank; } /* Implementation of cConfigParser */ cConfigParser::cConfigParser(char* Line, bool TakePointer) { this->Line=TakePointer ? Line : strdup(Line); Buffer=(char*)malloc(strlen(Line) + 1); Pos=this->Line; FieldNumber=-1; CurrentLength=-1; } cConfigParser::~cConfigParser() { if(Line) free(Line); if(Buffer) free(Buffer); } char* cConfigParser::Next() { if(Pos!=Line && *(Pos-1)=='\0') { FieldNumber=-1; CurrentLength=-1; return NULL; } char* BufferPos=Buffer; for(; Pos==Line || *(Pos-1)!='\0'; Pos++) { switch(*Pos) { case '\0': case Delimiter: Pos++; *(BufferPos)='\0'; FieldNumber++; CurrentLength=BufferPos - Buffer; return Buffer; case Escape: if(*(Pos+1)==Delimiter) { *(BufferPos++)=Delimiter; Pos++; } else { *(BufferPos++)=*Pos; } break; default: *(BufferPos++)=*Pos; break; } } return NULL; } char* cConfigParser::First() { Pos=Line; FieldNumber=-1; CurrentLength=-1; return Next(); } /* Implementation of cCommandParser */ cCommandParser::cCommandParser(const cString &Command, bool DoReplacements, bool ShellEscape) { this->DoReplacements=DoReplacements; this->Command=Command; this->ShellEscape=ShellEscape; Handlers=new cHandlerList(); } cCommandParser::~cCommandParser() { if(Handlers) delete Handlers; } void cCommandParser::AddHandler(char Key, ParseProc Proc, void* Data) { cHandler* NewHandler=new cHandler(); NewHandler->Proc=Proc; NewHandler->Params.Key=Key; NewHandler->Params.Data=Data; NewHandler->Params.ShellEscape=ShellEscape; NewHandler->Params.DoReplacements=DoReplacements; Handlers->Add(NewHandler); } void cCommandParser::AddReplacement(char Key, const char* String) { AddHandler(Key, &cCommandParser::ReplacementHandler, (void*)String); } cString cCommandParser::Parse() { if(!*Command) { return cString(); } #define BUFLEN 50 char* Text=(char*)malloc(BUFLEN); Text[0]='\0'; char* TextPos=Text; int TextLength=BUFLEN; D(fprintf(stderr, "parsing %s\n", *Command)); for(char* i=(char*)*Command; i==*Command || *(i-1)!='\0'; i++) { if(TextPos-Text >= TextLength) { int Pos=TextPos-Text; TextLength+=BUFLEN; D(fprintf(stderr, "reallocating %d bytes, Text is \"%s\"\n", TextLength, Text)); Text=(char*)realloc(Text, TextLength); TextPos=Text+Pos; } if(*i=='%') { char* InsText=NULL; int InsTextLength=0; cHandler* FoundHandler=NULL; for(cHandler* h=Handlers->First(); h; h=(cHandler*)h->Next()) { if(h->Params.Key==*(i+1)) { FoundHandler=h; } } if(FoundHandler) { InsText=FoundHandler->Proc(*Command, i, &FoundHandler->Params); InsTextLength=(InsText ? strlen(InsText) + 1 : 0); } else { InsText=(char*)malloc(2); InsTextLength=2; sprintf(InsText, "%c", *(i+1)); } if(TextPos+InsTextLength-Text >= TextLength) { int Pos=TextPos-Text; TextLength+=InsTextLength+BUFLEN; Text=(char*)realloc(Text, TextLength); TextPos=Text+Pos; } if(InsText) { strcpy(TextPos, InsText); TextPos+=InsTextLength-1; free(InsText); } i++; continue; } *TextPos++=*i; } D(fprintf(stderr, "Finished parsing - returning %s\n", Text)); return cString(Text, true); } char* cCommandParser::ReplacementHandler(const char* OrgString, const char* CurrentPos, const cHandlerParameters* Params) { if(!Params->DoReplacements) { return NULL; } if(Params->ShellEscape) { return EscapeShellArgument((char*)Params->Data, NULL); } return strdup((char*)Params->Data); } char* cCommandParser::EscapeShellArgument(char* Argument, int* EscapedLength) { #define ESCAPE_SEQUENCE "'\\''" #define ESCAPE_SEQUENCE_LENGTH strlen(ESCAPE_SEQUENCE) D(fprintf(stderr, "escaping shell argument %s\n", Argument)); int Length=strlen(Argument); char* result=(char*)malloc(Length*ESCAPE_SEQUENCE_LENGTH + 3); char* result_pos=result; *result_pos++='\''; Length++; for(char* i=Argument; *i!='\0'; i++) { if(*i!='\'') { *result_pos++=*i; } else { strcpy(result_pos, ESCAPE_SEQUENCE); result_pos+=ESCAPE_SEQUENCE_LENGTH; Length+=ESCAPE_SEQUENCE_LENGTH-1; } } *result_pos++='\''; *result_pos++='\0'; Length++; result=(char*)realloc(result, Length+1); D(fprintf(stderr, "finished escaping - returning %s[%d]\n", result, Length)); if(EscapedLength) { *EscapedLength=Length; } return result; }