1/*
2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <ctype.h>
8#include <errno.h>
9#include <getopt.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#include <package/hpkg/PackageInfoAttributeValue.h>
15#include <package/hpkg/RepositoryContentHandler.h>
16#include <package/hpkg/RepositoryReader.h>
17#include <package/hpkg/StandardErrorOutput.h>
18#include <package/PackageInfo.h>
19#include <package/RepositoryInfo.h>
20
21#include "package_repo.h"
22#include "PackageInfoPrinter.h"
23
24
25using namespace BPackageKit::BHPKG;
26using namespace BPackageKit;
27
28struct RepositoryContentListHandler : BRepositoryContentHandler {
29	RepositoryContentListHandler(bool verbose)
30		:
31		fPrinter(),
32		fLevel(0),
33		fVerbose(verbose)
34	{
35	}
36
37	virtual status_t HandlePackage(const char* packageName)
38	{
39		return B_OK;
40	}
41
42	virtual status_t HandlePackageAttribute(
43		const BPackageInfoAttributeValue& value)
44	{
45		if (value.attributeID == B_PACKAGE_INFO_NAME) {
46			if (fVerbose) {
47				printf("package-attributes:\n");
48				fPrinter.PrintName(value.string);
49			} else
50				printf("\t%s\n", value.string);
51		} else {
52			if (fVerbose && !fPrinter.PrintAttribute(value)) {
53				printf("*** Invalid package attribute section: unexpected "
54					"package attribute id %d encountered\n", value.attributeID);
55				return B_BAD_DATA;
56			}
57		}
58
59		return B_OK;
60	}
61
62	virtual status_t HandlePackageDone(const char* packageName)
63	{
64		return B_OK;
65	}
66
67	virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo)
68	{
69		printf("repository-info:\n");
70		printf("\tname: %s\n", repositoryInfo.Name().String());
71		printf("\tsummary: %s\n", repositoryInfo.Summary().String());
72		printf("\tbase-url: %s\n", repositoryInfo.BaseURL().String());
73		printf("\tidentifier: %s\n", repositoryInfo.Identifier().String());
74		printf("\tvendor: %s\n", repositoryInfo.Vendor().String());
75		printf("\tpriority: %u\n", repositoryInfo.Priority());
76		printf("\tarchitecture: %s\n",
77			BPackageInfo::kArchitectureNames[repositoryInfo.Architecture()]);
78		const BStringList licenseNames = repositoryInfo.LicenseNames();
79		if (!licenseNames.IsEmpty()) {
80			printf("\tlicenses:\n");
81			for (int i = 0; i < licenseNames.CountStrings(); ++i)
82				printf("\t\t%s\n", licenseNames.StringAt(i).String());
83		}
84		printf("packages:\n");
85
86		return B_OK;
87	}
88
89	virtual void HandleErrorOccurred()
90	{
91	}
92
93private:
94	static void _PrintPackageVersion(const BPackageVersionData& version)
95	{
96		printf("%s", BPackageVersion(version).ToString().String());
97	}
98
99private:
100	PackageInfoPrinter	fPrinter;
101	int					fLevel;
102	bool				fVerbose;
103};
104
105
106int
107command_list(int argc, const char* const* argv)
108{
109	bool verbose = false;
110
111	while (true) {
112		static struct option sLongOptions[] = {
113			{ "help", no_argument, 0, 'h' },
114			{ "verbose", no_argument, 0, 'v' },
115			{ 0, 0, 0, 0 }
116		};
117
118		opterr = 0; // don't print errors
119		int c = getopt_long(argc, (char**)argv, "+hv", sLongOptions, NULL);
120		if (c == -1)
121			break;
122
123		switch (c) {
124			case 'h':
125				print_usage_and_exit(false);
126				break;
127
128			case 'v':
129				verbose = true;
130				break;
131
132			default:
133				print_usage_and_exit(true);
134				break;
135		}
136	}
137
138	// One argument should remain -- the repository file name.
139	if (optind + 1 != argc)
140		print_usage_and_exit(true);
141
142	const char* repositoryFileName = argv[optind++];
143
144	// open repository
145	BStandardErrorOutput errorOutput;
146	BRepositoryReader repositoryReader(&errorOutput);
147	status_t error = repositoryReader.Init(repositoryFileName);
148	if (error != B_OK)
149		return 1;
150
151	// list
152	RepositoryContentListHandler handler(verbose);
153	error = repositoryReader.ParseContent(&handler);
154	if (error != B_OK)
155		return 1;
156
157	return 0;
158}
159