1/*
2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de>
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "pkgman.h"
8
9#include <errno.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#include <package/manager/Exceptions.h>
15
16#include "Command.h"
17
18
19using namespace BPackageKit::BManager::BPrivate;
20
21
22extern const char* __progname;
23const char* kProgramName = __progname;
24
25
26static const char* const kUsage =
27	"Usage: %s <command> <command args>\n"
28	"Manages packages and package repositories.\n"
29	"\n"
30	"Package management commands:\n"
31	"%s"
32	"Repository management commands:\n"
33	"%s"
34	"Other commands:\n"
35	"%s"
36	"Common options:\n"
37	"  -h, --help   - Print usage info for a specific command.\n"
38;
39
40
41static BString
42get_commands_usage_for_category(const char* category)
43{
44	BString commandsUsage;
45	CommandList commands;
46	CommandManager::Default()->GetCommandsForCategory(category, commands);
47	for (int32 i = 0; Command* command = commands.ItemAt(i); i++)
48		commandsUsage << command->ShortUsage() << '\n';
49	return commandsUsage;
50}
51
52
53void
54print_usage_and_exit(bool error)
55{
56	BString packageCommandsUsage
57		= get_commands_usage_for_category(COMMAND_CATEGORY_PACKAGES);
58	BString repositoryCommandsUsage
59		= get_commands_usage_for_category(COMMAND_CATEGORY_REPOSITORIES);
60	BString otherCommandsUsage
61		= get_commands_usage_for_category(COMMAND_CATEGORY_OTHER);
62
63    fprintf(error ? stderr : stdout, kUsage, kProgramName,
64    	packageCommandsUsage.String(), repositoryCommandsUsage.String(),
65    	otherCommandsUsage.String());
66
67    exit(error ? 1 : 0);
68}
69
70
71int
72main(int argc, const char* const* argv)
73{
74	CommandManager::Default()->InitCommands(kProgramName);
75
76	if (argc < 2)
77		print_usage_and_exit(true);
78
79	const char* command = argv[1];
80	if (strcmp(command, "help") == 0)
81		print_usage_and_exit(false);
82
83	CommandList commands;
84	CommandManager::Default()->GetCommands(command, commands);
85	if (commands.CountItems() != 1)
86		print_usage_and_exit(true);
87
88	try {
89		return commands.ItemAt(0)->Execute(argc - 1, argv + 1);
90	} catch (BNothingToDoException&) {
91		fprintf(stderr, "Nothing to do.\n");
92		return 0;
93	} catch (std::bad_alloc&) {
94		fprintf(stderr, "Out of memory!\n");
95		return 1;
96	} catch (BFatalErrorException& exception) {
97		if (!exception.Details().IsEmpty())
98			fprintf(stderr, "%s", exception.Details().String());
99		if (exception.Error() == B_OK) {
100			fprintf(stderr, "*** %s\n", exception.Message().String());
101		} else {
102			fprintf(stderr, "*** %s: %s\n", exception.Message().String(),
103				strerror(exception.Error()));
104		}
105		return 1;
106	} catch (BAbortedByUserException&) {
107		return 0;
108	}
109}
110