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/PackageInfo.h> 18 #include <package/RepositoryInfo.h> 19 20 #include "package.h" 21 #include "StandardErrorOutput.h" 22 23 24 using namespace BPackageKit::BHPKG; 25 using namespace BPackageKit; 26 27 struct RepositoryContentListHandler : BRepositoryContentHandler { 28 RepositoryContentListHandler(bool verbose) 29 : 30 fLevel(0), 31 fVerbose(verbose) 32 { 33 } 34 35 virtual status_t HandleEntry(BPackageEntry* entry) 36 { 37 return B_OK; 38 } 39 40 virtual status_t HandleEntryAttribute(BPackageEntry* entry, 41 BPackageEntryAttribute* attribute) 42 { 43 return B_OK; 44 } 45 46 virtual status_t HandleEntryDone(BPackageEntry* entry) 47 { 48 return B_OK; 49 } 50 51 virtual status_t HandlePackageAttribute( 52 const BPackageInfoAttributeValue& value) 53 { 54 switch (value.attributeID) { 55 case B_PACKAGE_INFO_NAME: 56 if (fVerbose) { 57 printf("package-attributes:\n"); 58 printf("\tname: %s\n", value.string); 59 } else 60 printf("package: %s", value.string); 61 break; 62 63 case B_PACKAGE_INFO_SUMMARY: 64 if (fVerbose) 65 printf("\tsummary: %s\n", value.string); 66 break; 67 68 case B_PACKAGE_INFO_DESCRIPTION: 69 if (fVerbose) 70 printf("\tdescription: %s\n", value.string); 71 break; 72 73 case B_PACKAGE_INFO_VENDOR: 74 if (fVerbose) 75 printf("\tvendor: %s\n", value.string); 76 break; 77 78 case B_PACKAGE_INFO_PACKAGER: 79 if (fVerbose) 80 printf("\tpackager: %s\n", value.string); 81 break; 82 83 case B_PACKAGE_INFO_FLAGS: 84 if (value.unsignedInt == 0 || !fVerbose) 85 break; 86 printf("\tflags:\n"); 87 if ((value.unsignedInt & B_PACKAGE_FLAG_APPROVE_LICENSE) != 0) 88 printf("\t\tapprove_license\n"); 89 if ((value.unsignedInt & B_PACKAGE_FLAG_SYSTEM_PACKAGE) != 0) 90 printf("\t\tsystem_package\n"); 91 break; 92 93 case B_PACKAGE_INFO_ARCHITECTURE: 94 if (fVerbose) { 95 printf("\tarchitecture: %s\n", 96 BPackageInfo::kArchitectureNames[value.unsignedInt]); 97 } 98 break; 99 100 case B_PACKAGE_INFO_VERSION: 101 if (!fVerbose) 102 printf("("); 103 _PrintPackageVersion(value.version); 104 if (!fVerbose) 105 printf(")\n"); 106 break; 107 108 case B_PACKAGE_INFO_COPYRIGHTS: 109 if (fVerbose) 110 printf("\tcopyright: %s\n", value.string); 111 break; 112 113 case B_PACKAGE_INFO_LICENSES: 114 if (fVerbose) 115 printf("\tlicense: %s\n", value.string); 116 break; 117 118 case B_PACKAGE_INFO_URLS: 119 if (fVerbose) 120 printf("\tURL: %s\n", value.string); 121 break; 122 123 case B_PACKAGE_INFO_SOURCE_URLS: 124 if (fVerbose) 125 printf("\tsource URL: %s\n", value.string); 126 break; 127 128 case B_PACKAGE_INFO_PROVIDES: 129 if (!fVerbose) 130 break; 131 printf("\tprovides: %s", value.resolvable.name); 132 if (value.resolvable.haveVersion) { 133 printf(" = "); 134 _PrintPackageVersion(value.resolvable.version); 135 } 136 printf("\n"); 137 break; 138 139 case B_PACKAGE_INFO_REQUIRES: 140 if (!fVerbose) 141 break; 142 printf("\trequires: %s", value.resolvableExpression.name); 143 if (value.resolvableExpression.haveOpAndVersion) { 144 printf(" %s ", BPackageResolvableExpression::kOperatorNames[ 145 value.resolvableExpression.op]); 146 _PrintPackageVersion(value.resolvableExpression.version); 147 } 148 printf("\n"); 149 break; 150 151 case B_PACKAGE_INFO_SUPPLEMENTS: 152 if (!fVerbose) 153 break; 154 printf("\tsupplements: %s", value.resolvableExpression.name); 155 if (value.resolvableExpression.haveOpAndVersion) { 156 printf(" %s ", BPackageResolvableExpression::kOperatorNames[ 157 value.resolvableExpression.op]); 158 _PrintPackageVersion(value.resolvableExpression.version); 159 } 160 printf("\n"); 161 break; 162 163 case B_PACKAGE_INFO_CONFLICTS: 164 if (!fVerbose) 165 break; 166 printf("\tconflicts: %s", value.resolvableExpression.name); 167 if (value.resolvableExpression.haveOpAndVersion) { 168 printf(" %s ", BPackageResolvableExpression::kOperatorNames[ 169 value.resolvableExpression.op]); 170 _PrintPackageVersion(value.resolvableExpression.version); 171 } 172 printf("\n"); 173 break; 174 175 case B_PACKAGE_INFO_FRESHENS: 176 if (!fVerbose) 177 break; 178 printf("\tfreshens: %s", value.resolvableExpression.name); 179 if (value.resolvableExpression.haveOpAndVersion) { 180 printf(" %s ", BPackageResolvableExpression::kOperatorNames[ 181 value.resolvableExpression.op]); 182 _PrintPackageVersion(value.resolvableExpression.version); 183 } 184 printf("\n"); 185 break; 186 187 case B_PACKAGE_INFO_REPLACES: 188 if (!fVerbose) 189 break; 190 printf("\treplaces: %s\n", value.string); 191 break; 192 193 case B_PACKAGE_INFO_CHECKSUM: 194 printf("\tchecksum: %s\n", value.string); 195 break; 196 197 default: 198 printf( 199 "*** Invalid package attribute section: unexpected " 200 "package attribute id %d encountered\n", value.attributeID); 201 return B_BAD_DATA; 202 } 203 204 return B_OK; 205 } 206 207 virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo) 208 { 209 printf("repository-info:\n"); 210 printf("\tname: %s\n", repositoryInfo.Name().String()); 211 printf("\tsummary: %s\n", repositoryInfo.Summary().String()); 212 printf("\turl: %s\n", repositoryInfo.OriginalBaseURL().String()); 213 printf("\tvendor: %s\n", repositoryInfo.Vendor().String()); 214 printf("\tpriority: %u\n", repositoryInfo.Priority()); 215 printf("\tarchitecture: %s\n", 216 BPackageInfo::kArchitectureNames[repositoryInfo.Architecture()]); 217 const BStringList licenseNames = repositoryInfo.LicenseNames(); 218 if (!licenseNames.IsEmpty()) { 219 printf("\tlicenses:\n"); 220 for (int i = 0; i < licenseNames.CountStrings(); ++i) 221 printf("\t\t%s\n", licenseNames.StringAt(i).String()); 222 } 223 224 return B_OK; 225 } 226 227 virtual void HandleErrorOccurred() 228 { 229 } 230 231 private: 232 static void _PrintPackageVersion(const BPackageVersionData& version) 233 { 234 printf("%s", version.major); 235 if (version.minor != NULL && version.minor[0] != '\0') 236 printf(".%s", version.minor); 237 if (version.micro != NULL && version.micro[0] != '\0') 238 printf(".%s", version.micro); 239 if (version.preRelease != NULL && version.preRelease[0] != '\0') 240 printf("-%s", version.preRelease); 241 if (version.release > 0) 242 printf("-%d", version.release); 243 } 244 245 private: 246 int fLevel; 247 bool fVerbose; 248 }; 249 250 251 int 252 command_list(int argc, const char* const* argv) 253 { 254 bool verbose = false; 255 256 while (true) { 257 static struct option sLongOptions[] = { 258 { "help", no_argument, 0, 'h' }, 259 { "verbose", no_argument, 0, 'v' }, 260 { 0, 0, 0, 0 } 261 }; 262 263 opterr = 0; // don't print errors 264 int c = getopt_long(argc, (char**)argv, "+hv", sLongOptions, NULL); 265 if (c == -1) 266 break; 267 268 switch (c) { 269 case 'h': 270 print_usage_and_exit(false); 271 break; 272 273 case 'v': 274 verbose = true; 275 break; 276 277 default: 278 print_usage_and_exit(true); 279 break; 280 } 281 } 282 283 // One argument should remain -- the repository file name. 284 if (optind + 1 != argc) 285 print_usage_and_exit(true); 286 287 const char* repositoryFileName = argv[optind++]; 288 289 // open repository 290 StandardErrorOutput errorOutput; 291 BRepositoryReader repositoryReader(&errorOutput); 292 status_t error = repositoryReader.Init(repositoryFileName); 293 if (error != B_OK) 294 return 1; 295 296 // list 297 RepositoryContentListHandler handler(verbose); 298 error = repositoryReader.ParseContent(&handler); 299 if (error != B_OK) 300 return 1; 301 302 return 0; 303 } 304