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 {
RepositoryContentListHandlerRepositoryContentListHandler30 RepositoryContentListHandler(bool filenames, bool verbose)
31 :
32 fPrinter(),
33 fLevel(0),
34 fVerbose(verbose),
35 fFilenames(filenames),
36 fPackageInfoContentHandler(fPackageInfo, NULL)
37 {
38 }
39
HandlePackageRepositoryContentListHandler40 virtual status_t HandlePackage(const char* packageName)
41 {
42 return B_OK;
43 }
44
HandlePackageAttributeRepositoryContentListHandler45 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
HandlePackageDoneRepositoryContentListHandler69 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
HandleRepositoryInfoRepositoryContentListHandler79 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
HandleErrorOccurredRepositoryContentListHandler101 virtual void HandleErrorOccurred()
102 {
103 }
104
105 private:
_PrintPackageVersionRepositoryContentListHandler106 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
command_list(int argc,const char * const * argv)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