xref: /haiku/src/bin/pkgman/command_list_repos.cpp (revision 500bb6305c339017d7d7302dc1f63ac90443f267)
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