Index: trunk/i386/libsaio/xml.c =================================================================== --- trunk/i386/libsaio/xml.c (revision 795) +++ trunk/i386/libsaio/xml.c (revision 796) @@ -27,6 +27,47 @@ #include "sl.h" #include "xml.h" +string_ref *ref_strings = NULL; + +/// TODO: remove below +static char* buffer_start = NULL; +// TODO: redo the next two functions +void SaveRefString(char* string, int id) +{ + //printf("Adding Ref String %d (%s)\n", id, string); + string_ref* tmp = ref_strings; + while(tmp) + { + if(tmp->id == id) + { + tmp->string = malloc(strlen(string)+1); + sprintf(tmp->string, "%s", string); + return; + } + tmp = tmp->next; + } + + string_ref* new_ref = malloc(sizeof(string_ref)); + new_ref->string = malloc(strlen(string)+1); + sprintf(new_ref->string, "%s", string); + new_ref->id = id; + new_ref->next = ref_strings; + ref_strings = new_ref; +} + +char* GetRefString(int id) +{ + string_ref* tmp = ref_strings; + while(tmp) + { + if(tmp->id == id) return tmp->string; + tmp = tmp->next; + } + //verbose("Unable to locate Ref String %d\n", id); + return ""; +} + + struct Module { struct Module *nextModule; long willLoad; @@ -52,7 +93,7 @@ unsigned long signature1; unsigned long signature2; unsigned long length; - unsigned long alder32; + unsigned long adler32; unsigned long version; unsigned long numDrivers; unsigned long reserved1; @@ -110,6 +151,50 @@ return 0; } + +// XMLGetTag(int index) + +// XMLTagCount( TagPtr dict ) +int XMLTagCount( TagPtr dict ) +{ + int count = 0; + TagPtr tagList, tag; + + if (dict->type != kTagTypeDict && dict->type != kTagTypeArray) return 0; + tag = 0; + tagList = dict->tag; + while (tagList) + { + tag = tagList; + tagList = tag->tagNext; + + if (((tag->type != kTagTypeKey) && ((tag->string == 0) || (tag->string[0] == 0))) + && (dict->type != kTagTypeArray) // If we are an array, any element is valid + ) continue; + + if(tag->type == kTagTypeKey) printf("Located key %s\n", tag->string); + + count++; + } + + return count; +} + +TagPtr XMLGetElement( TagPtr dict, int id ) +{ + if(dict->type != kTagTypeArray) return 0; + + int element = 0; + TagPtr tmp = dict->tag; + + while(element < id) + { + element++; + tmp = tmp->tagNext; + } + + return tmp; +} /* Function for basic XML character entities parsing */ char* @@ -168,12 +253,13 @@ return out; } -#if UNUSED +//#if UNUSED //========================================================================== // XMLParseFile -// Expects to see one dictionary in the XML file. +// Expects to see one dictionary in the XML file, the final pos will be returned +// If the pos is not equal to the strlen, then there are multiple dicts // Puts the first dictionary it finds in the -// tag pointer and returns 0, or returns -1 if not found. +// tag pointer and returns the end of the dic, or returns -1 if not found. // long XMLParseFile( char * buffer, TagPtr * dict ) @@ -181,10 +267,18 @@ long length, pos; TagPtr tag; pos = 0; - + char *configBuffer; + + + + configBuffer = malloc(strlen(buffer)+1); + strcpy(configBuffer, buffer); + + buffer_start = configBuffer; + while (1) { - length = XMLParseNextTag(buffer + pos, &tag); + length = XMLParseNextTag(configBuffer + pos, &tag); if (length == -1) break; pos += length; @@ -194,17 +288,18 @@ XMLFreeTag(tag); } - if (length < 0) { + free(configBuffer); + if (length < 0) { return -1; } *dict = tag; - return 0; + return pos; } -#endif /* UNUSED */ +//#endif /* UNUSED */ //========================================================================== // ParseNextTag - +// TODO: cleanup long XMLParseNextTag( char * buffer, TagPtr * tag ) { @@ -213,62 +308,235 @@ length = GetNextTag(buffer, &tagName, 0); if (length == -1) return -1; - + pos = length; if (!strncmp(tagName, kXMLTagPList, 6)) { length = 0; } + /***** dict ****/ else if (!strcmp(tagName, kXMLTagDict)) { length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0); } - else if (!strcmp(tagName, kXMLTagDict "/")) + else if (!strncmp(tagName, kXMLTagDict, strlen(kXMLTagDict)) && tagName[strlen(tagName)-1] == '/') { length = ParseTagList(buffer + pos, tag, kTagTypeDict, 1); } + else if (!strncmp(tagName, kXMLTagDict " ", strlen(kXMLTagDict " "))) + { + length = ParseTagList(buffer + pos, tag, kTagTypeDict, 0); + } + /***** key ****/ else if (!strcmp(tagName, kXMLTagKey)) { length = ParseTagKey(buffer + pos, tag); } + + /***** string ****/ else if (!strcmp(tagName, kXMLTagString)) { length = ParseTagString(buffer + pos, tag); } + else if (!strncmp(tagName, kXMLTagString " ", strlen(kXMLTagString " "))) + { + // TODO: save tag if if found + if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringID, strlen(kXMLStringID))) + { + // ID= + int id = 0; + int cnt = strlen(kXMLTagString " " kXMLStringID "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagString " " kXMLStringID "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseStringID error (0x%x)\n", *val); + getc(); + return -1; + + } + + } + length = ParseTagString(buffer + pos, tag); + + SaveRefString(buffer + pos, id); + } + else if(!strncmp(tagName + strlen(kXMLTagString " "), kXMLStringIDRef, strlen(kXMLStringIDRef))) + { + // IDREF= + int id = 0; + int cnt = strlen(kXMLTagString " " kXMLStringIDRef "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagString " " kXMLStringIDRef "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseStringIDREF error (0x%x)\n", *val); + getc(); + return -1; + + } + + } + char* str = GetRefString(id); + + TagPtr tmpTag = NewTag(); + tmpTag->type = kTagTypeString; + tmpTag->string = str; + tmpTag->tag = 0; + tmpTag->tagNext = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0; + *tag = tmpTag; + + length = 0; + //printf("Located IDREF, id = %d, string = %s\n", id, str); + } + + } + + /***** integer ****/ else if (!strcmp(tagName, kXMLTagInteger)) { length = ParseTagInteger(buffer + pos, tag); } + else if (!strncmp(tagName, kXMLTagInteger " ", strlen(kXMLTagInteger " "))) + { + if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringID, strlen(kXMLStringID))) + { + // ID= + int id = 0; + int cnt = strlen(kXMLTagInteger " " kXMLStringID "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagInteger " " kXMLStringID "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseIntegerID error (0x%x)\n", *val); + getc(); + return -1; + + } + + } + length = ParseTagInteger(buffer + pos, tag); + + SaveRefString((*tag)->string, id); + } + else if(!strncmp(tagName + strlen(kXMLTagInteger " "), kXMLStringIDRef, strlen(kXMLStringIDRef))) + { + // IDREF= + int id = 0; + int cnt = strlen(kXMLTagInteger " " kXMLStringIDRef "\"") + 1; + while ((tagName[cnt] != '\0') && (tagName[cnt] != '"')) cnt++; + tagName[cnt] = 0; + char* val = tagName + strlen(kXMLTagInteger " " kXMLStringIDRef "\""); + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + id = (id * 10) + (*val++ - '0'); + } + else + { + printf("ParseStringIDREF error (0x%x)\n", *val); + getc(); + return -1; + + } + + } + int integer = (int)GetRefString(id); + + TagPtr tmpTag = NewTag(); + tmpTag->type = kTagTypeInteger; + tmpTag->string = (char*) integer; + tmpTag->tag = 0; + tmpTag->tagNext = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start + pos : 0; + + *tag = tmpTag; + + length = 0; + //printf("Located IDREF, id = %d, string = %s\n", id, str); + } + else + { + length = ParseTagInteger(buffer + pos, tag); + } + } + + /***** data ****/ else if (!strcmp(tagName, kXMLTagData)) { length = ParseTagData(buffer + pos, tag); } + else if (!strncmp(tagName, kXMLTagData " ", strlen(kXMLTagData " "))) + { + length = ParseTagData(buffer + pos, tag); + } else if (!strcmp(tagName, kXMLTagDate)) { length = ParseTagDate(buffer + pos, tag); } + + /***** date ****/ + else if (!strncmp(tagName, kXMLTagDate " ", strlen(kXMLTagDate " "))) + { + length = ParseTagDate(buffer + pos, tag); + } + + /***** false ****/ else if (!strcmp(tagName, kXMLTagFalse)) { length = ParseTagBoolean(buffer + pos, tag, kTagTypeFalse); } + /***** true ****/ else if (!strcmp(tagName, kXMLTagTrue)) { length = ParseTagBoolean(buffer + pos, tag, kTagTypeTrue); } + + /***** array ****/ else if (!strcmp(tagName, kXMLTagArray)) { length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0); } + else if (!strncmp(tagName, kXMLTagArray " ", strlen(kXMLTagArray " "))) + { + length = ParseTagList(buffer + pos, tag, kTagTypeArray, 0); + } else if (!strcmp(tagName, kXMLTagArray "/")) { length = ParseTagList(buffer + pos, tag, kTagTypeArray, 1); } + + /***** unknown ****/ else { *tag = 0; length = 0; } + if (length == -1) return -1; return pos + length; @@ -316,6 +584,7 @@ tmpTag->type = type; tmpTag->string = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start : 0; tmpTag->tag = tagList; tmpTag->tagNext = 0; @@ -358,6 +627,7 @@ tmpTag->type = kTagTypeKey; tmpTag->string = string; tmpTag->tag = subTag; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; tmpTag->tagNext = 0; *tag = tmpTag; @@ -373,12 +643,11 @@ { long length; char * string; - TagPtr tmpTag; length = FixDataMatchingTag(buffer, kXMLTagString); if (length == -1) return -1; - tmpTag = NewTag(); + TagPtr tmpTag = NewTag(); if (tmpTag == 0) return -1; string = NewSymbol(buffer); @@ -391,6 +660,7 @@ tmpTag->type = kTagTypeString; tmpTag->string = string; tmpTag->tag = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; tmpTag->tagNext = 0; *tag = tmpTag; @@ -404,23 +674,99 @@ ParseTagInteger( char * buffer, TagPtr * tag ) { long length, integer; + bool negative = false; TagPtr tmpTag; - - length = FixDataMatchingTag(buffer, kXMLTagInteger); + char* val = buffer; + int size; + + + if(buffer[0] == '<') + { + printf("Warning integer is non existant\n"); + getc(); + tmpTag = NewTag(); + tmpTag->type = kTagTypeInteger; + tmpTag->string = 0; + tmpTag->tag = 0; + tmpTag->offset = 0; + tmpTag->tagNext = 0; + + *tag = tmpTag; + + return 0; + } + + size = length = FixDataMatchingTag(buffer, kXMLTagInteger); if (length == -1) return -1; tmpTag = NewTag(); if (tmpTag == 0) return -1; integer = 0; - + + if(size > 1 && (val[1] == 'x' || val[1] == 'X')) // Hex value + { + val += 2; + while(*val) + { + if ((*val >= '0' && *val <= '9')) // 0 - 9 + { + integer = (integer * 16) + (*val++ - '0'); + } + else if ((*val >= 'a' && *val <= 'f')) // a - f + { + integer = (integer * 16) + (*val++ - 'a' + 10); + } + else if ((*val >= 'A' && *val <= 'F')) // A - F + { + integer = (integer * 16) + (*val++ - 'a' + 10); + } + else + { + printf("ParseTagInteger hex error (0x%x) in buffer %s\n", *val, buffer); + getc(); + return -1; + + } + + } + } + else if ( size ) // Decimal value + { + if (*val == '-') + { + negative = true; + val++; + size--; + } + + for (integer = 0; size > 0; size--) + { + if(*val) // UGLY HACK, fix me. + { + if (*val < '0' || *val > '9') + { + printf("ParseTagInteger decimal error (0x%x) in buffer %s\n", *val, buffer); + getc(); + return -1; + } + + integer = (integer * 10) + (*val++ - '0'); + } + } + + if (negative) + integer = -integer; + } + tmpTag->type = kTagTypeInteger; - tmpTag->string = (char *)integer; - tmpTag->tag = 0; + tmpTag->string = (char *)integer; + tmpTag->tag = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; tmpTag->tagNext = 0; *tag = tmpTag; - + return length; } @@ -432,16 +778,24 @@ { long length; TagPtr tmpTag; - + length = FixDataMatchingTag(buffer, kXMLTagData); if (length == -1) return -1; tmpTag = NewTag(); if (tmpTag == 0) return -1; + //printf("ParseTagData unimplimented\n"); + //printf("Data: %s\n", buffer); + // getc(); + + // TODO: base64 decode + + char* string = NewSymbol(buffer); tmpTag->type = kTagTypeData; - tmpTag->string = 0; + tmpTag->string = string; tmpTag->tag = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; tmpTag->tagNext = 0; *tag = tmpTag; @@ -464,9 +818,13 @@ tmpTag = NewTag(); if (tmpTag == 0) return -1; + printf("ParseTagDate unimplimented\n"); + getc(); + tmpTag->type = kTagTypeDate; tmpTag->string = 0; tmpTag->tag = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; tmpTag->tagNext = 0; *tag = tmpTag; @@ -488,6 +846,7 @@ tmpTag->type = type; tmpTag->string = 0; tmpTag->tag = 0; + tmpTag->offset = buffer_start ? buffer - buffer_start: 0; tmpTag->tagNext = 0; *tag = tmpTag; @@ -609,6 +968,7 @@ tag->type = kTagTypeNone; tag->string = 0; tag->tag = 0; + tag->offset = 0; tag->tagNext = gTagsFree; gTagsFree = tag; #else @@ -720,3 +1080,71 @@ return symbol; } + + + +bool XMLIsType(TagPtr dict, enum xmltype type) +{ + if(!dict) return (type == kTagTypeNone); + return (dict->type == type); +} + + +/*** Cast functions ***/ +TagPtr XMLCastArray(TagPtr dict) +{ + if(!dict) return NULL; + if(dict->type == kTagTypeArray) return dict; + else return NULL; +} + + +TagPtr XMLCastDict(TagPtr dict) +{ + if(!dict) return NULL; + if(dict->type == kTagTypeDict) return dict; + else return NULL; +} + +char* XMLCastString(TagPtr dict) +{ + if(!dict) return NULL; + + if((dict->type == kTagTypeString) || + (dict->type == kTagTypeKey)) return dict->string; + + return NULL; +} + +long XMLCastStringOffset(TagPtr dict) +{ + if(dict && + ((dict->type == kTagTypeString) || + (dict->type == kTagTypeKey))) + { + return dict->offset; + } + else + { + return -1; + } +} + + +bool XMLCastBoolean(TagPtr dict) +{ + if(!dict) return false; + if(dict->type == kTagTypeTrue) return true; + return false; +} + +int XMLCastInteger(TagPtr dict) +{ + if(!dict) + { + printf("XMLCastInteger: null dict\n"); + return 0; + } + if(dict->type == kTagTypeInteger) return (int)(dict->string); + return 0; +} Index: trunk/i386/libsaio/xml.h =================================================================== --- trunk/i386/libsaio/xml.h (revision 795) +++ trunk/i386/libsaio/xml.h (revision 796) @@ -25,7 +25,7 @@ #ifndef __LIBSAIO_XML_H #define __LIBSAIO_XML_H -enum { +enum xmltype { kTagTypeNone = 0, kTagTypeDict, kTagTypeKey, @@ -38,6 +38,17 @@ kTagTypeArray }; + +struct string_ref +{ + char* string; + int id; + struct string_ref* next; +}; +typedef struct string_ref string_ref; + +extern string_ref* ref_strings; + #define kXMLTagPList "plist " #define kXMLTagDict "dict" #define kXMLTagKey "key" @@ -49,7 +60,10 @@ #define kXMLTagTrue "true/" #define kXMLTagArray "array" +#define kXMLStringID "ID=" +#define kXMLStringIDRef "IDREF=" + #define kPropCFBundleIdentifier ("CFBundleIdentifier") #define kPropCFBundleExecutable ("CFBundleExecutable") #define kPropOSBundleRequired ("OSBundleRequired") @@ -71,6 +85,18 @@ extern long gImageLastKernelAddr; TagPtr XMLGetProperty( TagPtr dict, const char * key ); +TagPtr XMLGetElement( TagPtr dict, int id ); +int XMLTagCount( TagPtr dict ); + +bool XMLIsType(TagPtr dict, enum xmltype type); + +bool XMLCastBoolean( TagPtr dict ); +char* XMLCastString( TagPtr dict ); +long XMLCastStringOffset(TagPtr dict); +int XMLCastInteger ( TagPtr dict ); +TagPtr XMLCastDict ( TagPtr dict ); +TagPtr XMLCastArray( TagPtr dict ); + long XMLParseNextTag(char *buffer, TagPtr *tag); void XMLFreeTag(TagPtr tag); char* XMLDecode(const char *in); Index: trunk/i386/libsaio/saio_types.h =================================================================== --- trunk/i386/libsaio/saio_types.h (revision 795) +++ trunk/i386/libsaio/saio_types.h (revision 796) @@ -56,6 +56,7 @@ struct Tag { long type; char *string; + long offset; struct Tag *tag; struct Tag *tagNext; }; Index: trunk/i386/boot2/drivers.c =================================================================== --- trunk/i386/boot2/drivers.c (revision 795) +++ trunk/i386/boot2/drivers.c (revision 796) @@ -70,7 +70,7 @@ unsigned long signature1; unsigned long signature2; unsigned long length; - unsigned long alder32; + unsigned long adler32; unsigned long version; unsigned long numDrivers; unsigned long reserved1; @@ -85,7 +85,7 @@ long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p); -static unsigned long Alder32( unsigned char * buffer, long length ); +/*static*/ unsigned long Adler32( unsigned char * buffer, long length ); static long FileLoadDrivers(char *dirSpec, long plugin); static long NetLoadDrivers(char *dirSpec); @@ -109,8 +109,8 @@ static char * gTempSpec; static char * gFileName; -static unsigned long -Alder32( unsigned char * buffer, long length ) +/*static*/ unsigned long +Adler32( unsigned char * buffer, long length ) { long cnt; unsigned long result, lowHalf, highHalf; @@ -397,8 +397,8 @@ if (( GetPackageElement(signature1) != kDriverPackageSignature1) || ( GetPackageElement(signature2) != kDriverPackageSignature2) || ( GetPackageElement(length) > kLoadSize ) || - ( GetPackageElement(alder32) != - Alder32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) ) + ( GetPackageElement(adler32) != + Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) ) { return -1; } @@ -798,7 +798,7 @@ return -1; } if (OSSwapBigToHostInt32(kernel_header->adler32) != - Alder32(binary, uncompressed_size)) { + Adler32(binary, uncompressed_size)) { printf("adler mismatch\n"); return -1; }