1/*
2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefere.de>
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include <getopt.h>
8#include <stdio.h>
9#include <stdlib.h>
10
11#include <Errors.h>
12#include <SupportDefs.h>
13#include <Url.h>
14
15#include <package/AddRepositoryRequest.h>
16#include <package/Context.h>
17#include <package/RefreshRepositoryRequest.h>
18#include <package/PackageRoster.h>
19
20#include "Command.h"
21#include "DecisionProvider.h"
22#include "JobStateListener.h"
23#include "pkgman.h"
24
25
26using namespace BPackageKit;
27
28
29// TODO: internationalization!
30
31
32static const char* const kShortUsage =
33	"  %command% <repo-base-url>\n"
34	"    Adds the repository with the given <repo-base-URL>.\n";
35
36static const char* const kLongUsage =
37	"Usage: %program% %command% <repo-URL> [<repo-URL> ...]\n"
38	"Adds one or more repositories by downloading them from the given URL(s).\n"
39	"\n";
40
41
42DEFINE_COMMAND(AddRepoCommand, "add-repo", kShortUsage, kLongUsage,
43	COMMAND_CATEGORY_REPOSITORIES)
44
45
46int
47AddRepoCommand::Execute(int argc, const char* const* argv)
48{
49	bool asUserRepository = false;
50
51	while (true) {
52		static struct option sLongOptions[] = {
53			{ "help", no_argument, 0, 'h' },
54			{ "user", no_argument, 0, 'u' },
55			{ 0, 0, 0, 0 }
56		};
57
58		opterr = 0; // don't print errors
59		int c = getopt_long(argc, (char**)argv, "hu", sLongOptions, NULL);
60		if (c == -1)
61			break;
62
63		switch (c) {
64			case 'h':
65				PrintUsageAndExit(false);
66				break;
67
68			case 'u':
69				asUserRepository = true;
70				break;
71
72			default:
73				PrintUsageAndExit(true);
74				break;
75		}
76	}
77
78	// The remaining arguments are repo URLs, i. e. at least one more argument.
79	if (argc < optind + 1)
80		PrintUsageAndExit(true);
81
82	const char* const* repoURLs = argv + optind;
83	int urlCount = argc - optind;
84
85	DecisionProvider decisionProvider;
86	JobStateListener listener;
87	BContext context(decisionProvider, listener);
88
89	status_t result;
90	for (int i = 0; i < urlCount; ++i) {
91		// Test if a valid URL has been supplied before attempting to add
92		BUrl repoURL(repoURLs[i]);
93		if (!repoURL.IsValid()) {
94			result = B_BAD_VALUE;
95			DIE(result, "request for adding repository \"%s\" failed",
96				repoURLs[i]);
97		}
98		AddRepositoryRequest addRequest(context, repoURLs[i], asUserRepository);
99		result = addRequest.Process(true);
100		if (result != B_OK) {
101			if (result != B_CANCELED) {
102				DIE(result, "request for adding repository \"%s\" failed",
103					repoURLs[i]);
104			}
105			return 1;
106		}
107
108		// now refresh the repo-cache of the new repository
109		BString repoName = addRequest.RepositoryName();
110		BPackageRoster roster;
111		BRepositoryConfig repoConfig;
112		roster.GetRepositoryConfig(repoName, &repoConfig);
113
114		BRefreshRepositoryRequest refreshRequest(context, repoConfig);
115		result = refreshRequest.Process(true);
116		if (result != B_OK) {
117			if (result != B_CANCELED) {
118				DIE(result, "request for refreshing repository \"%s\" failed",
119					repoName.String());
120			}
121			return 1;
122		}
123	}
124
125	return 0;
126}
127