1050aa61bSIngo Weinhold/*
29172ffdbSIngo 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>
135eedc380SIngo Weinhold#include <time.h>
14050aa61bSIngo Weinhold
154ce282c7SIngo Weinhold#include <Entry.h>
165fb1c6ffSOliver Tappe#include <package/hpkg/PackageContentHandler.h>
170d6b3b20SOliver Tappe#include <package/hpkg/PackageEntry.h>
180d6b3b20SOliver Tappe#include <package/hpkg/PackageEntryAttribute.h>
196f0278cdSOliver Tappe#include <package/hpkg/PackageInfoAttributeValue.h>
200d6b3b20SOliver Tappe#include <package/hpkg/PackageReader.h>
210816749eSIngo Weinhold#include <package/hpkg/StandardErrorOutput.h>
229172ffdbSIngo Weinhold#include <package/hpkg/v1/PackageContentHandler.h>
239172ffdbSIngo Weinhold#include <package/hpkg/v1/PackageEntry.h>
249172ffdbSIngo Weinhold#include <package/hpkg/v1/PackageEntryAttribute.h>
259172ffdbSIngo Weinhold#include <package/hpkg/v1//PackageReader.h>
260d6b3b20SOliver Tappe
276f0278cdSOliver Tappe#include <package/PackageInfo.h>
286f0278cdSOliver Tappe
29050aa61bSIngo Weinhold#include "package.h"
30ed156ea6SIngo Weinhold#include "PackageInfoPrinter.h"
31050aa61bSIngo Weinhold
32050aa61bSIngo Weinhold
336f0278cdSOliver Tappeusing namespace BPackageKit;
341f633814SIngo Weinholdusing BPackageKit::BHPKG::BErrorOutput;
359172ffdbSIngo Weinholdusing BPackageKit::BHPKG::BPackageInfoAttributeValue;
361f633814SIngo Weinholdusing BPackageKit::BHPKG::BStandardErrorOutput;
370d6b3b20SOliver Tappe
380d6b3b20SOliver Tappe
399172ffdbSIngo Weinholdstruct VersionPolicyV1 {
409172ffdbSIngo Weinhold	typedef BPackageKit::BHPKG::V1::BPackageContentHandler
419172ffdbSIngo Weinhold		PackageContentHandler;
429172ffdbSIngo Weinhold	typedef BPackageKit::BHPKG::V1::BPackageEntry PackageEntry;
439172ffdbSIngo Weinhold	typedef BPackageKit::BHPKG::V1::BPackageEntryAttribute
449172ffdbSIngo Weinhold		PackageEntryAttribute;
459172ffdbSIngo Weinhold	typedef BPackageKit::BHPKG::V1::BPackageReader PackageReader;
461f633814SIngo Weinhold
471f633814SIngo Weinhold	static inline uint64 PackageDataSize(
481f633814SIngo Weinhold		const BPackageKit::BHPKG::V1::BPackageData& data)
491f633814SIngo Weinhold	{
501f633814SIngo Weinhold		return data.UncompressedSize();
511f633814SIngo Weinhold	}
52d59e0febSIngo Weinhold
53d59e0febSIngo Weinhold	static inline status_t InitReader(PackageReader& packageReader,
54d59e0febSIngo Weinhold		const char* fileName)
55d59e0febSIngo Weinhold	{
56d59e0febSIngo Weinhold		return packageReader.Init(fileName);
57d59e0febSIngo Weinhold	}
589172ffdbSIngo Weinhold};
599172ffdbSIngo Weinhold
609172ffdbSIngo Weinholdstruct VersionPolicyV2 {
619172ffdbSIngo Weinhold	typedef BPackageKit::BHPKG::BPackageContentHandler PackageContentHandler;
629172ffdbSIngo Weinhold	typedef BPackageKit::BHPKG::BPackageEntry PackageEntry;
639172ffdbSIngo Weinhold	typedef BPackageKit::BHPKG::BPackageEntryAttribute PackageEntryAttribute;
649172ffdbSIngo Weinhold	typedef BPackageKit::BHPKG::BPackageReader PackageReader;
651f633814SIngo Weinhold
661f633814SIngo Weinhold	static inline uint64 PackageDataSize(
671f633814SIngo Weinhold		const BPackageKit::BHPKG::BPackageData& data)
681f633814SIngo Weinhold	{
691f633814SIngo Weinhold		return data.Size();
701f633814SIngo Weinhold	}
71d59e0febSIngo Weinhold
72d59e0febSIngo Weinhold	static inline status_t InitReader(PackageReader& packageReader,
73d59e0febSIngo Weinhold		const char* fileName)
74d59e0febSIngo Weinhold	{
75d59e0febSIngo Weinhold		return packageReader.Init(fileName,
76d59e0febSIngo Weinhold			BPackageKit::BHPKG
77d59e0febSIngo Weinhold				::B_HPKG_READER_DONT_PRINT_VERSION_MISMATCH_MESSAGE);
78d59e0febSIngo Weinhold	}
799172ffdbSIngo Weinhold};
809172ffdbSIngo Weinhold
819172ffdbSIngo Weinhold
824e6141b8SIngo Weinholdenum ListMode {
834e6141b8SIngo Weinhold	LIST_ALL,
844e6141b8SIngo Weinhold	LIST_PATHS_ONLY,
854e6141b8SIngo Weinhold	LIST_META_INFO_ONLY
864e6141b8SIngo Weinhold};
874e6141b8SIngo Weinhold
884e6141b8SIngo Weinhold
899172ffdbSIngo Weinholdtemplate<typename VersionPolicy>
909172ffdbSIngo Weinholdstruct PackageContentListHandler : VersionPolicy::PackageContentHandler {
914e6141b8SIngo Weinhold	PackageContentListHandler(bool listEntries, bool listAttributes)
92050aa61bSIngo Weinhold		:
93ed156ea6SIngo Weinhold		fPrinter(),
94050aa61bSIngo Weinhold		fLevel(0),
954e6141b8SIngo Weinhold		fListEntries(listEntries),
964e6141b8SIngo Weinhold		fListAttribute(listEntries && listAttributes)
97050aa61bSIngo Weinhold	{
98050aa61bSIngo Weinhold	}
99050aa61bSIngo Weinhold
1009172ffdbSIngo Weinhold	virtual status_t HandleEntry(typename VersionPolicy::PackageEntry* entry)
101050aa61bSIngo Weinhold	{
1024e6141b8SIngo Weinhold		if (!fListEntries)
1034e6141b8SIngo Weinhold			return B_OK;
1044e6141b8SIngo Weinhold
105050aa61bSIngo Weinhold		fLevel++;
106050aa61bSIngo Weinhold
107050aa61bSIngo Weinhold		int indentation = (fLevel - 1) * 2;
108050aa61bSIngo Weinhold		printf("%*s", indentation, "");
109050aa61bSIngo Weinhold
110050aa61bSIngo Weinhold		// name and size
111050aa61bSIngo Weinhold		printf("%-*s", indentation < 32 ? 32 - indentation : 0, entry->Name());
1121f633814SIngo Weinhold		printf("  %8llu",
1131f633814SIngo Weinhold			(unsigned long long)VersionPolicy::PackageDataSize(entry->Data()));
114050aa61bSIngo Weinhold
115050aa61bSIngo Weinhold		// time
116050aa61bSIngo Weinhold		struct tm* time = localtime(&entry->ModifiedTime().tv_sec);
117050aa61bSIngo Weinhold		printf("  %04d-%02d-%02d %02d:%02d:%02d",
118050aa61bSIngo Weinhold			1900 + time->tm_year, time->tm_mon + 1, time->tm_mday,
119050aa61bSIngo Weinhold			time->tm_hour, time->tm_min, time->tm_sec);
120050aa61bSIngo Weinhold
121050aa61bSIngo Weinhold		// file type
122050aa61bSIngo Weinhold		mode_t mode = entry->Mode();
123050aa61bSIngo Weinhold		if (S_ISREG(mode))
124050aa61bSIngo Weinhold			printf("  -");
125050aa61bSIngo Weinhold		else if (S_ISDIR(mode))
126050aa61bSIngo Weinhold			printf("  d");
127050aa61bSIngo Weinhold		else if (S_ISLNK(mode))
128050aa61bSIngo Weinhold			printf("  l");
129050aa61bSIngo Weinhold		else
130050aa61bSIngo Weinhold			printf("  ?");
131050aa61bSIngo Weinhold
132050aa61bSIngo Weinhold		// permissions
133050aa61bSIngo Weinhold		char buffer[4];
134050aa61bSIngo Weinhold		printf("%s", _PermissionString(buffer, mode >> 6,
135050aa61bSIngo Weinhold			(mode & S_ISUID) != 0));
136050aa61bSIngo Weinhold		printf("%s", _PermissionString(buffer, mode >> 3,
137050aa61bSIngo Weinhold			(mode & S_ISGID) != 0));
138050aa61bSIngo Weinhold		printf("%s", _PermissionString(buffer, mode, false));
139050aa61bSIngo Weinhold
140050aa61bSIngo Weinhold		// print the symlink path
141050aa61bSIngo Weinhold		if (S_ISLNK(mode))
142050aa61bSIngo Weinhold			printf("  -> %s", entry->SymlinkPath());
143050aa61bSIngo Weinhold
144050aa61bSIngo Weinhold		printf("\n");
145050aa61bSIngo Weinhold		return B_OK;
146050aa61bSIngo Weinhold	}
147050aa61bSIngo Weinhold
1489172ffdbSIngo Weinhold	virtual status_t HandleEntryAttribute(
1499172ffdbSIngo Weinhold		typename VersionPolicy::PackageEntry* entry,
1509172ffdbSIngo Weinhold		typename VersionPolicy::PackageEntryAttribute* attribute)
151050aa61bSIngo Weinhold	{
152050aa61bSIngo Weinhold		if (!fListAttribute)
153050aa61bSIngo Weinhold			return B_OK;
154050aa61bSIngo Weinhold
155050aa61bSIngo Weinhold		int indentation = fLevel * 2;
156050aa61bSIngo Weinhold		printf("%*s<", indentation, "");
157050aa61bSIngo Weinhold		printf("%-*s  %8llu", indentation < 31 ? 31 - indentation : 0,
15842ae6444SIngo Weinhold			attribute->Name(),
1591f633814SIngo Weinhold			(unsigned long long)VersionPolicy::PackageDataSize(
1601f633814SIngo Weinhold				attribute->Data()));
161050aa61bSIngo Weinhold
162050aa61bSIngo Weinhold		uint32 type = attribute->Type();
163050aa61bSIngo Weinhold		if (isprint(type & 0xff) && isprint((type >> 8) & 0xff)
164050aa61bSIngo Weinhold			 && isprint((type >> 16) & 0xff) && isprint(type >> 24)) {
165050aa61bSIngo Weinhold			printf("  '%c%c%c%c'", int(type >> 24), int((type >> 16) & 0xff),
166050aa61bSIngo Weinhold				int((type >> 8) & 0xff), int(type & 0xff));
167050aa61bSIngo Weinhold		} else
1685eedc380SIngo Weinhold			printf("  %#" B_PRIx32, type);
169050aa61bSIngo Weinhold
170050aa61bSIngo Weinhold		printf(">\n");
171050aa61bSIngo Weinhold		return B_OK;
172050aa61bSIngo Weinhold	}
173050aa61bSIngo Weinhold
1749172ffdbSIngo Weinhold	virtual status_t HandleEntryDone(
1759172ffdbSIngo Weinhold		typename VersionPolicy::PackageEntry* entry)
176050aa61bSIngo Weinhold	{
1774e6141b8SIngo Weinhold		if (!fListEntries)
1784e6141b8SIngo Weinhold			return B_OK;
1794e6141b8SIngo Weinhold
180050aa61bSIngo Weinhold		fLevel--;
181050aa61bSIngo Weinhold		return B_OK;
182050aa61bSIngo Weinhold	}
183050aa61bSIngo Weinhold
1846f0278cdSOliver Tappe	virtual status_t HandlePackageAttribute(
1856f0278cdSOliver Tappe		const BPackageInfoAttributeValue& value)
1866f0278cdSOliver Tappe	{
187ed156ea6SIngo Weinhold		if (value.attributeID == B_PACKAGE_INFO_NAME)
188ed156ea6SIngo Weinhold			printf("package-attributes:\n");
189ed156ea6SIngo Weinhold
190ed156ea6SIngo Weinhold		if (!fPrinter.PrintAttribute(value)) {
191ed156ea6SIngo Weinhold			printf("*** Invalid package attribute section: unexpected "
192ed156ea6SIngo Weinhold				"package attribute id %d encountered\n", value.attributeID);
193ed156ea6SIngo Weinhold			return B_BAD_DATA;
1946f0278cdSOliver Tappe		}
1956f0278cdSOliver Tappe
1966f0278cdSOliver Tappe		return B_OK;
1976f0278cdSOliver Tappe	}
1986f0278cdSOliver Tappe
199050aa61bSIngo Weinhold	virtual void HandleErrorOccurred()
200050aa61bSIngo Weinhold	{
201050aa61bSIngo Weinhold	}
202050aa61bSIngo Weinhold
203050aa61bSIngo Weinholdprivate:
204050aa61bSIngo Weinhold	static const char* _PermissionString(char* buffer, uint32 mode, bool sticky)
205050aa61bSIngo Weinhold	{
206050aa61bSIngo Weinhold		buffer[0] = (mode & 0x4) != 0 ? 'r' : '-';
207050aa61bSIngo Weinhold		buffer[1] = (mode & 0x2) != 0 ? 'w' : '-';
208050aa61bSIngo Weinhold
209050aa61bSIngo Weinhold		if ((mode & 0x1) != 0)
210050aa61bSIngo Weinhold			buffer[2] = sticky ? 's' : 'x';
211050aa61bSIngo Weinhold		else
212050aa61bSIngo Weinhold			buffer[2] = '-';
213050aa61bSIngo Weinhold
214050aa61bSIngo Weinhold		buffer[3] = '\0';
215050aa61bSIngo Weinhold		return buffer;
216050aa61bSIngo Weinhold	}
217050aa61bSIngo Weinhold
2186f0278cdSOliver Tappe	static void _PrintPackageVersion(const BPackageVersionData& version)
2196f0278cdSOliver Tappe	{
220b50e5e33SIngo Weinhold		printf("%s", BPackageVersion(version).ToString().String());
2216f0278cdSOliver Tappe	}
2226f0278cdSOliver Tappe
223050aa61bSIngo Weinholdprivate:
224ed156ea6SIngo Weinhold	PackageInfoPrinter	fPrinter;
225ed156ea6SIngo Weinhold	int					fLevel;
2264e6141b8SIngo Weinhold	bool				fListEntries;
227ed156ea6SIngo Weinhold	bool				fListAttribute;
228050aa61bSIngo Weinhold};
229050aa61bSIngo Weinhold
230050aa61bSIngo Weinhold
2319172ffdbSIngo Weinholdtemplate<typename VersionPolicy>
2329172ffdbSIngo Weinholdstruct PackageContentListPathsHandler : VersionPolicy::PackageContentHandler {
233330cb41eSIngo Weinhold	PackageContentListPathsHandler()
234330cb41eSIngo Weinhold		:
235330cb41eSIngo Weinhold		fPathComponents()
236330cb41eSIngo Weinhold	{
237330cb41eSIngo Weinhold	}
238330cb41eSIngo Weinhold
2399172ffdbSIngo Weinhold	virtual status_t HandleEntry(typename VersionPolicy::PackageEntry* entry)
240330cb41eSIngo Weinhold	{
241330cb41eSIngo Weinhold		fPathComponents.Add(entry->Name());
242330cb41eSIngo Weinhold		printf("%s\n", fPathComponents.Join("/").String());
243330cb41eSIngo Weinhold		return B_OK;
244330cb41eSIngo Weinhold	}
245330cb41eSIngo Weinhold
2469172ffdbSIngo Weinhold	virtual status_t HandleEntryAttribute(
2479172ffdbSIngo Weinhold		typename VersionPolicy::PackageEntry* entry,
2489172ffdbSIngo Weinhold		typename VersionPolicy::PackageEntryAttribute* attribute)
249330cb41eSIngo Weinhold	{
250330cb41eSIngo Weinhold		return B_OK;
251330cb41eSIngo Weinhold	}
252330cb41eSIngo Weinhold
2539172ffdbSIngo Weinhold	virtual status_t HandleEntryDone(
2549172ffdbSIngo Weinhold		typename VersionPolicy::PackageEntry* entry)
255330cb41eSIngo Weinhold	{
256330cb41eSIngo Weinhold		fPathComponents.Remove(fPathComponents.CountStrings() - 1);
257330cb41eSIngo Weinhold		return B_OK;
258330cb41eSIngo Weinhold	}
259330cb41eSIngo Weinhold
260330cb41eSIngo Weinhold	virtual status_t HandlePackageAttribute(
261330cb41eSIngo Weinhold		const BPackageInfoAttributeValue& value)
262330cb41eSIngo Weinhold	{
263330cb41eSIngo Weinhold		return B_OK;
264330cb41eSIngo Weinhold	}
265330cb41eSIngo Weinhold
266330cb41eSIngo Weinhold	virtual void HandleErrorOccurred()
267330cb41eSIngo Weinhold	{
268330cb41eSIngo Weinhold	}
269330cb41eSIngo Weinhold
270330cb41eSIngo Weinholdprivate:
271330cb41eSIngo Weinhold	BStringList	fPathComponents;
272330cb41eSIngo Weinhold};
273330cb41eSIngo Weinhold
274330cb41eSIngo Weinhold
2759172ffdbSIngo Weinholdtemplate<typename VersionPolicy>
2769172ffdbSIngo Weinholdstatic void
2774e6141b8SIngo Weinholddo_list(const char* packageFileName, bool listAttributes, ListMode listMode,
2789172ffdbSIngo Weinhold	bool ignoreVersionError)
2799172ffdbSIngo Weinhold{
2809172ffdbSIngo Weinhold	// open package
2811f633814SIngo Weinhold	BStandardErrorOutput errorOutput;
2829172ffdbSIngo Weinhold	typename VersionPolicy::PackageReader packageReader(&errorOutput);
283d59e0febSIngo Weinhold	status_t error = VersionPolicy::InitReader(packageReader, packageFileName);
2849172ffdbSIngo Weinhold	if (error != B_OK) {
2859172ffdbSIngo Weinhold		if (ignoreVersionError && error == B_MISMATCHED_VALUES)
2869172ffdbSIngo Weinhold			return;
2879172ffdbSIngo Weinhold		exit(1);
2889172ffdbSIngo Weinhold	}
2899172ffdbSIngo Weinhold
2909172ffdbSIngo Weinhold	// list
2914e6141b8SIngo Weinhold	switch (listMode) {
2924e6141b8SIngo Weinhold		case LIST_PATHS_ONLY:
2934e6141b8SIngo Weinhold		{
2944e6141b8SIngo Weinhold			PackageContentListPathsHandler<VersionPolicy> handler;
2954e6141b8SIngo Weinhold			error = packageReader.ParseContent(&handler);
2964e6141b8SIngo Weinhold			break;
2974e6141b8SIngo Weinhold		}
2984e6141b8SIngo Weinhold
2994e6141b8SIngo Weinhold		case LIST_ALL:
3004e6141b8SIngo Weinhold		case LIST_META_INFO_ONLY:
3014e6141b8SIngo Weinhold		{
3024e6141b8SIngo Weinhold			PackageContentListHandler<VersionPolicy> handler(
3034e6141b8SIngo Weinhold				listMode != LIST_META_INFO_ONLY, listAttributes);
3044e6141b8SIngo Weinhold			error = packageReader.ParseContent(&handler);
3054e6141b8SIngo Weinhold		}
3069172ffdbSIngo Weinhold	}
3074e6141b8SIngo Weinhold
3089172ffdbSIngo Weinhold	if (error != B_OK)
3099172ffdbSIngo Weinhold		exit(1);
3109172ffdbSIngo Weinhold
3119172ffdbSIngo Weinhold	exit(0);
3129172ffdbSIngo Weinhold}
3139172ffdbSIngo Weinhold
3149172ffdbSIngo Weinhold
315050aa61bSIngo Weinholdint
316050aa61bSIngo Weinholdcommand_list(int argc, const char* const* argv)
317050aa61bSIngo Weinhold{
3184e6141b8SIngo Weinhold	ListMode listMode = LIST_ALL;
319050aa61bSIngo Weinhold	bool listAttributes = false;
320050aa61bSIngo Weinhold
321050aa61bSIngo Weinhold	while (true) {
322050aa61bSIngo Weinhold		static struct option sLongOptions[] = {
323050aa61bSIngo Weinhold			{ "help", no_argument, 0, 'h' },
324050aa61bSIngo Weinhold			{ 0, 0, 0, 0 }
325050aa61bSIngo Weinhold		};
326050aa61bSIngo Weinhold
327050aa61bSIngo Weinhold		opterr = 0; // don't print errors
3284e6141b8SIngo Weinhold		int c = getopt_long(argc, (char**)argv, "+ahip", sLongOptions, NULL);
329050aa61bSIngo Weinhold		if (c == -1)
330050aa61bSIngo Weinhold			break;
331050aa61bSIngo Weinhold
332050aa61bSIngo Weinhold		switch (c) {
333050aa61bSIngo Weinhold			case 'a':
334050aa61bSIngo Weinhold				listAttributes = true;
335050aa61bSIngo Weinhold				break;
336050aa61bSIngo Weinhold
3374e6141b8SIngo Weinhold			case 'i':
3384e6141b8SIngo Weinhold				listMode = LIST_META_INFO_ONLY;
3394e6141b8SIngo Weinhold				break;
3404e6141b8SIngo Weinhold
341050aa61bSIngo Weinhold			case 'h':
342050aa61bSIngo Weinhold				print_usage_and_exit(false);
343050aa61bSIngo Weinhold				break;
344050aa61bSIngo Weinhold
345330cb41eSIngo Weinhold			case 'p':
3464e6141b8SIngo Weinhold				listMode = LIST_PATHS_ONLY;
347330cb41eSIngo Weinhold				break;
348330cb41eSIngo Weinhold
349050aa61bSIngo Weinhold			default:
350050aa61bSIngo Weinhold				print_usage_and_exit(true);
351050aa61bSIngo Weinhold				break;
352050aa61bSIngo Weinhold		}
353050aa61bSIngo Weinhold	}
354050aa61bSIngo Weinhold
355050aa61bSIngo Weinhold	// One argument should remain -- the package file name.
356050aa61bSIngo Weinhold	if (optind + 1 != argc)
357050aa61bSIngo Weinhold		print_usage_and_exit(true);
358050aa61bSIngo Weinhold
359050aa61bSIngo Weinhold	const char* packageFileName = argv[optind++];
360050aa61bSIngo Weinhold
3614ce282c7SIngo Weinhold	// If the file doesn't look like a package file, try to load it as a
3624ce282c7SIngo Weinhold	// package info file.
3634ce282c7SIngo Weinhold	if (!BString(packageFileName).EndsWith(".hpkg")) {
3644ce282c7SIngo Weinhold		struct ErrorListener : BPackageInfo::ParseErrorListener {
3654ce282c7SIngo Weinhold			virtual void OnError(const BString& msg, int line, int col)
3664ce282c7SIngo Weinhold			{
3674ce282c7SIngo Weinhold				fprintf(stderr, "%s:%d:%d: %s\n", fPath, line, col,
3684ce282c7SIngo Weinhold					msg.String());
3694ce282c7SIngo Weinhold			}
3704ce282c7SIngo Weinhold
3714ce282c7SIngo Weinhold			const char*	fPath;
3724ce282c7SIngo Weinhold		} errorListener;
3734ce282c7SIngo Weinhold		errorListener.fPath = packageFileName;
3744ce282c7SIngo Weinhold
3754ce282c7SIngo Weinhold		BPackageInfo info;
3764ce282c7SIngo Weinhold		if (info.ReadFromConfigFile(BEntry(packageFileName), &errorListener)
3774ce282c7SIngo Weinhold				!= B_OK) {
3784ce282c7SIngo Weinhold			return 1;
3794ce282c7SIngo Weinhold		}
3804ce282c7SIngo Weinhold
3814ce282c7SIngo Weinhold		printf("package-attributes:\n");
3824ce282c7SIngo Weinhold		PackageInfoPrinter().PrintPackageInfo(info);
3834ce282c7SIngo Weinhold		return 0;
3844ce282c7SIngo Weinhold	}
3854ce282c7SIngo Weinhold
3869172ffdbSIngo Weinhold	BHPKG::BStandardErrorOutput errorOutput;
387050aa61bSIngo Weinhold
3889172ffdbSIngo Weinhold	// current package file format version
3894e6141b8SIngo Weinhold	do_list<VersionPolicyV2>(packageFileName, listAttributes, listMode, true);
3904e6141b8SIngo Weinhold	do_list<VersionPolicyV1>(packageFileName, listAttributes, listMode, false);
391050aa61bSIngo Weinhold
392050aa61bSIngo Weinhold	return 0;
393050aa61bSIngo Weinhold}
394