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 { 30 RepositoryContentListHandler(bool filenames, bool verbose) 31 : 32 fPrinter(), 33 fLevel(0), 34 fVerbose(verbose), 35 fFilenames(filenames), 36 fPackageInfoContentHandler(fPackageInfo, NULL) 37 { 38 } 39 40 virtual status_t HandlePackage(const char* packageName) 41 { 42 return B_OK; 43 } 44 45 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 69 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 79 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 101 virtual void HandleErrorOccurred() 102 { 103 } 104 105 private: 106 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 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