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) 2012-2015 Matthew Seaman <matthew@FreeBSD.org>
6 : : * Copyright (c) 2013-2016 Vsevolod Stakhov <vsevolod@FreeBSD.org>
7 : : * All rights reserved.
8 : : *
9 : : * Redistribution and use in source and binary forms, with or without
10 : : * modification, are permitted provided that the following conditions
11 : : * are met:
12 : : * 1. Redistributions of source code must retain the above copyright
13 : : * notice, this list of conditions and the following disclaimer
14 : : * in this position and unchanged.
15 : : * 2. Redistributions in binary form must reproduce the above copyright
16 : : * notice, this list of conditions and the following disclaimer in the
17 : : * documentation and/or other materials provided with the distribution.
18 : : *
19 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
20 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
23 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 : : */
30 : :
31 : : #ifdef HAVE_CONFIG_H
32 : : #include "pkg_config.h"
33 : : #endif
34 : :
35 : : #include <sys/param.h>
36 : : #include <sys/stat.h>
37 : :
38 : : #include <err.h>
39 : : #include <fcntl.h>
40 : : #include <grp.h>
41 : : #include <inttypes.h>
42 : : #ifdef HAVE_LIBUTIL_H
43 : : #include <libutil.h>
44 : : #endif
45 : : #include <string.h>
46 : : #include <unistd.h>
47 : : #include <stdarg.h>
48 : : #include <paths.h>
49 : : #include <stdio.h>
50 : : #include <stdlib.h>
51 : : #include <errno.h>
52 : : #include <pwd.h>
53 : : #include <pkg.h>
54 : :
55 : : #include <bsd_compat.h>
56 : :
57 : : #include "utlist.h"
58 : : #include "pkgcli.h"
59 : :
60 : : struct jobs_sum_number {
61 : : int install;
62 : : int reinstall;
63 : : int downgrade;
64 : : int upgrade;
65 : : int delete;
66 : : int fetch;
67 : : };
68 : :
69 : : void
70 : 0 : append_yesno(bool r, char *yesnomsg, size_t len)
71 : : {
72 : : static const char trunc[] = "\n[truncated] ";
73 : : /* These two strings must be the same length. */
74 : : static const char yes[] = "[Y/n]: ";
75 : : static const char no[] = "[y/N]: ";
76 : :
77 : 0 : size_t msglen = strlen(yesnomsg);
78 : :
79 [ # # ]: 0 : if (msglen > len - sizeof yes) {
80 : 0 : yesnomsg[len - sizeof trunc - sizeof yes] = '\0';
81 : 0 : strlcat(yesnomsg, trunc, len);
82 : 0 : }
83 : 0 : strlcat(yesnomsg, r ? yes : no, len);
84 : 0 : }
85 : :
86 : : bool
87 : 0 : query_tty_yesno(bool r, const char *msg, ...)
88 : : {
89 : : int c;
90 : : va_list ap;
91 : : int tty_fd;
92 : : FILE *tty;
93 : 0 : int tty_flags = O_RDWR;
94 : : char yesnomsg[65536];
95 : :
96 : : #ifdef O_TTY_INIT
97 : 0 : tty_flags |= O_TTY_INIT;
98 : : #endif
99 : 0 : tty_fd = open(_PATH_TTY, tty_flags);
100 [ # # ]: 0 : if (tty_fd == -1) {
101 : : /* No ctty -- return the default answer */
102 [ # # ]: 0 : if (default_yes)
103 : 0 : return (true);
104 : 0 : return (r);
105 : : }
106 : :
107 : 0 : tty = fdopen(tty_fd, "r+");
108 : :
109 : 0 : strlcpy(yesnomsg, msg, sizeof(yesnomsg));
110 [ # # ]: 0 : append_yesno(default_yes || r, yesnomsg, sizeof yesnomsg);
111 : :
112 : 0 : va_start(ap, msg);
113 : 0 : pkg_vfprintf(tty, yesnomsg, ap);
114 : 0 : va_end(ap);
115 : :
116 : 0 : fflush(tty);
117 [ # # # # ]: 0 : c = getc(tty);
118 [ # # # # ]: 0 : if (c == 'y' || c == 'Y')
119 : 0 : r = true;
120 [ # # # # ]: 0 : else if (c == 'n' || c == 'N')
121 : 0 : r = false;
122 [ # # # # ]: 0 : else if (c == '\n' || c == EOF) {
123 [ # # ]: 0 : if (default_yes)
124 : 0 : r = true;
125 : : /* Else, r is not modified. It's default value is kept. */
126 : 0 : goto cleanup;
127 : : }
128 : :
129 [ # # # # : 0 : while ((c = getc(tty)) != '\n' && c != EOF)
# # # # ]
130 : 0 : continue;
131 : :
132 : : cleanup:
133 : 0 : fclose(tty);
134 : :
135 : 0 : return (r);
136 : 0 : }
137 : :
138 : : static bool
139 : 324 : vquery_yesno(bool deft, const char *msg, va_list ap)
140 : : {
141 : 324 : char *line = NULL;
142 : : char *out;
143 : 324 : size_t linecap = 0;
144 : : int linelen;
145 : 324 : bool r = deft;
146 : : char yesnomsg[65536];
147 : :
148 : : /* We use default value of yes or default in case of quiet mode */
149 [ - + ]: 324 : if (quiet)
150 [ # # # # ]: 0 : return (yes || default_yes || r);
151 : :
152 [ - + ]: 324 : if (dry_run)
153 [ # # # # ]: 0 : return (yes || default_yes || r );
154 : :
155 : : /* Do not query user if we have specified yes flag */
156 [ + - ]: 324 : if (yes)
157 : 324 : return (true);
158 : :
159 : 0 : strlcpy(yesnomsg, msg, sizeof(yesnomsg));
160 [ # # ]: 0 : append_yesno(default_yes || r, yesnomsg, sizeof yesnomsg);
161 : :
162 : 0 : pkg_vasprintf(&out, yesnomsg, ap);
163 : 0 : printf("%s", out);
164 : :
165 : 0 : for (;;) {
166 [ # # ]: 0 : if ((linelen = getline(&line, &linecap, stdin)) != -1) {
167 : :
168 [ # # # # ]: 0 : if (linelen == 1 && line[0] == '\n') {
169 [ # # ]: 0 : if (default_yes)
170 : 0 : r = true;
171 : 0 : break;
172 : : }
173 [ # # ]: 0 : else if (linelen == 2) {
174 [ # # # # ]: 0 : if (line[0] == 'y' || line[0] == 'Y') {
175 : 0 : r = true;
176 : 0 : break;
177 : : }
178 [ # # # # ]: 0 : else if (line[0] == 'n' || line[0] == 'N') {
179 : 0 : r = false;
180 : 0 : break;
181 : : }
182 : 0 : }
183 : : else {
184 [ # # ]: 0 : if (strcasecmp(line, "yes\n") == 0) {
185 : 0 : r = true;
186 : 0 : break;
187 : : }
188 [ # # ]: 0 : else if (strcasecmp(line, "no\n") == 0) {
189 : 0 : r = false;
190 : 0 : break;
191 : : }
192 : : }
193 : 0 : printf("Please type 'Y[es]' or 'N[o]' to make a selection\n");
194 : 0 : printf("%s", out);
195 : 0 : }
196 : : else {
197 [ # # ]: 0 : if (errno == EINTR) {
198 : 0 : continue;
199 : : } else {
200 [ # # ]: 0 : if (default_yes) {
201 : 0 : r = true;
202 : : /* Else, assume EOF as false */
203 : 0 : } else {
204 : 0 : r = false;
205 : : }
206 : 0 : break;
207 : : }
208 : : }
209 : : }
210 : :
211 : 0 : free(out);
212 : :
213 : 0 : return (r);
214 : 324 : }
215 : :
216 : : bool
217 : 324 : query_yesno(bool deft, const char *msg, ...)
218 : : {
219 : : va_list ap;
220 : : bool r;
221 : :
222 : 324 : va_start(ap, msg);
223 : 324 : r = vquery_yesno(deft, msg, ap);
224 : 324 : va_end(ap);
225 : :
226 : 324 : return (r);
227 : : }
228 : :
229 : : int
230 : 0 : query_select(const char *msg, const char **opts, int ncnt, int deft)
231 : : {
232 : : int i;
233 : 0 : char *str = NULL;
234 : 0 : char *endpntr = NULL;
235 : 0 : size_t n = 0;
236 : :
237 : 0 : printf("%s\n", msg);
238 [ # # ]: 0 : for (i = 0; i < ncnt; i++) {
239 [ # # ]: 0 : if (i + 1 == deft)
240 : : {
241 : 0 : printf("*[%d] %s\n",
242 : 0 : i + 1, opts[i]);
243 : 0 : } else {
244 : 0 : printf(" [%d] %s\n",
245 : 0 : i + 1, opts[i]);
246 : : }
247 : 0 : }
248 : :
249 : 0 : i = deft;
250 [ # # ]: 0 : while (getline(&str, &n, stdin) == -1) {
251 [ # # ]: 0 : if (errno == EINTR)
252 : 0 : continue;
253 : : else
254 : 0 : goto cleanup;
255 : : }
256 : 0 : i = (int) strtoul(str, &endpntr, 10);
257 : :
258 [ # # # # ]: 0 : if (endpntr == NULL || *endpntr == '\0') {
259 : 0 : i = deft;
260 [ # # # # ]: 0 : } else if (*endpntr == '\n' || *endpntr == '\r') {
261 [ # # # # ]: 0 : if (i > ncnt || i < 1)
262 : 0 : i = deft;
263 : 0 : } else
264 : 0 : i = -1;
265 : :
266 : : cleanup:
267 : 0 : free(str);
268 : 0 : return (i);
269 : : }
270 : :
271 : : /* what the pkg needs to load in order to display the requested info */
272 : : int
273 : 152 : info_flags(uint64_t opt, bool remote)
274 : : {
275 : 152 : int flags = PKG_LOAD_BASIC;
276 : :
277 [ + + ]: 152 : if (opt & INFO_CATEGORIES)
278 : 30 : flags |= PKG_LOAD_CATEGORIES;
279 [ + + ]: 152 : if (opt & INFO_LICENSES)
280 : 30 : flags |= PKG_LOAD_LICENSES;
281 [ + + ]: 152 : if (opt & (INFO_OPTIONS|INFO_OPTION_DEFAULTS|INFO_OPTION_DESCRIPTIONS))
282 : 30 : flags |= PKG_LOAD_OPTIONS;
283 [ + + ]: 152 : if (opt & INFO_SHLIBS_REQUIRED)
284 : 30 : flags |= PKG_LOAD_SHLIBS_REQUIRED;
285 [ + + ]: 152 : if (opt & INFO_SHLIBS_PROVIDED)
286 : 30 : flags |= PKG_LOAD_SHLIBS_PROVIDED;
287 [ + + ]: 152 : if (opt & INFO_PROVIDED)
288 : 30 : flags |= PKG_LOAD_PROVIDES;
289 [ + + ]: 152 : if (opt & INFO_REQUIRED)
290 : 30 : flags |= PKG_LOAD_REQUIRES;
291 [ + + ]: 152 : if (opt & INFO_ANNOTATIONS)
292 : 72 : flags |= PKG_LOAD_ANNOTATIONS;
293 [ + - ]: 152 : if (opt & INFO_DEPS)
294 : 0 : flags |= PKG_LOAD_DEPS;
295 [ + - ]: 152 : if (opt & INFO_RDEPS)
296 : 0 : flags |= PKG_LOAD_RDEPS;
297 [ + - ]: 152 : if (opt & INFO_FILES)
298 : 0 : flags |= PKG_LOAD_FILES;
299 [ + - ]: 152 : if (opt & INFO_DIRS)
300 : 0 : flags |= PKG_LOAD_DIRS;
301 [ + - ]: 152 : if (opt & INFO_USERS)
302 : 0 : flags |= PKG_LOAD_USERS;
303 [ + - ]: 152 : if (opt & INFO_GROUPS)
304 : 0 : flags |= PKG_LOAD_GROUPS;
305 [ + - ]: 152 : if (opt & INFO_RAW) {
306 : 0 : flags |= PKG_LOAD_CATEGORIES |
307 : : PKG_LOAD_LICENSES |
308 : : PKG_LOAD_OPTIONS |
309 : : PKG_LOAD_SHLIBS_REQUIRED |
310 : : PKG_LOAD_SHLIBS_PROVIDED |
311 : : PKG_LOAD_PROVIDES |
312 : : PKG_LOAD_REQUIRES |
313 : : PKG_LOAD_ANNOTATIONS |
314 : : PKG_LOAD_DEPS;
315 [ # # ]: 0 : if (!remote) {
316 : 0 : flags |= PKG_LOAD_FILES |
317 : : PKG_LOAD_DIRS |
318 : : PKG_LOAD_USERS |
319 : : PKG_LOAD_GROUPS |
320 : : PKG_LOAD_SCRIPTS |
321 : : PKG_LOAD_LUA_SCRIPTS;
322 : 0 : }
323 : 0 : }
324 : :
325 : 152 : return flags;
326 : : }
327 : :
328 : : void
329 : 181 : print_info(struct pkg * const pkg, uint64_t options)
330 : : {
331 : 181 : bool print_tag = false;
332 : 181 : bool show_locks = false;
333 : : const char *repourl;
334 : : unsigned opt;
335 : : int64_t flatsize, oldflatsize, pkgsize;
336 : 181 : int cout = 0; /* Number of characters output */
337 : : int info_num; /* Number of different data items to print */
338 : 181 : int outflags = PKG_MANIFEST_EMIT_LOCAL_METADATA;
339 : :
340 : 181 : pkg_get(pkg,
341 : : PKG_REPOURL, &repourl,
342 : : PKG_FLATSIZE, &flatsize,
343 : : PKG_OLD_FLATSIZE, &oldflatsize,
344 : : PKG_PKGSIZE, &pkgsize);
345 : :
346 [ + + ]: 181 : if (options & INFO_RAW) {
347 [ - + + - : 33 : switch (options & (INFO_RAW_YAML|INFO_RAW_JSON|INFO_RAW_JSON_COMPACT|INFO_RAW_UCL)) {
- ]
348 : : case INFO_RAW_YAML:
349 : 4 : outflags |= PKG_MANIFEST_EMIT_PRETTY;
350 : 4 : break;
351 : : case INFO_RAW_UCL:
352 : 29 : outflags |= PKG_MANIFEST_EMIT_UCL;
353 : 29 : break;
354 : : case INFO_RAW_JSON:
355 : 0 : outflags |= PKG_MANIFEST_EMIT_JSON;
356 : 0 : break;
357 : : case INFO_RAW_JSON_COMPACT:
358 : 0 : break;
359 : : default:
360 : 0 : outflags |= PKG_MANIFEST_EMIT_UCL;
361 : 0 : }
362 [ + - ]: 33 : if (pkg_type(pkg) == PKG_REMOTE)
363 : 0 : outflags |= PKG_MANIFEST_EMIT_COMPACT;
364 : :
365 : 33 : pkg_emit_manifest_file(pkg, stdout, outflags, NULL);
366 : :
367 : 33 : return;
368 : : }
369 : :
370 : : /* Show locking status when requested to display it and the
371 : : package is locally installed */
372 [ + + + - ]: 148 : if (pkg_type(pkg) == PKG_INSTALLED && (options & INFO_LOCKED) != 0)
373 : 0 : show_locks = true;
374 : :
375 [ + + ]: 148 : if (!quiet) {
376 : : /* Print a tag-line identifying the package -- either
377 : : NAMEVER, ORIGIN or NAME (in that order of
378 : : preference). This may be the only output from this
379 : : function */
380 : :
381 [ + + ]: 140 : if (options & INFO_TAG_NAMEVER)
382 : 132 : cout = pkg_printf("%n-%v", pkg, pkg);
383 [ + - ]: 8 : else if (options & INFO_TAG_ORIGIN)
384 : 8 : cout = pkg_printf("%o", pkg);
385 [ # # ]: 0 : else if (options & INFO_TAG_NAME)
386 : 0 : cout = pkg_printf("%n", pkg);
387 : 140 : }
388 : :
389 : : /* If we printed a tag, and there are no other items to print,
390 : : then just return now. If there's only one single-line item
391 : : to print, show it at column 32 on the same line. If there's
392 : : one multi-line item to print, start a new line. If there is
393 : : more than one item to print per pkg, use 'key : value'
394 : : style to show on a new line. */
395 : :
396 : 148 : info_num = 0;
397 [ + + ]: 4588 : for (opt = 0x1U; opt <= INFO_LASTFIELD; opt <<= 1)
398 [ + + ]: 4932 : if ((opt & options) != 0)
399 : 492 : info_num++;
400 : :
401 [ + + + - ]: 148 : if (info_num == 0 && cout > 0) {
402 : 16 : printf("\n");
403 : 16 : return;
404 : : }
405 : :
406 [ + + ]: 132 : if (info_num == 1) {
407 : : /* Only one item to print */
408 : 114 : print_tag = false;
409 [ + + ]: 114 : if (!quiet) {
410 [ + + ]: 106 : if (options & INFO_MULTILINE)
411 : 66 : printf(":\n");
412 : : else {
413 [ + - ]: 40 : if (cout < 31)
414 : 40 : cout = 31 - cout;
415 : : else
416 : 0 : cout = 1;
417 : 40 : printf("%*s", cout, " ");
418 : : }
419 : 106 : }
420 : 114 : } else {
421 : : /* Several items to print */
422 : 18 : print_tag = true;
423 [ - + ]: 18 : if (!quiet)
424 : 18 : printf("\n");
425 : : }
426 : :
427 [ + + ]: 4092 : for (opt = 0x1; opt <= INFO_LASTFIELD; opt <<= 1) {
428 [ + + ]: 3960 : if ((opt & options) == 0)
429 : 3468 : continue;
430 : :
431 [ - + + + : 492 : switch (opt) {
+ + + + +
+ + + + +
+ + + + +
+ + + - -
+ - - - +
- - ]
432 : : case INFO_NAME:
433 [ - + ]: 18 : if (print_tag)
434 : 18 : printf("%-15s: ", "Name");
435 : 18 : pkg_printf("%n\n", pkg);
436 : 18 : break;
437 : : case INFO_INSTALLED:
438 [ + - ]: 18 : if (pkg_type(pkg) == PKG_INSTALLED) {
439 [ - + ]: 18 : if (print_tag) {
440 : 18 : printf("%-15s: ", "Installed on");
441 : 18 : pkg_printf("%t%{%c %Z%}\n", pkg);
442 : 18 : }
443 [ # # ]: 18 : } else if (!print_tag)
444 : 0 : printf("\n");
445 : 18 : break;
446 : : case INFO_VERSION:
447 [ - + ]: 18 : if (print_tag)
448 : 18 : printf("%-15s: ", "Version");
449 : 18 : pkg_printf("%v\n", pkg);
450 : 18 : break;
451 : : case INFO_ORIGIN:
452 [ + + ]: 22 : if (print_tag)
453 : 18 : printf("%-15s: ", "Origin");
454 : 22 : pkg_printf("%o\n", pkg);
455 : 22 : break;
456 : : case INFO_PREFIX:
457 [ - + ]: 18 : if (print_tag)
458 : 18 : printf("%-15s: ", "Prefix");
459 : 18 : pkg_printf("%p\n", pkg);
460 : 18 : break;
461 : : case INFO_REPOSITORY:
462 [ - + # # ]: 18 : if (pkg_type(pkg) == PKG_REMOTE &&
463 [ # # ]: 0 : repourl != NULL && repourl[0] != '\0') {
464 [ # # ]: 0 : if (print_tag)
465 : 0 : printf("%-15s: ", "Repository");
466 : 0 : pkg_printf("%N [%S]\n", pkg, repourl);
467 [ + - ]: 18 : } else if (!print_tag)
468 : 0 : printf("\n");
469 : 18 : break;
470 : : case INFO_CATEGORIES:
471 [ - + ]: 18 : if (print_tag)
472 : 18 : printf("%-15s: ", "Categories");
473 : 18 : pkg_printf("%C%{%Cn%| %}\n", pkg);
474 : 18 : break;
475 : : case INFO_LICENSES:
476 [ - + ]: 18 : if (print_tag)
477 : 18 : printf("%-15s: ", "Licenses");
478 : 18 : pkg_printf("%L%{%Ln%| %l %}\n", pkg);
479 : 18 : break;
480 : : case INFO_MAINTAINER:
481 [ - + ]: 18 : if (print_tag)
482 : 18 : printf("%-15s: ", "Maintainer");
483 : 18 : pkg_printf("%m\n", pkg);
484 : 18 : break;
485 : : case INFO_WWW:
486 [ - + ]: 18 : if (print_tag)
487 : 18 : printf("%-15s: ", "WWW");
488 : 18 : pkg_printf("%w\n", pkg);
489 : 18 : break;
490 : : case INFO_COMMENT:
491 [ + + ]: 58 : if (print_tag)
492 : 18 : printf("%-15s: ", "Comment");
493 : 58 : pkg_printf("%c\n", pkg);
494 : 58 : break;
495 : : case INFO_OPTIONS:
496 [ + - ]: 18 : if (pkg_list_count(pkg, PKG_OPTIONS) > 0) {
497 [ # # ]: 0 : if (print_tag)
498 : 0 : printf("%-15s:\n", "Options");
499 [ # # ]: 0 : if (quiet)
500 : 0 : pkg_printf("%O%{%-15On: %Ov\n%|%}", pkg);
501 : : else
502 : 0 : pkg_printf("%O%{\t%-15On: %Ov\n%|%}", pkg);
503 : 0 : }
504 : 18 : break;
505 : : case INFO_SHLIBS_REQUIRED:
506 [ + - ]: 18 : if (pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0) {
507 [ # # ]: 0 : if (print_tag)
508 : 0 : printf("%-15s:\n", "Shared Libs required");
509 [ # # ]: 0 : if (quiet)
510 : 0 : pkg_printf("%B%{%Bn\n%|%}", pkg);
511 : : else
512 : 0 : pkg_printf("%B%{\t%Bn\n%|%}", pkg);
513 : 0 : }
514 : 18 : break;
515 : : case INFO_SHLIBS_PROVIDED:
516 [ + - ]: 18 : if (pkg_list_count(pkg, PKG_SHLIBS_PROVIDED) > 0) {
517 [ # # ]: 0 : if (print_tag)
518 : 0 : printf("%-15s:\n", "Shared Libs provided");
519 [ # # ]: 0 : if (quiet)
520 : 0 : pkg_printf("%b%{%bn\n%|%}", pkg);
521 : : else
522 : 0 : pkg_printf("%b%{\t%bn\n%|%}", pkg);
523 : 0 : }
524 : 18 : break;
525 : : case INFO_REQUIRED:
526 [ + - ]: 18 : if (pkg_list_count(pkg, PKG_REQUIRES) > 0) {
527 [ # # ]: 0 : if (print_tag)
528 : 0 : printf("%-15s:\n", "Requires");
529 [ # # ]: 0 : if (quiet)
530 : 0 : pkg_printf("%Y%{%Yn\n%|%}", pkg);
531 : : else
532 : 0 : pkg_printf("%Y%{\t%Yn\n%|%}", pkg);
533 : 0 : }
534 : 18 : break;
535 : : case INFO_PROVIDED:
536 [ + - ]: 18 : if (pkg_list_count(pkg, PKG_PROVIDES) > 0) {
537 [ # # ]: 0 : if (print_tag)
538 : 0 : printf("%-15s:\n", "Provides");
539 [ # # ]: 0 : if (quiet)
540 : 0 : pkg_printf("%y%{%yn\n%|%}", pkg);
541 : : else
542 : 0 : pkg_printf("%y%{\t%yn\n%|%}", pkg);
543 : 0 : }
544 : 18 : break;
545 : : case INFO_ANNOTATIONS:
546 [ + + ]: 60 : if (print_tag)
547 : 18 : printf("%-15s:\n", "Annotations");
548 [ - + ]: 60 : if (quiet)
549 : 0 : pkg_printf("%A%{%-15An: %Av\n%|%}", pkg);
550 : : else
551 : 60 : pkg_printf("%A%{\t%-15An: %Av\n%|%}", pkg);
552 : 60 : break;
553 : : case INFO_FLATSIZE:
554 [ - + ]: 18 : if (print_tag)
555 : 18 : printf("%-15s: ", "Flat size");
556 : 18 : pkg_printf("%#sB\n", pkg);
557 : 18 : break;
558 : : case INFO_PKGSIZE: /* Remote pkgs only */
559 [ - + ]: 18 : if (pkg_type(pkg) == PKG_REMOTE) {
560 [ # # ]: 0 : if (print_tag)
561 : 0 : printf("%-15s: ", "Pkg size");
562 : 0 : pkg_printf("%#xB\n", pkg);
563 [ + - ]: 18 : } else if (!print_tag)
564 : 0 : printf("\n");
565 : 18 : break;
566 : : case INFO_DESCR:
567 [ - + ]: 18 : if (print_tag)
568 : 18 : printf("%-15s:\n", "Description");
569 : 18 : pkg_printf("%e\n", pkg);
570 : 18 : break;
571 : : case INFO_MESSAGE:
572 [ + - ]: 24 : if (print_tag)
573 : 0 : printf("%-15s:\n", "Message");
574 [ - + ]: 24 : if (pkg_has_message(pkg))
575 : 24 : pkg_printf("%M\n", pkg);
576 : 24 : break;
577 : : case INFO_DEPS:
578 [ # # ]: 0 : if (pkg_list_count(pkg, PKG_DEPS) > 0) {
579 [ # # ]: 0 : if (print_tag)
580 : 0 : printf("%-15s:\n", "Depends on");
581 [ # # ]: 0 : if (quiet) {
582 [ # # ]: 0 : if (show_locks)
583 : 0 : pkg_printf("%d%{%dn-%dv%#dk\n%|%}", pkg);
584 : : else
585 : 0 : pkg_printf("%d%{%dn-%dv\n%|%}", pkg);
586 : 0 : } else {
587 [ # # ]: 0 : if (show_locks)
588 : 0 : pkg_printf("%d%{\t%dn-%dv%#dk\n%|%}", pkg);
589 : : else
590 : 0 : pkg_printf("%d%{\t%dn-%dv\n%|%}", pkg);
591 : : }
592 : 0 : }
593 : 0 : break;
594 : : case INFO_RDEPS:
595 [ # # ]: 0 : if (pkg_list_count(pkg, PKG_RDEPS) > 0) {
596 [ # # ]: 0 : if (print_tag)
597 : 0 : printf("%-15s:\n", "Required by");
598 [ # # ]: 0 : if (quiet) {
599 [ # # ]: 0 : if (show_locks)
600 : 0 : pkg_printf("%r%{%rn-%rv%#rk\n%|%}", pkg);
601 : : else
602 : 0 : pkg_printf("%r%{%rn-%rv\n%|%}", pkg);
603 : 0 : } else {
604 [ # # ]: 0 : if (show_locks)
605 : 0 : pkg_printf("%r%{\t%rn-%rv%#rk\n%|%}", pkg);
606 : : else
607 : 0 : pkg_printf("%r%{\t%rn-%rv\n%|%}", pkg);
608 : : }
609 : 0 : }
610 : 0 : break;
611 : : case INFO_FILES: /* Installed pkgs only */
612 [ + - - + ]: 4 : if (pkg_type(pkg) != PKG_REMOTE &&
613 : 4 : pkg_list_count(pkg, PKG_FILES) > 0) {
614 [ + - ]: 4 : if (print_tag)
615 : 0 : printf("%-15s:\n", "Files");
616 [ + - ]: 4 : if (quiet)
617 : 4 : pkg_printf("%F%{%Fn\n%|%}", pkg);
618 : : else
619 : 0 : pkg_printf("%F%{\t%Fn\n%|%}", pkg);
620 : 4 : }
621 : 4 : break;
622 : : case INFO_DIRS: /* Installed pkgs only */
623 [ # # # # ]: 0 : if (pkg_type(pkg) != PKG_REMOTE &&
624 : 0 : pkg_list_count(pkg, PKG_DIRS) > 0) {
625 [ # # ]: 0 : if (print_tag)
626 : 0 : printf("%-15s:\n", "Directories");
627 [ # # ]: 0 : if (quiet)
628 : 0 : pkg_printf("%D%{%Dn\n%|%}", pkg);
629 : : else
630 : 0 : pkg_printf("%D%{\t%Dn\n%|%}", pkg);
631 : 0 : }
632 : 0 : break;
633 : : case INFO_USERS: /* Installed pkgs only */
634 [ # # # # ]: 0 : if (pkg_type(pkg) != PKG_REMOTE &&
635 : 0 : pkg_list_count(pkg, PKG_USERS) > 0) {
636 [ # # ]: 0 : if (print_tag)
637 : 0 : printf("%-15s: ", "Users");
638 : 0 : pkg_printf("%U%{%Un%| %}\n", pkg);
639 : 0 : }
640 : 0 : break;
641 : : case INFO_GROUPS: /* Installed pkgs only */
642 [ # # # # ]: 0 : if (pkg_type(pkg) != PKG_REMOTE &&
643 : 0 : pkg_list_count(pkg, PKG_GROUPS) > 0) {
644 [ # # ]: 0 : if (print_tag)
645 : 0 : printf("%-15s: ", "Groups");
646 : 0 : pkg_printf("%G%{%Gn%| %}\n", pkg);
647 : 0 : }
648 : 0 : break;
649 : : case INFO_ARCH:
650 [ - + ]: 18 : if (print_tag)
651 : 18 : printf("%-15s: ", "Architecture");
652 : 18 : pkg_printf("%q\n", pkg);
653 : 18 : break;
654 : : case INFO_REPOURL:
655 [ # # # # ]: 0 : if (pkg_type(pkg) == PKG_REMOTE &&
656 [ # # ]: 0 : repourl != NULL && repourl[0] != '\0') {
657 [ # # ]: 0 : if (print_tag)
658 : 0 : printf("%-15s: ", "Pkg URL");
659 [ # # ]: 0 : if (repourl[strlen(repourl) -1] == '/')
660 : 0 : pkg_printf("%S%R\n", repourl, pkg);
661 : : else
662 : 0 : pkg_printf("%S/%R\n", repourl, pkg);
663 [ # # ]: 0 : } else if (!print_tag)
664 : 0 : printf("\n");
665 : 0 : break;
666 : : case INFO_LOCKED:
667 [ # # ]: 0 : if (print_tag)
668 : 0 : printf("%-15s: ", "Locked");
669 : 0 : pkg_printf("%?k\n", pkg);
670 : 0 : break;
671 : : }
672 : 492 : }
673 : 181 : }
674 : :
675 : : enum pkg_display_type {
676 : : PKG_DISPLAY_LOCKED = 0,
677 : : PKG_DISPLAY_DELETE,
678 : : PKG_DISPLAY_INSTALL,
679 : : PKG_DISPLAY_UPGRADE,
680 : : PKG_DISPLAY_DOWNGRADE,
681 : : PKG_DISPLAY_REINSTALL,
682 : : PKG_DISPLAY_FETCH,
683 : : PKG_DISPLAY_MAX
684 : : };
685 : : struct pkg_solved_display_item {
686 : : struct pkg *new, *old;
687 : : enum pkg_display_type display_type;
688 : : pkg_solved_t solved_type;
689 : : struct pkg_solved_display_item *prev, *next;
690 : : };
691 : :
692 : : static void
693 : 561 : set_jobs_summary_pkg(struct pkg_jobs *jobs, struct pkg *new_pkg,
694 : : struct pkg *old_pkg, pkg_solved_t type, int64_t *oldsize,
695 : : int64_t *newsize, int64_t *dlsize, struct pkg_solved_display_item **disp,
696 : : struct jobs_sum_number *sum)
697 : : {
698 : : const char *oldversion, *repopath, *destdir;
699 : : char path[MAXPATHLEN];
700 : : int ret;
701 : : struct stat st;
702 : : int64_t flatsize, oldflatsize, pkgsize;
703 : : struct pkg_solved_display_item *it;
704 : :
705 : 561 : flatsize = oldflatsize = pkgsize = 0;
706 : 561 : oldversion = NULL;
707 : :
708 : 561 : pkg_get(new_pkg, PKG_FLATSIZE, &flatsize, PKG_PKGSIZE, &pkgsize,
709 : : PKG_REPOPATH, &repopath);
710 [ + + ]: 561 : if (old_pkg != NULL)
711 : 156 : pkg_get(old_pkg, PKG_VERSION, &oldversion, PKG_FLATSIZE, &oldflatsize);
712 : :
713 : 561 : it = malloc(sizeof (*it));
714 [ + - ]: 561 : if (it == NULL) {
715 : 0 : fprintf(stderr, "malloc failed for "
716 : 0 : "pkg_solved_display_item: %s", strerror (errno));
717 : 0 : return;
718 : : }
719 : 561 : it->new = new_pkg;
720 : 561 : it->old = old_pkg;
721 : 561 : it->solved_type = type;
722 : 561 : it->display_type = PKG_DISPLAY_MAX;
723 : :
724 [ + + + - ]: 561 : if (old_pkg != NULL && pkg_is_locked(old_pkg)) {
725 : 0 : it->display_type = PKG_DISPLAY_LOCKED;
726 [ # # ]: 0 : DL_APPEND(disp[it->display_type], it);
727 : 0 : return;
728 : : }
729 : :
730 : 561 : destdir = pkg_jobs_destdir(jobs);
731 : :
732 [ + - + + : 561 : switch (type) {
- ]
733 : : case PKG_SOLVED_INSTALL:
734 : : case PKG_SOLVED_UPGRADE:
735 [ + - ]: 360 : if (destdir == NULL)
736 : 360 : ret = pkg_repo_cached_name(new_pkg, path, sizeof(path));
737 [ # # ]: 0 : else if (repopath != NULL) {
738 : 0 : snprintf(path, sizeof(path), "%s/%s", destdir, repopath);
739 : 0 : ret = EPKG_OK;
740 : 0 : } else
741 : 0 : break;
742 : :
743 [ + + + + : 360 : if ((ret == EPKG_OK || ret == EPKG_FATAL) && (stat(path, &st) == -1 || pkgsize != st.st_size)) {
+ + ]
744 : : /* file looks corrupted (wrong size),
745 : : assume a checksum mismatch will
746 : : occur later and the file will be
747 : : fetched from remote again */
748 : 660 : *dlsize += pkgsize;
749 : 660 : nbtodl += 1;
750 : 660 : }
751 : :
752 [ + + ]: 320 : if (old_pkg != NULL) {
753 [ + - + + ]: 116 : switch (pkg_version_change_between(new_pkg, old_pkg)) {
754 : : case PKG_DOWNGRADE:
755 : 0 : it->display_type = PKG_DISPLAY_DOWNGRADE;
756 : 0 : sum->downgrade++;
757 : 0 : break;
758 : : case PKG_REINSTALL:
759 : 49 : it->display_type = PKG_DISPLAY_REINSTALL;
760 : 49 : sum->reinstall++;
761 : 49 : break;
762 : : case PKG_UPGRADE:
763 : 107 : it->display_type = PKG_DISPLAY_UPGRADE;
764 : 107 : sum->upgrade++;
765 : 107 : break;
766 : : }
767 : 196 : *oldsize += oldflatsize;
768 : 196 : *newsize += flatsize;
769 : 196 : } else {
770 : 204 : it->display_type = PKG_DISPLAY_INSTALL;
771 : 204 : sum->install++;
772 : 204 : *newsize += flatsize;
773 : : }
774 : 400 : break;
775 : : case PKG_SOLVED_DELETE:
776 : 161 : *oldsize += flatsize;
777 : 161 : it->display_type = PKG_DISPLAY_DELETE;
778 : 161 : sum->delete++;
779 : 161 : break;
780 : : case PKG_SOLVED_UPGRADE_INSTALL:
781 : : case PKG_SOLVED_UPGRADE_REMOVE:
782 : : /* Ignore split-upgrade packages for display */
783 : 0 : free(it);
784 : 0 : return;
785 : : break;
786 : :
787 : : case PKG_SOLVED_FETCH:
788 : 0 : *newsize += pkgsize;
789 : 0 : it->display_type = PKG_DISPLAY_FETCH;
790 [ # # ]: 0 : if (destdir == NULL)
791 : 0 : pkg_repo_cached_name(new_pkg, path, sizeof(path));
792 : : else
793 : 0 : snprintf(path, sizeof(path), "%s/%s", destdir, repopath);
794 : :
795 [ # # ]: 0 : if (stat(path, &st) != -1) {
796 : 0 : *oldsize += st.st_size;
797 : :
798 [ # # ]: 0 : if (pkgsize != st.st_size)
799 : 0 : *dlsize += pkgsize;
800 : : else {
801 : 0 : free(it);
802 : 0 : return;
803 : : }
804 : 0 : }
805 : : else
806 : 0 : *dlsize += pkgsize;
807 : 0 : sum->fetch++;
808 : :
809 : 0 : break;
810 : : }
811 [ + + ]: 601 : DL_APPEND(disp[it->display_type], it);
812 : 521 : }
813 : :
814 : : static void
815 : 521 : display_summary_item(struct pkg_solved_display_item *it, int64_t dlsize)
816 : : {
817 : : const char *why;
818 : : int64_t pkgsize;
819 : : char size[8], tlsize[8];
820 : : const char *type;
821 : :
822 : 521 : pkg_get(it->new, PKG_PKGSIZE, &pkgsize);
823 : :
824 [ + - - + : 521 : switch (it->display_type) {
+ - + - ]
825 : : case PKG_DISPLAY_LOCKED:
826 : 0 : pkg_printf("\tPackage %n-%v is locked ", it->old, it->old);
827 [ # # # # ]: 0 : switch (it->solved_type) {
828 : : case PKG_SOLVED_INSTALL:
829 : : case PKG_SOLVED_UPGRADE:
830 : : case PKG_SOLVED_UPGRADE_INSTALL:
831 : : /* If it's a new install, then it
832 : : * cannot have been locked yet. */
833 [ # # # # ]: 0 : switch (pkg_version_change_between(it->old, it->new)) {
834 : : case PKG_DOWNGRADE:
835 : 0 : type = "downgraded";
836 : 0 : break;
837 : : case PKG_REINSTALL:
838 : 0 : type = "reinstalled";
839 : 0 : break;
840 : : case PKG_UPGRADE:
841 : 0 : type = "upgraded";
842 : 0 : break;
843 : : default: /* appease compiler warnings */
844 : 0 : type = "upgraded";
845 : 0 : break;
846 : : }
847 : 0 : pkg_printf("and may not be %S to version %v\n", type,
848 : 0 : it->new);
849 : 0 : break;
850 : : case PKG_SOLVED_DELETE:
851 : : case PKG_SOLVED_UPGRADE_REMOVE:
852 : 0 : printf("and may not be deinstalled\n");
853 : 0 : return;
854 : : break;
855 : : case PKG_SOLVED_FETCH:
856 : 0 : printf("but a new package can still be fetched\n");
857 : 0 : break;
858 : : }
859 : 0 : break;
860 : : case PKG_DISPLAY_DELETE:
861 : 161 : pkg_get(it->new, PKG_REASON, &why);
862 : 161 : pkg_printf("\t%n: %v", it->new, it->new);
863 [ + - ]: 161 : if (why != NULL)
864 : 0 : printf(" (%s)", why);
865 : 161 : printf("\n");
866 : 161 : break;
867 : : case PKG_DISPLAY_INSTALL:
868 : 204 : pkg_printf("\t%n: %v", it->new, it->new);
869 [ + + ]: 204 : if (pkg_repos_total_count() > 1)
870 : 60 : pkg_printf(" [%N]", it->new);
871 : 204 : printf("\n");
872 : 204 : break;
873 : : case PKG_DISPLAY_UPGRADE:
874 : 107 : pkg_printf("\t%n: %v -> %v", it->new, it->old, it->new);
875 [ + + ]: 107 : if (pkg_repos_total_count() > 1)
876 : 13 : pkg_printf(" [%N]", it->new);
877 : 107 : printf("\n");
878 : 107 : break;
879 : : case PKG_DISPLAY_DOWNGRADE:
880 : 0 : pkg_printf("\t%n: %v -> %v", it->new, it->old, it->new);
881 [ # # ]: 0 : if (pkg_repos_total_count() > 1)
882 : 0 : pkg_printf(" [%N]", it->new);
883 : 0 : printf("\n");
884 : 0 : break;
885 : : case PKG_DISPLAY_REINSTALL:
886 : 49 : pkg_get(it->new, PKG_REASON, &why);
887 : 49 : pkg_printf("\t%n-%v", it->new, it->new);
888 [ + + ]: 49 : if (pkg_repos_total_count() > 1)
889 : 13 : pkg_printf(" [%N]", it->new);
890 [ + + ]: 49 : if (why != NULL)
891 : 36 : printf(" (%s)", why);
892 : 49 : printf("\n");
893 : 49 : break;
894 : : case PKG_DISPLAY_FETCH:
895 : 0 : humanize_number(size, sizeof(size), pkgsize, "B",
896 : : HN_AUTOSCALE, HN_IEC_PREFIXES);
897 : 0 : humanize_number(tlsize, sizeof(size), dlsize, "B",
898 : : HN_AUTOSCALE, HN_IEC_PREFIXES);
899 : :
900 : 0 : pkg_printf("\t%n: %v ", it->new, it->new);
901 : 0 : printf("(%s: %.2f%% of the %s to download)\n", size,
902 : 0 : ((double)100 * pkgsize) / (double)dlsize, tlsize);
903 : 0 : break;
904 : : default:
905 : 0 : break;
906 : : }
907 : 521 : }
908 : :
909 : :
910 : : static const char* pkg_display_messages[PKG_DISPLAY_MAX + 1] = {
911 : : [PKG_DISPLAY_LOCKED] = "Installed packages LOCKED",
912 : : [PKG_DISPLAY_DELETE] = "Installed packages to be REMOVED",
913 : : [PKG_DISPLAY_INSTALL] = "New packages to be INSTALLED",
914 : : [PKG_DISPLAY_UPGRADE] = "Installed packages to be UPGRADED",
915 : : [PKG_DISPLAY_DOWNGRADE] = "Installed packages to be DOWNGRADED",
916 : : [PKG_DISPLAY_REINSTALL] = "Installed packages to be REINSTALLED",
917 : : [PKG_DISPLAY_FETCH] = "New packages to be FETCHED",
918 : : [PKG_DISPLAY_MAX] = NULL
919 : : };
920 : :
921 : : static int
922 : 180 : namecmp(struct pkg_solved_display_item *a, struct pkg_solved_display_item *b)
923 : : {
924 : :
925 : 180 : return (pkg_namecmp(a->new, b->new));
926 : : }
927 : :
928 : : int
929 : 305 : print_jobs_summary(struct pkg_jobs *jobs, const char *msg, ...)
930 : : {
931 : : struct pkg *new_pkg, *old_pkg;
932 : 305 : void *iter = NULL;
933 : : char size[8];
934 : : va_list ap;
935 : 305 : int type, displayed = 0;
936 : : int64_t dlsize, oldsize, newsize;
937 : : struct pkg_solved_display_item *disp[PKG_DISPLAY_MAX], *cur, *tmp;
938 : 305 : bool first = true;
939 : : size_t bytes_change, limbytes;
940 : : struct jobs_sum_number sum;
941 : :
942 : 305 : dlsize = oldsize = newsize = 0;
943 : 305 : type = pkg_jobs_type(jobs);
944 : 305 : memset(disp, 0, sizeof(disp));
945 : 305 : memset(&sum, 0, sizeof(sum));
946 : :
947 : 305 : nbtodl = 0;
948 [ + + ]: 826 : while (pkg_jobs_iter(jobs, &iter, &new_pkg, &old_pkg, &type)) {
949 : 1042 : set_jobs_summary_pkg(jobs, new_pkg, old_pkg, type, &oldsize,
950 : 521 : &newsize, &dlsize, disp, &sum);
951 : : }
952 : :
953 [ + + ]: 2440 : for (type = 0; type < PKG_DISPLAY_MAX; type ++) {
954 [ + + ]: 2135 : if (disp[type] != NULL) {
955 : : /* Space between each section. */
956 [ + + ]: 381 : if (!first)
957 : 76 : puts("");
958 : : else
959 : 305 : first = false;
960 [ + + ]: 381 : if (msg != NULL) {
961 : 305 : va_start(ap, msg);
962 : 305 : vprintf(msg, ap);
963 : 305 : va_end(ap);
964 : 305 : fflush(stdout);
965 : 305 : msg = NULL;
966 : 305 : }
967 : 381 : printf("%s:\n", pkg_display_messages[type]);
968 [ - + + + : 2152 : DL_SORT(disp[type], namecmp);
+ + + + +
+ + + + +
+ + + + +
+ + + + +
+ + + + ]
969 [ + + + + ]: 902 : DL_FOREACH_SAFE(disp[type], cur, tmp) {
970 : 521 : display_summary_item(cur, dlsize);
971 : 521 : displayed ++;
972 : 521 : free(cur);
973 : 521 : }
974 : 381 : }
975 : 2135 : }
976 : :
977 : 305 : limbytes = pkg_object_int(pkg_config_get("WARN_SIZE_LIMIT"));
978 : 305 : bytes_change = (size_t)llabs(newsize - oldsize);
979 : :
980 : 305 : puts("");
981 [ + + ]: 305 : if (sum.delete > 0) {
982 : 137 : printf("Number of packages to be removed: %d\n", sum.delete);
983 : 137 : }
984 [ + + ]: 305 : if (sum.install > 0) {
985 : 116 : printf("Number of packages to be installed: %d\n", sum.install);
986 : 116 : }
987 [ + + ]: 305 : if (sum.upgrade > 0) {
988 : 95 : printf("Number of packages to be upgraded: %d\n", sum.upgrade);
989 : 95 : }
990 [ + + ]: 305 : if (sum.reinstall > 0) {
991 : 33 : printf("Number of packages to be reinstalled: %d\n",
992 : 33 : sum.reinstall);
993 : 33 : }
994 [ + - ]: 305 : if (sum.downgrade > 0) {
995 : 0 : printf("Number of packages to be downgraded: %d\n",
996 : 0 : sum.downgrade);
997 : 0 : }
998 [ + - ]: 305 : if (sum.fetch > 0) {
999 : 0 : printf("Number of packages to be fetched: %d\n", sum.fetch);
1000 : 0 : }
1001 : : /* Add an extra line before the size output. */
1002 [ + - + + ]: 305 : if (bytes_change > limbytes || dlsize)
1003 : 4 : puts("");
1004 : :
1005 [ + - ]: 305 : if (bytes_change > limbytes) {
1006 [ # # ]: 0 : if (oldsize > newsize) {
1007 : 0 : humanize_number(size, sizeof(size), oldsize - newsize, "B",
1008 : : HN_AUTOSCALE, HN_IEC_PREFIXES);
1009 : 0 : printf("The operation will free %s.\n", size);
1010 [ # # ]: 0 : } else if (newsize > oldsize) {
1011 : 0 : humanize_number(size, sizeof(size), newsize - oldsize, "B",
1012 : : HN_AUTOSCALE, HN_IEC_PREFIXES);
1013 : 0 : printf("The process will require %s more space.\n", size);
1014 : 0 : }
1015 : 0 : }
1016 : :
1017 [ + + ]: 305 : if (dlsize > 0) {
1018 : 4 : humanize_number(size, sizeof(size), dlsize, "B",
1019 : : HN_AUTOSCALE, HN_IEC_PREFIXES);
1020 : 4 : printf("%s to be downloaded.\n", size);
1021 : 4 : }
1022 : :
1023 : 305 : return (displayed);
1024 : : }
1025 : :
1026 : : void
1027 : 355 : drop_privileges(void)
1028 : : {
1029 : : struct passwd *nobody;
1030 : :
1031 [ + - ]: 355 : if (geteuid() == 0) {
1032 : 0 : nobody = getpwnam("nobody");
1033 [ # # ]: 0 : if (nobody == NULL)
1034 : 0 : errx(EXIT_FAILURE, "Unable to drop privileges: no 'nobody' user");
1035 : 0 : setgroups(1, &nobody->pw_gid);
1036 : : /* setgid also sets egid and setuid also sets euid */
1037 [ # # ]: 0 : if (setgid(nobody->pw_gid) == -1)
1038 : 0 : err(EXIT_FAILURE, "Unable to setgid");
1039 [ # # ]: 0 : if (setuid(nobody->pw_uid) == -1)
1040 : 0 : err(EXIT_FAILURE, "Unable to setuid");
1041 : 0 : }
1042 : 355 : }
1043 : :
1044 : : int
1045 : 4 : print_pkg(struct pkg *p, void *ctx)
1046 : : {
1047 : : const char *name;
1048 : 4 : int *counter = ctx;
1049 : :
1050 : 4 : pkg_get(p, PKG_NAME, &name);
1051 : 4 : printf("\t%s\n", name);
1052 : 4 : (*counter)++;
1053 : :
1054 : 4 : return 0;
1055 : : }
|