1050aa61bSIngo Weinhold /*
2*1f633814SIngo Weinhold * Copyright 2009-2013, 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
145fb1c6ffSOliver Tappe #include <package/hpkg/HPKGDefs.h>
155fb1c6ffSOliver Tappe #include <package/hpkg/PackageAttributeValue.h>
165fb1c6ffSOliver 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>
200816749eSIngo Weinhold #include <package/hpkg/StandardErrorOutput.h>
210d6b3b20SOliver Tappe
22050aa61bSIngo Weinhold #include "package.h"
23050aa61bSIngo Weinhold
24050aa61bSIngo Weinhold
255fb1c6ffSOliver Tappe using namespace BPackageKit::BHPKG;
260d6b3b20SOliver Tappe
270d6b3b20SOliver Tappe
285fb1c6ffSOliver Tappe struct PackageContentDumpHandler : BLowLevelPackageContentHandler {
PackageContentDumpHandlerPackageContentDumpHandler29050aa61bSIngo Weinhold PackageContentDumpHandler()
30050aa61bSIngo Weinhold :
31050aa61bSIngo Weinhold fLevel(0),
32050aa61bSIngo Weinhold fErrorOccurred(false),
33050aa61bSIngo Weinhold fHasChildren(false)
34050aa61bSIngo Weinhold {
35050aa61bSIngo Weinhold }
36050aa61bSIngo Weinhold
HandleSectionStartPackageContentDumpHandler3797aabbedSIngo Weinhold virtual status_t HandleSectionStart(BHPKGPackageSectionID sectionID,
3897aabbedSIngo Weinhold bool& _handleSection)
3997aabbedSIngo Weinhold {
4097aabbedSIngo Weinhold const char* sectionName;
4197aabbedSIngo Weinhold
4297aabbedSIngo Weinhold switch (sectionID) {
4397aabbedSIngo Weinhold case B_HPKG_SECTION_HEADER:
4497aabbedSIngo Weinhold sectionName = "header";
4597aabbedSIngo Weinhold break;
4697aabbedSIngo Weinhold case B_HPKG_SECTION_HEAP:
4797aabbedSIngo Weinhold sectionName = "heap";
4897aabbedSIngo Weinhold break;
4997aabbedSIngo Weinhold case B_HPKG_SECTION_PACKAGE_TOC:
5097aabbedSIngo Weinhold sectionName = "TOC";
5197aabbedSIngo Weinhold break;
5297aabbedSIngo Weinhold case B_HPKG_SECTION_PACKAGE_ATTRIBUTES:
5397aabbedSIngo Weinhold sectionName = "package attributes";
5497aabbedSIngo Weinhold break;
5597aabbedSIngo Weinhold case B_HPKG_SECTION_REPOSITORY_INFO:
5697aabbedSIngo Weinhold sectionName = "repository info";
5797aabbedSIngo Weinhold break;
5897aabbedSIngo Weinhold default:
5997aabbedSIngo Weinhold sectionName = "<unknown section>";
6097aabbedSIngo Weinhold break;
6197aabbedSIngo Weinhold }
6297aabbedSIngo Weinhold
6397aabbedSIngo Weinhold printf("\n==== SECTION: %s ====\n", sectionName);
6497aabbedSIngo Weinhold
6597aabbedSIngo Weinhold _handleSection = true;
6697aabbedSIngo Weinhold return B_OK;
6797aabbedSIngo Weinhold }
6897aabbedSIngo Weinhold
HandleSectionEndPackageContentDumpHandler6997aabbedSIngo Weinhold virtual status_t HandleSectionEnd(BHPKGPackageSectionID sectionID)
7097aabbedSIngo Weinhold {
7197aabbedSIngo Weinhold return B_OK;
7297aabbedSIngo Weinhold }
7397aabbedSIngo Weinhold
HandleAttributePackageContentDumpHandler7433bc4425SOliver Tappe virtual status_t HandleAttribute(BHPKGAttributeID attributeID,
755fb1c6ffSOliver Tappe const BPackageAttributeValue& value, void* parentToken, void*& _token)
76050aa61bSIngo Weinhold {
77050aa61bSIngo Weinhold if (fErrorOccurred)
78050aa61bSIngo Weinhold return B_OK;
79050aa61bSIngo Weinhold
8033bc4425SOliver Tappe printf("%*s>%s: ", fLevel * 2, "", AttributeNameForID(attributeID));
81050aa61bSIngo Weinhold _PrintValue(value);
82050aa61bSIngo Weinhold printf("\n");
83050aa61bSIngo Weinhold
84050aa61bSIngo Weinhold fHasChildren = false;
85050aa61bSIngo Weinhold fLevel++;
86050aa61bSIngo Weinhold return B_OK;
87050aa61bSIngo Weinhold }
88050aa61bSIngo Weinhold
HandleAttributeDonePackageContentDumpHandler8933bc4425SOliver Tappe virtual status_t HandleAttributeDone(BHPKGAttributeID attributeID,
90697b9545SIngo Weinhold const BPackageAttributeValue& value, void* parentToken, void* token)
91050aa61bSIngo Weinhold {
92050aa61bSIngo Weinhold if (fErrorOccurred)
93050aa61bSIngo Weinhold return B_OK;
94050aa61bSIngo Weinhold
95050aa61bSIngo Weinhold fLevel--;
96050aa61bSIngo Weinhold
97050aa61bSIngo Weinhold if (fHasChildren)
9833bc4425SOliver Tappe printf("%*s<%s\n", fLevel * 2, "", AttributeNameForID(attributeID));
99050aa61bSIngo Weinhold
100050aa61bSIngo Weinhold fHasChildren = true;
101050aa61bSIngo Weinhold return B_OK;
102050aa61bSIngo Weinhold }
103050aa61bSIngo Weinhold
HandleErrorOccurredPackageContentDumpHandler104050aa61bSIngo Weinhold virtual void HandleErrorOccurred()
105050aa61bSIngo Weinhold {
106050aa61bSIngo Weinhold fErrorOccurred = true;
107050aa61bSIngo Weinhold }
108050aa61bSIngo Weinhold
109050aa61bSIngo Weinhold private:
_PrintValuePackageContentDumpHandler1105fb1c6ffSOliver Tappe void _PrintValue(const BPackageAttributeValue& value)
111050aa61bSIngo Weinhold {
112050aa61bSIngo Weinhold switch (value.type) {
113050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_INT:
11442ae6444SIngo Weinhold printf("%lld (%#llx)", (long long)value.signedInt,
11542ae6444SIngo Weinhold (long long)value.signedInt);
116050aa61bSIngo Weinhold break;
117050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_UINT:
11842ae6444SIngo Weinhold printf("%llu (%#llx)", (unsigned long long)value.unsignedInt,
11942ae6444SIngo Weinhold (unsigned long long)value.unsignedInt);
120050aa61bSIngo Weinhold break;
121050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_STRING:
122050aa61bSIngo Weinhold printf("\"%s\"", value.string);
123050aa61bSIngo Weinhold break;
124050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_TYPE_RAW:
125050aa61bSIngo Weinhold switch (value.encoding) {
126050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_ENCODING_RAW_INLINE:
12742ae6444SIngo Weinhold printf("data: size: %llu, inline",
12842ae6444SIngo Weinhold (unsigned long long)value.data.size);
129050aa61bSIngo Weinhold // TODO: Print the data bytes!
130050aa61bSIngo Weinhold break;
131050aa61bSIngo Weinhold case B_HPKG_ATTRIBUTE_ENCODING_RAW_HEAP:
132050aa61bSIngo Weinhold printf("data: size: %llu, offset: %llu",
13342ae6444SIngo Weinhold (unsigned long long)value.data.size,
13442ae6444SIngo Weinhold (unsigned long long)value.data.offset);
135050aa61bSIngo Weinhold break;
136050aa61bSIngo Weinhold default:
137050aa61bSIngo Weinhold break;
138050aa61bSIngo Weinhold }
139050aa61bSIngo Weinhold break;
140050aa61bSIngo Weinhold default:
141050aa61bSIngo Weinhold printf("<unknown type %u>\n", value.type);
142050aa61bSIngo Weinhold break;
143050aa61bSIngo Weinhold }
144050aa61bSIngo Weinhold }
145050aa61bSIngo Weinhold
146050aa61bSIngo Weinhold private:
147050aa61bSIngo Weinhold int fLevel;
148050aa61bSIngo Weinhold bool fErrorOccurred;
149050aa61bSIngo Weinhold bool fHasChildren;
150050aa61bSIngo Weinhold };
151050aa61bSIngo Weinhold
152050aa61bSIngo Weinhold
153050aa61bSIngo Weinhold int
command_dump(int argc,const char * const * argv)154050aa61bSIngo Weinhold command_dump(int argc, const char* const* argv)
155050aa61bSIngo Weinhold {
156050aa61bSIngo Weinhold while (true) {
157050aa61bSIngo Weinhold static struct option sLongOptions[] = {
158050aa61bSIngo Weinhold { "help", no_argument, 0, 'h' },
159050aa61bSIngo Weinhold { 0, 0, 0, 0 }
160050aa61bSIngo Weinhold };
161050aa61bSIngo Weinhold
162050aa61bSIngo Weinhold opterr = 0; // don't print errors
163050aa61bSIngo Weinhold int c = getopt_long(argc, (char**)argv, "+h", sLongOptions, NULL);
164050aa61bSIngo Weinhold if (c == -1)
165050aa61bSIngo Weinhold break;
166050aa61bSIngo Weinhold
167050aa61bSIngo Weinhold switch (c) {
168050aa61bSIngo Weinhold case 'h':
169050aa61bSIngo Weinhold print_usage_and_exit(false);
170050aa61bSIngo Weinhold break;
171050aa61bSIngo Weinhold
172050aa61bSIngo Weinhold default:
173050aa61bSIngo Weinhold print_usage_and_exit(true);
174050aa61bSIngo Weinhold break;
175050aa61bSIngo Weinhold }
176050aa61bSIngo Weinhold }
177050aa61bSIngo Weinhold
178050aa61bSIngo Weinhold // One argument should remain -- the package file name.
179050aa61bSIngo Weinhold if (optind + 1 != argc)
180050aa61bSIngo Weinhold print_usage_and_exit(true);
181050aa61bSIngo Weinhold
182050aa61bSIngo Weinhold const char* packageFileName = argv[optind++];
183050aa61bSIngo Weinhold
184050aa61bSIngo Weinhold // open package
1850816749eSIngo Weinhold BStandardErrorOutput errorOutput;
1865fb1c6ffSOliver Tappe BPackageReader packageReader(&errorOutput);
187050aa61bSIngo Weinhold status_t error = packageReader.Init(packageFileName);
188050aa61bSIngo Weinhold if (error != B_OK)
189050aa61bSIngo Weinhold return 1;
190050aa61bSIngo Weinhold
191050aa61bSIngo Weinhold // list
192050aa61bSIngo Weinhold PackageContentDumpHandler handler;
193050aa61bSIngo Weinhold error = packageReader.ParseContent(&handler);
194050aa61bSIngo Weinhold if (error != B_OK)
195050aa61bSIngo Weinhold return 1;
196050aa61bSIngo Weinhold
197050aa61bSIngo Weinhold return 0;
198050aa61bSIngo Weinhold }
199