xref: /haiku/src/bin/package_repo/command_list.cpp (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
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/PackageInfoContentHandler.h>
20 #include <package/RepositoryInfo.h>
21 
22 #include "package_repo.h"
23 #include "PackageInfoPrinter.h"
24 
25 
26 using namespace BPackageKit::BHPKG;
27 using namespace BPackageKit;
28 
29 struct RepositoryContentListHandler : BRepositoryContentHandler {
30 	RepositoryContentListHandler(bool filenames, bool verbose)
31 		:
32 		fPrinter(),
33 		fLevel(0),
34 		fVerbose(verbose),
35 		fFilenames(filenames),
36 		fPackageInfoContentHandler(fPackageInfo, NULL)
37 	{
38 	}
39 
40 	virtual status_t HandlePackage(const char* packageName)
41 	{
42 		return B_OK;
43 	}
44 
45 	virtual status_t HandlePackageAttribute(
46 		const BPackageInfoAttributeValue& value)
47 	{
48 		if (fFilenames)
49 			fPackageInfoContentHandler.HandlePackageAttribute(value);
50 
51 		if (value.attributeID == B_PACKAGE_INFO_NAME) {
52 			if (fVerbose) {
53 				printf("package-attributes:\n");
54 				fPrinter.PrintName(value.string);
55 			} else if (!fFilenames) {
56 				printf("\t%s\n", value.string);
57 			}
58 		} else {
59 			if (fVerbose && !fPrinter.PrintAttribute(value)) {
60 				printf("*** Invalid package attribute section: unexpected "
61 					"package attribute id %d encountered\n", value.attributeID);
62 				return B_BAD_DATA;
63 			}
64 		}
65 
66 		return B_OK;
67 	}
68 
69 	virtual status_t HandlePackageDone(const char* packageName)
70 	{
71 		if (fFilenames) {
72 			printf("%s%s\n", fVerbose ? "filename: " : "\t",
73 				fPackageInfo.CanonicalFileName().String());
74 			fPackageInfo.Clear();
75 		}
76 		return B_OK;
77 	}
78 
79 	virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo)
80 	{
81 		printf("repository-info:\n");
82 		printf("\tname: %s\n", repositoryInfo.Name().String());
83 		printf("\tsummary: %s\n", repositoryInfo.Summary().String());
84 		printf("\tbase-url: %s\n", repositoryInfo.BaseURL().String());
85 		printf("\tidentifier: %s\n", repositoryInfo.Identifier().String());
86 		printf("\tvendor: %s\n", repositoryInfo.Vendor().String());
87 		printf("\tpriority: %u\n", repositoryInfo.Priority());
88 		printf("\tarchitecture: %s\n",
89 			BPackageInfo::kArchitectureNames[repositoryInfo.Architecture()]);
90 		const BStringList licenseNames = repositoryInfo.LicenseNames();
91 		if (!licenseNames.IsEmpty()) {
92 			printf("\tlicenses:\n");
93 			for (int i = 0; i < licenseNames.CountStrings(); ++i)
94 				printf("\t\t%s\n", licenseNames.StringAt(i).String());
95 		}
96 		printf("packages:\n");
97 
98 		return B_OK;
99 	}
100 
101 	virtual void HandleErrorOccurred()
102 	{
103 	}
104 
105 private:
106 	static void _PrintPackageVersion(const BPackageVersionData& version)
107 	{
108 		printf("%s", BPackageVersion(version).ToString().String());
109 	}
110 
111 private:
112 	PackageInfoPrinter	fPrinter;
113 	int					fLevel;
114 	bool				fVerbose;
115 
116 	bool				fFilenames;
117 	BPackageInfoContentHandler fPackageInfoContentHandler;
118 	BPackageInfo		fPackageInfo;
119 };
120 
121 
122 int
123 command_list(int argc, const char* const* argv)
124 {
125 	bool verbose = false, filenames = false;
126 
127 	while (true) {
128 		static struct option sLongOptions[] = {
129 			{ "help", no_argument, 0, 'h' },
130 			{ "filenames", no_argument, 0, 'f' },
131 			{ "verbose", no_argument, 0, 'v' },
132 			{ 0, 0, 0, 0 }
133 		};
134 
135 		opterr = 0; // don't print errors
136 		int c = getopt_long(argc, (char**)argv, "+hfv", sLongOptions, NULL);
137 		if (c == -1)
138 			break;
139 
140 		switch (c) {
141 			case 'h':
142 				print_usage_and_exit(false);
143 				break;
144 
145 			case 'f':
146 				filenames = true;
147 				break;
148 
149 			case 'v':
150 				verbose = true;
151 				break;
152 
153 			default:
154 				print_usage_and_exit(true);
155 				break;
156 		}
157 	}
158 
159 	// One argument should remain -- the repository file name.
160 	if (optind + 1 != argc)
161 		print_usage_and_exit(true);
162 
163 	const char* repositoryFileName = argv[optind++];
164 
165 	// open repository
166 	BStandardErrorOutput errorOutput;
167 	BRepositoryReader repositoryReader(&errorOutput);
168 	status_t error = repositoryReader.Init(repositoryFileName);
169 	if (error != B_OK)
170 		return 1;
171 
172 	// list
173 	RepositoryContentListHandler handler(filenames, verbose);
174 	error = repositoryReader.ParseContent(&handler);
175 	if (error != B_OK)
176 		return 1;
177 
178 	return 0;
179 }
180