xref: /haiku/src/bin/package_repo/command_list.cpp (revision 7bdeef54a24d3417300f251af891df962b638b9b)
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 
25 using namespace BPackageKit::BHPKG;
26 using namespace BPackageKit;
27 
28 struct 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("\tvendor: %s\n", repositoryInfo.Vendor().String());
73 		printf("\tpriority: %u\n", repositoryInfo.Priority());
74 		printf("\tarchitecture: %s\n",
75 			BPackageInfo::kArchitectureNames[repositoryInfo.Architecture()]);
76 		const BStringList licenseNames = repositoryInfo.LicenseNames();
77 		if (!licenseNames.IsEmpty()) {
78 			printf("\tlicenses:\n");
79 			for (int i = 0; i < licenseNames.CountStrings(); ++i)
80 				printf("\t\t%s\n", licenseNames.StringAt(i).String());
81 		}
82 		printf("packages:\n");
83 
84 		return B_OK;
85 	}
86 
87 	virtual void HandleErrorOccurred()
88 	{
89 	}
90 
91 private:
92 	static void _PrintPackageVersion(const BPackageVersionData& version)
93 	{
94 		printf("%s", BPackageVersion(version).ToString().String());
95 	}
96 
97 private:
98 	PackageInfoPrinter	fPrinter;
99 	int					fLevel;
100 	bool				fVerbose;
101 };
102 
103 
104 int
105 command_list(int argc, const char* const* argv)
106 {
107 	bool verbose = false;
108 
109 	while (true) {
110 		static struct option sLongOptions[] = {
111 			{ "help", no_argument, 0, 'h' },
112 			{ "verbose", no_argument, 0, 'v' },
113 			{ 0, 0, 0, 0 }
114 		};
115 
116 		opterr = 0; // don't print errors
117 		int c = getopt_long(argc, (char**)argv, "+hv", sLongOptions, NULL);
118 		if (c == -1)
119 			break;
120 
121 		switch (c) {
122 			case 'h':
123 				print_usage_and_exit(false);
124 				break;
125 
126 			case 'v':
127 				verbose = true;
128 				break;
129 
130 			default:
131 				print_usage_and_exit(true);
132 				break;
133 		}
134 	}
135 
136 	// One argument should remain -- the repository file name.
137 	if (optind + 1 != argc)
138 		print_usage_and_exit(true);
139 
140 	const char* repositoryFileName = argv[optind++];
141 
142 	// open repository
143 	BStandardErrorOutput errorOutput;
144 	BRepositoryReader repositoryReader(&errorOutput);
145 	status_t error = repositoryReader.Init(repositoryFileName);
146 	if (error != B_OK)
147 		return 1;
148 
149 	// list
150 	RepositoryContentListHandler handler(verbose);
151 	error = repositoryReader.ParseContent(&handler);
152 	if (error != B_OK)
153 		return 1;
154 
155 	return 0;
156 }
157