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_PROVIDES: 119 if (!fVerbose) 120 break; 121 printf("\tprovides: %s", value.resolvable.name); 122 if (value.resolvable.haveVersion) { 123 printf(" = "); 124 _PrintPackageVersion(value.resolvable.version); 125 } 126 printf("\n"); 127 break; 128 129 case B_PACKAGE_INFO_REQUIRES: 130 if (!fVerbose) 131 break; 132 printf("\trequires: %s", value.resolvableExpression.name); 133 if (value.resolvableExpression.haveOpAndVersion) { 134 printf(" %s ", BPackageResolvableExpression::kOperatorNames[ 135 value.resolvableExpression.op]); 136 _PrintPackageVersion(value.resolvableExpression.version); 137 } 138 printf("\n"); 139 break; 140 141 case B_PACKAGE_INFO_SUPPLEMENTS: 142 if (!fVerbose) 143 break; 144 printf("\tsupplements: %s", value.resolvableExpression.name); 145 if (value.resolvableExpression.haveOpAndVersion) { 146 printf(" %s ", BPackageResolvableExpression::kOperatorNames[ 147 value.resolvableExpression.op]); 148 _PrintPackageVersion(value.resolvableExpression.version); 149 } 150 printf("\n"); 151 break; 152 153 case B_PACKAGE_INFO_CONFLICTS: 154 if (!fVerbose) 155 break; 156 printf("\tconflicts: %s", value.resolvableExpression.name); 157 if (value.resolvableExpression.haveOpAndVersion) { 158 printf(" %s ", BPackageResolvableExpression::kOperatorNames[ 159 value.resolvableExpression.op]); 160 _PrintPackageVersion(value.resolvableExpression.version); 161 } 162 printf("\n"); 163 break; 164 165 case B_PACKAGE_INFO_FRESHENS: 166 if (!fVerbose) 167 break; 168 printf("\tfreshens: %s", value.resolvableExpression.name); 169 if (value.resolvableExpression.haveOpAndVersion) { 170 printf(" %s ", BPackageResolvableExpression::kOperatorNames[ 171 value.resolvableExpression.op]); 172 _PrintPackageVersion(value.resolvableExpression.version); 173 } 174 printf("\n"); 175 break; 176 177 case B_PACKAGE_INFO_REPLACES: 178 if (!fVerbose) 179 break; 180 printf("\treplaces: %s\n", value.string); 181 break; 182 183 case B_PACKAGE_INFO_CHECKSUM: 184 printf("\tchecksum: %s\n", value.string); 185 break; 186 187 default: 188 printf( 189 "*** Invalid package attribute section: unexpected " 190 "package attribute id %d encountered\n", value.attributeID); 191 return B_BAD_DATA; 192 } 193 194 return B_OK; 195 } 196 197 virtual status_t HandleRepositoryInfo(const BRepositoryInfo& repositoryInfo) 198 { 199 printf("repository-info:\n"); 200 printf("\tname: %s\n", repositoryInfo.Name().String()); 201 printf("\tsummary: %s\n", repositoryInfo.Summary().String()); 202 printf("\turl: %s\n", repositoryInfo.OriginalBaseURL().String()); 203 printf("\tvendor: %s\n", repositoryInfo.Vendor().String()); 204 printf("\tpriority: %u\n", repositoryInfo.Priority()); 205 printf("\tarchitecture: %s\n", 206 BPackageInfo::kArchitectureNames[repositoryInfo.Architecture()]); 207 const BObjectList<BString> licenseNames = repositoryInfo.LicenseNames(); 208 if (!licenseNames.IsEmpty()) { 209 printf("\tlicenses:\n"); 210 for (int i = 0; i < licenseNames.CountItems(); ++i) 211 printf("\t\t%s\n", licenseNames.ItemAt(i)->String()); 212 } 213 214 return B_OK; 215 } 216 217 virtual void HandleErrorOccurred() 218 { 219 } 220 221 private: 222 static void _PrintPackageVersion(const BPackageVersionData& version) 223 { 224 printf("%s", version.major); 225 if (version.minor != NULL && version.minor[0] != '\0') 226 printf(".%s", version.minor); 227 if (version.micro != NULL && version.micro[0] != '\0') 228 printf(".%s", version.micro); 229 if (version.release > 0) 230 printf("-%d", version.release); 231 } 232 233 private: 234 int fLevel; 235 bool fVerbose; 236 }; 237 238 239 int 240 command_list(int argc, const char* const* argv) 241 { 242 bool verbose = false; 243 244 while (true) { 245 static struct option sLongOptions[] = { 246 { "help", no_argument, 0, 'h' }, 247 { "verbose", no_argument, 0, 'v' }, 248 { 0, 0, 0, 0 } 249 }; 250 251 opterr = 0; // don't print errors 252 int c = getopt_long(argc, (char**)argv, "+hv", sLongOptions, NULL); 253 if (c == -1) 254 break; 255 256 switch (c) { 257 case 'h': 258 print_usage_and_exit(false); 259 break; 260 261 case 'v': 262 verbose = true; 263 break; 264 265 default: 266 print_usage_and_exit(true); 267 break; 268 } 269 } 270 271 // One argument should remain -- the repository file name. 272 if (optind + 1 != argc) 273 print_usage_and_exit(true); 274 275 const char* repositoryFileName = argv[optind++]; 276 277 // open repository 278 StandardErrorOutput errorOutput; 279 BRepositoryReader repositoryReader(&errorOutput); 280 status_t error = repositoryReader.Init(repositoryFileName); 281 if (error != B_OK) 282 return 1; 283 284 // list 285 RepositoryContentListHandler handler(verbose); 286 error = repositoryReader.ParseContent(&handler); 287 if (error != B_OK) 288 return 1; 289 290 return 0; 291 } 292