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