1*500bb630SOliver Tappe /* 2*500bb630SOliver Tappe * Copyright 2011, Oliver Tappe <zooey@hirschkaefere.de> 3*500bb630SOliver Tappe * Distributed under the terms of the MIT License. 4*500bb630SOliver Tappe */ 5*500bb630SOliver Tappe 6*500bb630SOliver Tappe 7*500bb630SOliver Tappe #include <getopt.h> 8*500bb630SOliver Tappe #include <stdio.h> 9*500bb630SOliver Tappe #include <stdlib.h> 10*500bb630SOliver Tappe 11*500bb630SOliver Tappe #include <new> 12*500bb630SOliver Tappe 13*500bb630SOliver Tappe #include <Entry.h> 14*500bb630SOliver Tappe #include <Errors.h> 15*500bb630SOliver Tappe #include <ObjectList.h> 16*500bb630SOliver Tappe #include <Path.h> 17*500bb630SOliver Tappe 18*500bb630SOliver Tappe #include <package/RepositoryConfig.h> 19*500bb630SOliver Tappe #include <package/Roster.h> 20*500bb630SOliver Tappe 21*500bb630SOliver Tappe #include "pkgman.h" 22*500bb630SOliver Tappe 23*500bb630SOliver Tappe 24*500bb630SOliver Tappe // TODO: internationalization! 25*500bb630SOliver Tappe 26*500bb630SOliver Tappe 27*500bb630SOliver Tappe using namespace Haiku::Package; 28*500bb630SOliver Tappe 29*500bb630SOliver Tappe 30*500bb630SOliver Tappe static const char* kCommandUsage = 31*500bb630SOliver Tappe "Usage:\n" 32*500bb630SOliver Tappe " %s list-repos [options]\n" 33*500bb630SOliver Tappe "Lists all configured package repositories.\n" 34*500bb630SOliver Tappe "\n" 35*500bb630SOliver Tappe ; 36*500bb630SOliver Tappe 37*500bb630SOliver Tappe 38*500bb630SOliver Tappe static void 39*500bb630SOliver Tappe print_command_usage_and_exit(bool error) 40*500bb630SOliver Tappe { 41*500bb630SOliver Tappe fprintf(error ? stderr : stdout, kCommandUsage, kProgramName); 42*500bb630SOliver Tappe exit(error ? 1 : 0); 43*500bb630SOliver Tappe } 44*500bb630SOliver Tappe 45*500bb630SOliver Tappe 46*500bb630SOliver Tappe typedef BObjectList<RepositoryConfig> RepositoryConfigList; 47*500bb630SOliver Tappe 48*500bb630SOliver Tappe 49*500bb630SOliver Tappe struct RepositoryConfigCollector : public RepositoryConfigVisitor { 50*500bb630SOliver Tappe RepositoryConfigCollector(RepositoryConfigList& _repositoryConfigList); 51*500bb630SOliver Tappe 52*500bb630SOliver Tappe status_t operator()(const BEntry& entry); 53*500bb630SOliver Tappe 54*500bb630SOliver Tappe RepositoryConfigList& repositoryConfigList; 55*500bb630SOliver Tappe }; 56*500bb630SOliver Tappe 57*500bb630SOliver Tappe 58*500bb630SOliver Tappe RepositoryConfigCollector::RepositoryConfigCollector( 59*500bb630SOliver Tappe RepositoryConfigList& _repositoryConfigList) 60*500bb630SOliver Tappe : 61*500bb630SOliver Tappe repositoryConfigList(_repositoryConfigList) 62*500bb630SOliver Tappe { 63*500bb630SOliver Tappe } 64*500bb630SOliver Tappe 65*500bb630SOliver Tappe 66*500bb630SOliver Tappe status_t 67*500bb630SOliver Tappe RepositoryConfigCollector::operator()(const BEntry& entry) 68*500bb630SOliver Tappe { 69*500bb630SOliver Tappe RepositoryConfig* repoConfig = new (std::nothrow) RepositoryConfig(entry); 70*500bb630SOliver Tappe if (repoConfig == NULL) 71*500bb630SOliver Tappe DIE(B_NO_MEMORY, "can't create repository-config object"); 72*500bb630SOliver Tappe 73*500bb630SOliver Tappe status_t result = repoConfig->InitCheck(); 74*500bb630SOliver Tappe if (result != B_OK) { 75*500bb630SOliver Tappe BPath path; 76*500bb630SOliver Tappe entry.GetPath(&path); 77*500bb630SOliver Tappe WARN(result, "skipping repository-config '%s'", path.Path()); 78*500bb630SOliver Tappe delete repoConfig; 79*500bb630SOliver Tappe 80*500bb630SOliver Tappe return B_OK; 81*500bb630SOliver Tappe // let collector continue 82*500bb630SOliver Tappe } 83*500bb630SOliver Tappe 84*500bb630SOliver Tappe return repositoryConfigList.AddItem(repoConfig) ? B_OK : B_NO_MEMORY; 85*500bb630SOliver Tappe } 86*500bb630SOliver Tappe 87*500bb630SOliver Tappe 88*500bb630SOliver Tappe int 89*500bb630SOliver Tappe command_list_repos(int argc, const char* const* argv) 90*500bb630SOliver Tappe { 91*500bb630SOliver Tappe bool verbose = false; 92*500bb630SOliver Tappe 93*500bb630SOliver Tappe while (true) { 94*500bb630SOliver Tappe static struct option sLongOptions[] = { 95*500bb630SOliver Tappe { "help", no_argument, 0, 'h' }, 96*500bb630SOliver Tappe { "verbose", no_argument, 0, 'v' }, 97*500bb630SOliver Tappe { 0, 0, 0, 0 } 98*500bb630SOliver Tappe }; 99*500bb630SOliver Tappe 100*500bb630SOliver Tappe opterr = 0; // don't print errors 101*500bb630SOliver Tappe int c = getopt_long(argc, (char**)argv, "hv", sLongOptions, NULL); 102*500bb630SOliver Tappe if (c == -1) 103*500bb630SOliver Tappe break; 104*500bb630SOliver Tappe 105*500bb630SOliver Tappe switch (c) { 106*500bb630SOliver Tappe case 'h': 107*500bb630SOliver Tappe print_command_usage_and_exit(false); 108*500bb630SOliver Tappe break; 109*500bb630SOliver Tappe 110*500bb630SOliver Tappe case 'v': 111*500bb630SOliver Tappe verbose = true; 112*500bb630SOliver Tappe break; 113*500bb630SOliver Tappe 114*500bb630SOliver Tappe default: 115*500bb630SOliver Tappe print_command_usage_and_exit(true); 116*500bb630SOliver Tappe break; 117*500bb630SOliver Tappe } 118*500bb630SOliver Tappe } 119*500bb630SOliver Tappe 120*500bb630SOliver Tappe // No remaining arguments. 121*500bb630SOliver Tappe if (argc != optind) 122*500bb630SOliver Tappe print_command_usage_and_exit(true); 123*500bb630SOliver Tappe 124*500bb630SOliver Tappe Roster roster; 125*500bb630SOliver Tappe RepositoryConfigList repositoryConfigs; 126*500bb630SOliver Tappe RepositoryConfigCollector repositoryConfigCollector(repositoryConfigs); 127*500bb630SOliver Tappe status_t result 128*500bb630SOliver Tappe = roster.VisitCommonRepositoryConfigs(repositoryConfigCollector); 129*500bb630SOliver Tappe if (result != B_OK && result != B_ENTRY_NOT_FOUND) 130*500bb630SOliver Tappe DIE(result, "can't collect common repository configs"); 131*500bb630SOliver Tappe 132*500bb630SOliver Tappe result = roster.VisitUserRepositoryConfigs(repositoryConfigCollector); 133*500bb630SOliver Tappe if (result != B_OK && result != B_ENTRY_NOT_FOUND) 134*500bb630SOliver Tappe DIE(result, "can't collect user's repository configs"); 135*500bb630SOliver Tappe 136*500bb630SOliver Tappe int32 count = repositoryConfigs.CountItems(); 137*500bb630SOliver Tappe for (int32 i = 0; i < count; ++i) { 138*500bb630SOliver Tappe RepositoryConfig* repoConfig = repositoryConfigs.ItemAt(i); 139*500bb630SOliver Tappe printf(" %s %s\n", 140*500bb630SOliver Tappe repoConfig->IsUserSpecific() ? "[User]" : " ", 141*500bb630SOliver Tappe repoConfig->Name().String()); 142*500bb630SOliver Tappe } 143*500bb630SOliver Tappe 144*500bb630SOliver Tappe return 0; 145*500bb630SOliver Tappe } 146