Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2012 Baptiste Daroussin <bapt@FreeBSD.org>
3 : : * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
4 : : * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
5 : : * Copyright (c) 2014 Matthew Seaman <matthew@FreeBSD.org>
6 : : * All rights reserved.
7 : : *
8 : : * Redistribution and use in source and binary forms, with or without
9 : : * modification, are permitted provided that the following conditions
10 : : * are met:
11 : : * 1. Redistributions of source code must retain the above copyright
12 : : * notice, this list of conditions and the following disclaimer
13 : : * in this position and unchanged.
14 : : * 2. Redistributions in binary form must reproduce the above copyright
15 : : * notice, this list of conditions and the following disclaimer in the
16 : : * documentation and/or other materials provided with the distribution.
17 : : *
18 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
19 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
22 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 : : */
29 : :
30 : : #include <sys/stat.h>
31 : : #include <sys/param.h>
32 : :
33 : : #include <err.h>
34 : : #include <getopt.h>
35 : : #include <stdio.h>
36 : : #include <stdlib.h>
37 : : #include <string.h>
38 : : #include <unistd.h>
39 : :
40 : : #include <pkg.h>
41 : :
42 : : #include "pkgcli.h"
43 : :
44 : : static bool
45 : 6 : _find_repo(c_charv_t *reponames, const char *name)
46 : : {
47 [ + + ]: 7 : for (size_t i = 0; i < reponames->len; i++) {
48 [ + + ]: 6 : if (STREQ(name, reponames->d[i]))
49 : 5 : return (true);
50 : 1 : }
51 : 1 : return(false);
52 : 6 : }
53 : :
54 : : /**
55 : : * Fetch repository calalogues.
56 : : */
57 : : int
58 : 124 : pkgcli_update(bool force, bool strict, c_charv_t *reponames)
59 : : {
60 : 124 : int retcode = EPKG_FATAL, update_count = 0, total_count = 0;
61 : 124 : struct pkg_repo *r = NULL;
62 : :
63 : : /* Only auto update if the user has write access. */
64 [ - + - + ]: 248 : if (pkgdb_access2(PKGDB_MODE_READ|PKGDB_MODE_WRITE|PKGDB_MODE_CREATE,
65 : 248 : PKGDB_DB_REPO, reponames) == EPKG_ENOACCESS)
66 : 0 : return (EPKG_OK);
67 : :
68 [ + + ]: 124 : if (pkg_repos_total_count() == 0) {
69 : 1 : fprintf(stderr, "No active remote repositories configured.\n");
70 : 1 : return (EPKG_FATAL);
71 : : }
72 : :
73 [ + + ]: 258 : while (pkg_repos(&r) == EPKG_OK) {
74 [ + + ]: 135 : if (reponames->len > 0 ) {
75 [ + + ]: 6 : if (!_find_repo(reponames, pkg_repo_name(r)))
76 : 1 : continue;
77 : 5 : } else {
78 [ + - ]: 129 : if (!pkg_repo_enabled(r))
79 : 0 : continue;
80 : : }
81 : :
82 [ + + ]: 134 : if (!quiet)
83 : 105 : printf("Updating %s repository catalogue...\n",
84 : 105 : pkg_repo_name(r));
85 : :
86 : 134 : retcode = pkg_update(r, force);
87 : :
88 [ + + ]: 134 : if (retcode == EPKG_UPTODATE) {
89 : 54 : retcode = EPKG_OK;
90 [ + + ]: 54 : if (!quiet) {
91 : 36 : printf("%s repository is up to date.\n",
92 : 36 : pkg_repo_name(r));
93 : 36 : }
94 : 54 : }
95 [ + + - + ]: 80 : else if (retcode != EPKG_OK && strict)
96 : 8 : retcode = EPKG_FATAL;
97 : :
98 [ + + ]: 134 : if (retcode == EPKG_OK) {
99 : 126 : update_count++;
100 : 126 : }
101 : :
102 : 134 : total_count ++;
103 : : }
104 : :
105 [ + - ]: 123 : if (total_count == 0) {
106 : 0 : retcode = EPKG_FATAL;
107 [ # # ]: 0 : if (!quiet) {
108 : 0 : printf("No repositories are enabled.\n");
109 : 0 : }
110 : 0 : }
111 [ + + ]: 123 : else if (update_count == total_count) {
112 [ + + ]: 115 : if (!quiet) {
113 [ + - + + ]: 86 : if (reponames == NULL || reponames->len == 0)
114 : 81 : printf("All repositories are up to date.\n");
115 : : else {
116 [ + + ]: 10 : for (size_t i = 0; i < reponames->len; i++)
117 : 5 : printf("%s%s", i == 0 ? "" : ", ", reponames->d[i]);
118 : 5 : printf(" %s up to date.\n", reponames->len == 1 ? "is" : "are");
119 : : }
120 : 86 : }
121 : 115 : }
122 [ + - ]: 8 : else if (total_count == 1) {
123 [ - + ]: 8 : if (!quiet) {
124 : 8 : printf("Error updating repositories!\n");
125 : 8 : }
126 : 8 : }
127 : : else {
128 [ # # ]: 0 : if (!quiet) {
129 : 0 : printf("Error updating repositories!\n");
130 : 0 : }
131 [ # # ]: 0 : if (strict) {
132 : 0 : retcode = EPKG_FATAL;
133 : 0 : }
134 : : }
135 : :
136 : 123 : return (retcode);
137 : 124 : }
138 : :
139 : :
140 : : void
141 : 0 : usage_update(void)
142 : : {
143 : 0 : fprintf(stderr, "Usage: pkg update [-fq] [-r reponame]\n\n");
144 : 0 : fprintf(stderr, "For more information, see 'pkg help update'.\n");
145 : 0 : }
146 : :
147 : : int
148 : 35 : exec_update(int argc, char **argv)
149 : : {
150 : : int ret;
151 : : int ch;
152 : : c_charv_t reponames;
153 : :
154 : 35 : struct option longopts[] = {
155 : : { "force", no_argument, NULL, 'f' },
156 : : { "quiet", no_argument, NULL, 'q' },
157 : : { "repository", required_argument, NULL, 'r' },
158 : : { NULL, 0, NULL, 0 },
159 : : };
160 : :
161 : 35 : pkgvec_init(&reponames);
162 [ + + ]: 43 : while ((ch = getopt_long(argc, argv, "+fqr:", longopts, NULL)) != -1) {
163 [ + + - - ]: 8 : switch (ch) {
164 : : case 'f':
165 : 7 : force = true;
166 : 7 : break;
167 : : case 'q':
168 : 1 : quiet = true;
169 : 1 : break;
170 : : case 'r':
171 [ # # # # : 0 : pkgvec_push(&reponames, optarg);
# # ]
172 : 0 : break;
173 : : default:
174 : 0 : usage_update();
175 : 0 : return (EXIT_FAILURE);
176 : : }
177 : : }
178 : 35 : argc -= optind;
179 : :
180 [ - + ]: 35 : if (argc != 0) {
181 : 0 : usage_update();
182 : 0 : return (EXIT_FAILURE);
183 : : }
184 : :
185 : 35 : ret = pkgdb_access2(PKGDB_MODE_WRITE|PKGDB_MODE_CREATE,
186 : : PKGDB_DB_REPO, &reponames);
187 [ - + ]: 35 : if (ret == EPKG_ENOACCESS) {
188 : 0 : warnx("Insufficient privileges to update the repository "
189 : : "catalogue.");
190 : 0 : return (EXIT_FAILURE);
191 [ - + ]: 35 : } else if (ret != EPKG_OK)
192 : 0 : return (EXIT_FAILURE);
193 : :
194 : : /* For pkg-update update op is strict */
195 : 35 : ret = pkgcli_update(force, true, &reponames);
196 : :
197 : 35 : return ((ret == EPKG_OK) ? EXIT_SUCCESS : EXIT_FAILURE);
198 : 35 : }
|