xref: /haiku/src/bin/package/command_dump.cpp (revision 9f81ca838ce7b92b5689e57d3f86765db4705a7b)
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