/* #################################################################################### # # # Bildschirmtricks MikroPAD V2.0.0 # # http client layer # # # # Copyright (C) 2008 Philipp Fabian Benedikt Maier (aka. Dexter) # # # # This program 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 2 of the License, or # # (at your option) any later version. # # # # This program 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 this program; if not, write to the Free Software # # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA # # # #################################################################################### */ /* ## HEADER ########################################################################## */ #include #include #include #include "config.h" /* Include btx configuration */ #include "cept.h" /* include own header file */ #define HEAD_PARSER_MODE 1 /* Parser control constants */ #define HYPERTEXT_PARSER_MODE 2 /* #################################################################################### */ /* ## CEPT PARSER ##################################################################### */ /* Trigger on a specified tag (Note: tag should be null terminated e.g. "\0" ) */ static int applicationBtxCeptTriggerTag(char *data, char *tag) { char *dataPointer = data; char *tagPointer = tag; while(*tagPointer != '\0') { if((*tagPointer != *dataPointer)||(*dataPointer == '\0')) return -1; /* Not that tag what we are looking for */ dataPointer++; tagPointer++; } return 0; /* All chars match, this is the tag what we ar looking for */ } /* Translate a cept tag to its binary pendant */ static int applicationBtxCeptTranslateTag(char *data, char *code, int *size) { *size = 1; int sizecount = 0; char *dataPointer = data; char *tagPointer = data; char hexCode = 0; if(*dataPointer == '<') { dataPointer++; /* Calculate tag size */ while(*dataPointer != '>') { if((sizecount >= BTX_CEPT_TAG_MAXSIZE)||(*dataPointer == '\0')) { *code = *data; *size = 1; return -1; /* Invalid tag */ } dataPointer++; sizecount++; } *size = sizecount + 2; /* Tag + 2 chars for <> */ /* Examine tag */ if(applicationBtxCeptTriggerTag(tagPointer,"<0x\0") == 0) { tagPointer++; tagPointer++; tagPointer++; /* Note: I know this is not very witty but i was tired to code a more sophisticated piece of code... */ if(*tagPointer == '0') hexCode = 0; else if(*tagPointer == '1') hexCode = 16; else if(*tagPointer == '2') hexCode = 32; else if(*tagPointer == '3') hexCode = 48; else if(*tagPointer == '4') hexCode = 64; else if(*tagPointer == '5') hexCode = 80; else if(*tagPointer == '6') hexCode = 96; else if(*tagPointer == '7') hexCode = 112; else if(*tagPointer == '8') hexCode = 128; else if(*tagPointer == '9') hexCode = 144; else if(*tagPointer == 'a') hexCode = 160; else if(*tagPointer == 'b') hexCode = 176; else if(*tagPointer == 'c') hexCode = 192; else if(*tagPointer == 'd') hexCode = 208; else if(*tagPointer == 'e') hexCode = 224; else if(*tagPointer == 'f') hexCode = 240; tagPointer++; if(*tagPointer == '1') hexCode += 1; else if(*tagPointer == '2') hexCode += 2; else if(*tagPointer == '3') hexCode += 3; else if(*tagPointer == '4') hexCode += 4; else if(*tagPointer == '5') hexCode += 5; else if(*tagPointer == '6') hexCode += 6; else if(*tagPointer == '7') hexCode += 7; else if(*tagPointer == '8') hexCode += 8; else if(*tagPointer == '9') hexCode += 9; else if(*tagPointer == 'a') hexCode += 10; else if(*tagPointer == 'b') hexCode += 11; else if(*tagPointer == 'c') hexCode += 12; else if(*tagPointer == 'd') hexCode += 13; else if(*tagPointer == 'e') hexCode += 14; else if(*tagPointer == 'f') hexCode += 15; *code = hexCode; } else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = ' '; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_APB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_APF; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_APD; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_APU; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_CS; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_APR; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_SI; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_SO; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_CON; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_RPT; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_COF; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_CAN; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_SS2; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ESC; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_SS3; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_APH; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_US; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_NUL; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_SOH; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_STX; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ETX; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_EOT; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ENQ; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ACK; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ITB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_DLE; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_NAK; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_SYN; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ETB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_INI; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_TER; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_DCT; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_FSH; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_STD; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_EBX; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_SBX; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_NSZ; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_DBH; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_DBW; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_DBS; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_CDY; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_SPL; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_STL; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_CSI; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ABK; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ANR; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ANG; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ANY; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ANB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ANM; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ANC; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_ANW; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_MBK; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_MSR; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_MSG; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_MSY; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_MSB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_MSM; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_MSC; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_MSW; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_BBD; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_NBD; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_HMS; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_RMS; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_BKF; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_RDF; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_GRF; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_YLF; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_BLF; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_MGF; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_CNF; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_WHF; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_BKB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_RDB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_GRB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_YLB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_BLB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_MGB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_CNB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_WHB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_NPO; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_IPO; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_TRB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_STC; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_FBKB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_FRDB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_FGRB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_FYLB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_FBLB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_FMGB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_FCNB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_FWHB; else if(applicationBtxCeptTriggerTag(tagPointer,"\0") == 0) *code = CEPT_FTRB; else { *size = 1; *code = *data; return -1; /* Invalid tag! */ } return 0; } else { *size = 1; *code = *data; return -1; /* Invalid tag! */ } } /* Strip everthing that is encapsulated by */ static int applicationBtxCeptStripComments(char *data) { int ignoreData = 0; char *dataPointer = data; char *dataAheadPointer = data; while(*dataAheadPointer != '\0') { if(applicationBtxCeptTriggerTag(dataAheadPointer, "\0") == 0) { ignoreData = 0; dataAheadPointer += 3; } *dataPointer = *dataAheadPointer; if(ignoreData == 0) dataPointer++; dataAheadPointer++; } *dataPointer = '\0'; return 0; } /* Chech if the character is non pintable. Return 0 when printable and -1 when non printable */ static int applicationBtxCeptCheckPrintable(char *data) { if(*data == ' ') /* In our case a space is a non printable char (We have for that) */ return -1; else if ((*data >= 0x20)&&(*data <= 0x7E)) /* Printable char */ return 0; else if(*data == '\0') /* Do not destroy \0 terminator */ return 0; else /* All other chars are threated as non printable */ return -1; } /* Strip non printable characters */ static int applicationBtxCeptStripNonPrintable(char *data) { char *dataPointer = data; char *dataAheadPointer = data; while(*dataAheadPointer != '\0') { if(applicationBtxCeptCheckPrintable(dataAheadPointer) == -1) dataAheadPointer++; else { *dataPointer = *dataAheadPointer; dataPointer++; dataAheadPointer++; } } *dataPointer = '\0'; return 0; } /* Extract content and name from a meta tag string */ static int applicationBtxParseMetaTag(char *data, char *name, char *content) { char *dataPointer = data; char *namePointer = name; char *contentPointer = content; int copyControl = 0; int nameSizeCount = 0; /* Size counter to prevent buffer overflow */ int contentSizeCount = 0; while(*dataPointer != '>') { if(*dataPointer == '\0') return -1; /* Something has gone completely wrong */ if(*dataPointer == '\"') /* Switch off copy control when delimeter character passes by */ copyControl = 0; if(copyControl == 1) { if(nameSizeCount < (BTX_CEPT_META_TAG_NAME_BUFFERSIZE -1)) { *namePointer = *dataPointer; namePointer++; nameSizeCount++; } else return -1; } else if(copyControl == 2) { if(contentSizeCount < (BTX_CEPT_META_TAG_CONTENT_BUFFERSIZE -1)) { *contentPointer = *dataPointer; contentPointer++; contentSizeCount++; } else return -1; } else { if((applicationBtxCeptTriggerTag(dataPointer,"name=\"\0") == 0)) { dataPointer += 5; copyControl = 1; } else if((applicationBtxCeptTriggerTag(dataPointer,"content=\"\0") == 0)) { dataPointer += 8; copyControl = 2; } } dataPointer++; } *namePointer = '\0'; *contentPointer = '\0'; if(copyControl != 0) /* If copy control flag is not zero something gone wrong ! */ return -1; else return 0; } /* Parse the raw data that was received via http to a btx-cept-page */ int applicationBtxCeptParse(char *dataIn, btxCeptPageData *page) { char *dataInPointer = dataIn; char *dataOutPointer = page->ceptPage; int tagSize; char binaryCode; int parserMode = 0; /* Parser control flags */ int parserActive = 0; int tagHistory = 0; page->ceptPageLength = 0; /* Initalize data in the page structure */ page->metaTagCount = 0; applicationBtxCeptStripComments(dataInPointer); /* strip comments */ applicationBtxCeptStripNonPrintable(dataInPointer); /* strip non printable chars (and whitespaces) */ while(*dataInPointer != '\0') { /* Handle parser control */ if((applicationBtxCeptTriggerTag(dataInPointer,"\0") == 0)) { if(tagHistory == 0) { tagHistory = 1; parserActive = 1; } else return -1; } if((applicationBtxCeptTriggerTag(dataInPointer,"\0") == 0)) { if(tagHistory == 1) { tagHistory = 2; parserMode = HEAD_PARSER_MODE; } else return -1; } if((applicationBtxCeptTriggerTag(dataInPointer,"\0") == 0)) { if(tagHistory == 2) { tagHistory = 3; parserMode = 0; } else return -1; } if((applicationBtxCeptTriggerTag(dataInPointer,"\0") == 0)) { if(tagHistory == 3) { tagHistory = 4; parserMode = HYPERTEXT_PARSER_MODE; dataInPointer += 6; /* Override the body tag */ } else return -1; } if((applicationBtxCeptTriggerTag(dataInPointer,"\0") == 0)) { if(tagHistory == 4) { tagHistory = 5; parserMode = 0; } else return -1; } if((applicationBtxCeptTriggerTag(dataInPointer,"\0") == 0)) { if(tagHistory == 5) { tagHistory = 6; parserActive = 0; } else return -1; } /* Head parser mode */ if((parserMode == HEAD_PARSER_MODE)&&(parserActive == 1)) { if((applicationBtxCeptTriggerTag(dataInPointer,"metaTagCountmetaName[page->metaTagCount],page->metaContent[page->metaTagCount]) == -1) return -1; page->metaTagCount++; } else return -1; } dataInPointer++; } /* Hypertect parser mode */ else if((parserMode == HYPERTEXT_PARSER_MODE)&&(parserActive == 1)) { if(page->ceptPageLength < BTX_CEPT_BINARY_BUFFERSIZE) { applicationBtxCeptTranslateTag(dataInPointer,&binaryCode,&tagSize); /* Translate hypertext to binary */ dataInPointer += tagSize; *dataOutPointer = binaryCode; dataOutPointer++; page->ceptPageLength++; } else return 0; } /* Parser off */ else dataInPointer++; } *dataOutPointer = '\0'; /* Do final check, every flack must be set! */ if((tagHistory == 6)&&(parserActive == 0)&&(parserMode == 0)) return 0; else return -1; } /* #################################################################################### */