1050aa61bSIngo Weinhold /* 2050aa61bSIngo Weinhold * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3050aa61bSIngo Weinhold * Distributed under the terms of the MIT License. 4050aa61bSIngo Weinhold */ 5050aa61bSIngo Weinhold 6050aa61bSIngo Weinhold 7050aa61bSIngo Weinhold #include <ctype.h> 8050aa61bSIngo Weinhold #include <errno.h> 9050aa61bSIngo Weinhold #include <getopt.h> 10050aa61bSIngo Weinhold #include <stdio.h> 11050aa61bSIngo Weinhold #include <stdlib.h> 12050aa61bSIngo Weinhold #include <string.h> 13050aa61bSIngo Weinhold 14*5fb1c6ffSOliver Tappe #include <package/hpkg/HPKGDefs.h> 15*5fb1c6ffSOliver Tappe #include <package/hpkg/PackageAttributeValue.h> 16*5fb1c6ffSOliver Tappe #include <package/hpkg/PackageContentHandler.h> 170d6b3b20SOliver Tappe #include <package/hpkg/PackageEntry.h> 180d6b3b20SOliver Tappe #include <package/hpkg/PackageEntryAttribute.h> 190d6b3b20SOliver Tappe #include <package/hpkg/PackageReader.h> 200d6b3b20SOliver Tappe 21050aa61bSIngo Weinhold #include "package.h" 226dccfe13SIngo Weinhold #include "StandardErrorOutput.h" 23050aa61bSIngo Weinhold 24050aa61bSIngo Weinhold 25*5fb1c6ffSOliver Tappe using namespace BPackageKit::BHPKG; 260d6b3b20SOliver Tappe 270d6b3b20SOliver Tappe 28*5fb1c6ffSOliver Tappe struct PackageContentDumpHandler : BLowLevelPackageContentHandler { 29050aa61bSIngo Weinhold PackageContentDumpHandler() 30050aa61bSIngo Weinhold : 31050aa61bSIngo Weinhold fLevel(0), 32050aa61bSIngo Weinhold fErrorOccurred(false), 33050aa61bSIngo Weinhold fHasChildren(false) 34050aa61bSIngo Weinhold { 35050aa61bSIngo Weinhold } 36050aa61bSIngo Weinhold 37050aa61bSIngo Weinhold virtual status_t HandleAttribute(const char* attributeName, 38*5fb1c6ffSOliver Tappe const BPackageAttributeValue& value, void* parentToken, void*& _token) 39050aa61bSIngo Weinhold { 40050aa61bSIngo Weinhold if (fErrorOccurred) 41050aa61bSIngo Weinhold return B_OK; 42050aa61bSIngo Weinhold 43050aa61bSIngo Weinhold printf("%*s>%s: ", fLevel * 2, "", attributeName); 44050aa61bSIngo Weinhold _PrintValue(value); 45050aa61bSIngo Weinhold printf("\n"); 46050aa61bSIngo Weinhold 47050aa61bSIngo Weinhold fHasChildren = false; 48050aa61bSIngo Weinhold fLevel++; 49050aa61bSIngo Weinhold return B_OK; 50050aa61bSIngo Weinhold } 51050aa61bSIngo Weinhold 52050aa61bSIngo Weinhold virtual status_t HandleAttributeDone(const char* attributeName, 53*5fb1c6ffSOliver Tappe const BPackageAttributeValue& value, void* token) 54050aa61bSIngo Weinhold { 55050aa61bSIngo Weinhold if (fErrorOccurred) 56050aa61bSIngo Weinhold return B_OK; 57050aa61bSIngo Weinhold 58050aa61bSIngo Weinhold fLevel--; 59050aa61bSIngo Weinhold 60050aa61bSIngo Weinhold if (fHasChildren) 61050aa61bSIngo Weinhold printf("%*s<%s\n", fLevel * 2, "", attributeName); 62050aa61bSIngo Weinhold 63050aa61bSIngo Weinhold fHasChildren = true; 64050aa61bSIngo Weinhold return B_OK; 65050aa61bSIngo Weinhold } 66050aa61bSIngo Weinhold 67050aa61bSIngo Weinhold virtual void HandleErrorOccurred() 68050aa61bSIngo Weinhold { 69050aa61bSIngo Weinhold fErrorOccurred = true; 70050aa61bSIngo Weinhold } 71050aa61bSIngo Weinhold 72050aa61bSIngo Weinhold private: 73*5fb1c6ffSOliver Tappe void _PrintValue(const BPackageAttributeValue& value) 74050aa61bSIngo Weinhold { 75050aa61bSIngo Weinhold switch (value.type) { 76050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_INT: 77050aa61bSIngo Weinhold printf("%lld (%#llx)", value.signedInt, value.signedInt); 78050aa61bSIngo Weinhold break; 79050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_UINT: 80050aa61bSIngo Weinhold printf("%llu (%#llx)", value.unsignedInt, value.unsignedInt); 81050aa61bSIngo Weinhold break; 82050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_STRING: 83050aa61bSIngo Weinhold printf("\"%s\"", value.string); 84050aa61bSIngo Weinhold break; 85050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_RAW: 86050aa61bSIngo Weinhold switch (value.encoding) { 87050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE: 88050aa61bSIngo Weinhold printf("data: size: %llu, inline", value.data.size); 89050aa61bSIngo Weinhold // TODO: Print the data bytes! 90050aa61bSIngo Weinhold break; 91050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP: 92050aa61bSIngo Weinhold printf("data: size: %llu, offset: %llu", 93050aa61bSIngo Weinhold value.data.size, value.data.offset); 94050aa61bSIngo Weinhold break; 95050aa61bSIngo Weinhold default: 96050aa61bSIngo Weinhold break; 97050aa61bSIngo Weinhold } 98050aa61bSIngo Weinhold break; 99050aa61bSIngo Weinhold default: 100050aa61bSIngo Weinhold printf("<unknown type %u>\n", value.type); 101050aa61bSIngo Weinhold break; 102050aa61bSIngo Weinhold } 103050aa61bSIngo Weinhold } 104050aa61bSIngo Weinhold 105050aa61bSIngo Weinhold private: 106050aa61bSIngo Weinhold int fLevel; 107050aa61bSIngo Weinhold bool fErrorOccurred; 108050aa61bSIngo Weinhold bool fHasChildren; 109050aa61bSIngo Weinhold }; 110050aa61bSIngo Weinhold 111050aa61bSIngo Weinhold 112050aa61bSIngo Weinhold int 113050aa61bSIngo Weinhold command_dump(int argc, const char* const* argv) 114050aa61bSIngo Weinhold { 115050aa61bSIngo Weinhold while (true) { 116050aa61bSIngo Weinhold static struct option sLongOptions[] = { 117050aa61bSIngo Weinhold { "help", no_argument, 0, 'h' }, 118050aa61bSIngo Weinhold { 0, 0, 0, 0 } 119050aa61bSIngo Weinhold }; 120050aa61bSIngo Weinhold 121050aa61bSIngo Weinhold opterr = 0; // don't print errors 122050aa61bSIngo Weinhold int c = getopt_long(argc, (char**)argv, "+h", sLongOptions, NULL); 123050aa61bSIngo Weinhold if (c == -1) 124050aa61bSIngo Weinhold break; 125050aa61bSIngo Weinhold 126050aa61bSIngo Weinhold switch (c) { 127050aa61bSIngo Weinhold case 'h': 128050aa61bSIngo Weinhold print_usage_and_exit(false); 129050aa61bSIngo Weinhold break; 130050aa61bSIngo Weinhold 131050aa61bSIngo Weinhold default: 132050aa61bSIngo Weinhold print_usage_and_exit(true); 133050aa61bSIngo Weinhold break; 134050aa61bSIngo Weinhold } 135050aa61bSIngo Weinhold } 136050aa61bSIngo Weinhold 137050aa61bSIngo Weinhold // One argument should remain -- the package file name. 138050aa61bSIngo Weinhold if (optind + 1 != argc) 139050aa61bSIngo Weinhold print_usage_and_exit(true); 140050aa61bSIngo Weinhold 141050aa61bSIngo Weinhold const char* packageFileName = argv[optind++]; 142050aa61bSIngo Weinhold 143050aa61bSIngo Weinhold // open package 1446dccfe13SIngo Weinhold StandardErrorOutput errorOutput; 145*5fb1c6ffSOliver Tappe BPackageReader packageReader(&errorOutput); 146050aa61bSIngo Weinhold status_t error = packageReader.Init(packageFileName); 147050aa61bSIngo Weinhold printf("Init(): %s\n", strerror(error)); 148050aa61bSIngo Weinhold if (error != B_OK) 149050aa61bSIngo Weinhold return 1; 150050aa61bSIngo Weinhold 151050aa61bSIngo Weinhold // list 152050aa61bSIngo Weinhold PackageContentDumpHandler handler; 153050aa61bSIngo Weinhold error = packageReader.ParseContent(&handler); 154050aa61bSIngo Weinhold printf("ParseContent(): %s\n", strerror(error)); 155050aa61bSIngo Weinhold if (error != B_OK) 156050aa61bSIngo Weinhold return 1; 157050aa61bSIngo Weinhold 158050aa61bSIngo Weinhold return 0; 159050aa61bSIngo Weinhold } 160