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*0d6b3b20SOliver Tappe #include <package/hpkg/PackageEntry.h> 15*0d6b3b20SOliver Tappe #include <package/hpkg/PackageEntryAttribute.h> 16*0d6b3b20SOliver Tappe #include <package/hpkg/PackageReader.h> 17*0d6b3b20SOliver Tappe 18050aa61bSIngo Weinhold #include "package.h" 196dccfe13SIngo Weinhold #include "StandardErrorOutput.h" 20050aa61bSIngo Weinhold 21050aa61bSIngo Weinhold 22*0d6b3b20SOliver Tappe using namespace BPackageKit::BHaikuPackage::BPrivate; 23*0d6b3b20SOliver Tappe 24*0d6b3b20SOliver Tappe 25050aa61bSIngo Weinhold struct PackageContentDumpHandler : LowLevelPackageContentHandler { 26050aa61bSIngo Weinhold PackageContentDumpHandler() 27050aa61bSIngo Weinhold : 28050aa61bSIngo Weinhold fLevel(0), 29050aa61bSIngo Weinhold fErrorOccurred(false), 30050aa61bSIngo Weinhold fHasChildren(false) 31050aa61bSIngo Weinhold { 32050aa61bSIngo Weinhold } 33050aa61bSIngo Weinhold 34050aa61bSIngo Weinhold virtual status_t HandleAttribute(const char* attributeName, 35050aa61bSIngo Weinhold const PackageAttributeValue& value, void* parentToken, void*& _token) 36050aa61bSIngo Weinhold { 37050aa61bSIngo Weinhold if (fErrorOccurred) 38050aa61bSIngo Weinhold return B_OK; 39050aa61bSIngo Weinhold 40050aa61bSIngo Weinhold printf("%*s>%s: ", fLevel * 2, "", attributeName); 41050aa61bSIngo Weinhold _PrintValue(value); 42050aa61bSIngo Weinhold printf("\n"); 43050aa61bSIngo Weinhold 44050aa61bSIngo Weinhold fHasChildren = false; 45050aa61bSIngo Weinhold fLevel++; 46050aa61bSIngo Weinhold return B_OK; 47050aa61bSIngo Weinhold } 48050aa61bSIngo Weinhold 49050aa61bSIngo Weinhold virtual status_t HandleAttributeDone(const char* attributeName, 50050aa61bSIngo Weinhold const PackageAttributeValue& value, void* token) 51050aa61bSIngo Weinhold { 52050aa61bSIngo Weinhold if (fErrorOccurred) 53050aa61bSIngo Weinhold return B_OK; 54050aa61bSIngo Weinhold 55050aa61bSIngo Weinhold fLevel--; 56050aa61bSIngo Weinhold 57050aa61bSIngo Weinhold if (fHasChildren) 58050aa61bSIngo Weinhold printf("%*s<%s\n", fLevel * 2, "", attributeName); 59050aa61bSIngo Weinhold 60050aa61bSIngo Weinhold fHasChildren = true; 61050aa61bSIngo Weinhold return B_OK; 62050aa61bSIngo Weinhold } 63050aa61bSIngo Weinhold 64050aa61bSIngo Weinhold virtual void HandleErrorOccurred() 65050aa61bSIngo Weinhold { 66050aa61bSIngo Weinhold fErrorOccurred = true; 67050aa61bSIngo Weinhold } 68050aa61bSIngo Weinhold 69050aa61bSIngo Weinhold private: 70050aa61bSIngo Weinhold void _PrintValue(const PackageAttributeValue& value) 71050aa61bSIngo Weinhold { 72050aa61bSIngo Weinhold switch (value.type) { 73050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_INT: 74050aa61bSIngo Weinhold printf("%lld (%#llx)", value.signedInt, value.signedInt); 75050aa61bSIngo Weinhold break; 76050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_UINT: 77050aa61bSIngo Weinhold printf("%llu (%#llx)", value.unsignedInt, value.unsignedInt); 78050aa61bSIngo Weinhold break; 79050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_STRING: 80050aa61bSIngo Weinhold printf("\"%s\"", value.string); 81050aa61bSIngo Weinhold break; 82050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_RAW: 83050aa61bSIngo Weinhold switch (value.encoding) { 84050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE: 85050aa61bSIngo Weinhold printf("data: size: %llu, inline", value.data.size); 86050aa61bSIngo Weinhold // TODO: Print the data bytes! 87050aa61bSIngo Weinhold break; 88050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP: 89050aa61bSIngo Weinhold printf("data: size: %llu, offset: %llu", 90050aa61bSIngo Weinhold value.data.size, value.data.offset); 91050aa61bSIngo Weinhold break; 92050aa61bSIngo Weinhold default: 93050aa61bSIngo Weinhold break; 94050aa61bSIngo Weinhold } 95050aa61bSIngo Weinhold break; 96050aa61bSIngo Weinhold default: 97050aa61bSIngo Weinhold printf("<unknown type %u>\n", value.type); 98050aa61bSIngo Weinhold break; 99050aa61bSIngo Weinhold } 100050aa61bSIngo Weinhold } 101050aa61bSIngo Weinhold 102050aa61bSIngo Weinhold private: 103050aa61bSIngo Weinhold int fLevel; 104050aa61bSIngo Weinhold bool fErrorOccurred; 105050aa61bSIngo Weinhold bool fHasChildren; 106050aa61bSIngo Weinhold }; 107050aa61bSIngo Weinhold 108050aa61bSIngo Weinhold 109050aa61bSIngo Weinhold int 110050aa61bSIngo Weinhold command_dump(int argc, const char* const* argv) 111050aa61bSIngo Weinhold { 112050aa61bSIngo Weinhold while (true) { 113050aa61bSIngo Weinhold static struct option sLongOptions[] = { 114050aa61bSIngo Weinhold { "help", no_argument, 0, 'h' }, 115050aa61bSIngo Weinhold { 0, 0, 0, 0 } 116050aa61bSIngo Weinhold }; 117050aa61bSIngo Weinhold 118050aa61bSIngo Weinhold opterr = 0; // don't print errors 119050aa61bSIngo Weinhold int c = getopt_long(argc, (char**)argv, "+h", sLongOptions, NULL); 120050aa61bSIngo Weinhold if (c == -1) 121050aa61bSIngo Weinhold break; 122050aa61bSIngo Weinhold 123050aa61bSIngo Weinhold switch (c) { 124050aa61bSIngo Weinhold case 'h': 125050aa61bSIngo Weinhold print_usage_and_exit(false); 126050aa61bSIngo Weinhold break; 127050aa61bSIngo Weinhold 128050aa61bSIngo Weinhold default: 129050aa61bSIngo Weinhold print_usage_and_exit(true); 130050aa61bSIngo Weinhold break; 131050aa61bSIngo Weinhold } 132050aa61bSIngo Weinhold } 133050aa61bSIngo Weinhold 134050aa61bSIngo Weinhold // One argument should remain -- the package file name. 135050aa61bSIngo Weinhold if (optind + 1 != argc) 136050aa61bSIngo Weinhold print_usage_and_exit(true); 137050aa61bSIngo Weinhold 138050aa61bSIngo Weinhold const char* packageFileName = argv[optind++]; 139050aa61bSIngo Weinhold 140050aa61bSIngo Weinhold // open package 1416dccfe13SIngo Weinhold StandardErrorOutput errorOutput; 1426dccfe13SIngo Weinhold PackageReader packageReader(&errorOutput); 143050aa61bSIngo Weinhold status_t error = packageReader.Init(packageFileName); 144050aa61bSIngo Weinhold printf("Init(): %s\n", strerror(error)); 145050aa61bSIngo Weinhold if (error != B_OK) 146050aa61bSIngo Weinhold return 1; 147050aa61bSIngo Weinhold 148050aa61bSIngo Weinhold // list 149050aa61bSIngo Weinhold PackageContentDumpHandler handler; 150050aa61bSIngo Weinhold error = packageReader.ParseContent(&handler); 151050aa61bSIngo Weinhold printf("ParseContent(): %s\n", strerror(error)); 152050aa61bSIngo Weinhold if (error != B_OK) 153050aa61bSIngo Weinhold return 1; 154050aa61bSIngo Weinhold 155050aa61bSIngo Weinhold return 0; 156050aa61bSIngo Weinhold } 157