]> git.ipfire.org Git - people/ms/pakfire.git/blame_incremental - src/cli/lib/update.c
cli: Check for root privileges when needed
[people/ms/pakfire.git] / src / cli / lib / update.c
... / ...
CommitLineData
1/*#############################################################################
2# #
3# Pakfire - The IPFire package management system #
4# Copyright (C) 2023 Pakfire development team #
5# #
6# This program is free software: you can redistribute it and/or modify #
7# it under the terms of the GNU General Public License as published by #
8# the Free Software Foundation, either version 3 of the License, or #
9# (at your option) any later version. #
10# #
11# This program is distributed in the hope that it will be useful, #
12# but WITHOUT ANY WARRANTY; without even the implied warranty of #
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14# GNU General Public License for more details. #
15# #
16# You should have received a copy of the GNU General Public License #
17# along with this program. If not, see <http://www.gnu.org/licenses/>. #
18# #
19#############################################################################*/
20
21#include <argp.h>
22
23#include <pakfire/pakfire.h>
24
25#include "command.h"
26#include "pakfire.h"
27#include "transaction.h"
28#include "update.h"
29
30static const char* args_doc = "update [OPTIONS...] PACKAGES...";
31
32static const char* doc = "Update packages";
33
34#define MAX_EXCLUDES 128
35#define MAX_PACKAGES 128
36
37struct config {
38 int transaction_flags;
39
40 // Excludes
41 char* excludes[MAX_EXCLUDES];
42 unsigned int num_excludes;
43
44 // Packages
45 char* packages[MAX_PACKAGES];
46 unsigned int num_packages;
47};
48
49enum {
50 OPT_ALLOW_DOWNGRADE = 1,
51 OPT_ALLOW_UNINSTALL = 2,
52};
53
54static struct argp_option options[] = {
55 { "allow-downgrade", OPT_ALLOW_DOWNGRADE, NULL, 0, "Allow downgrading packages", 0 },
56 { "allow-uninstall", OPT_ALLOW_UNINSTALL, NULL, 0, "Allow uninstalling packages", 0 },
57 { "exclude", 'x', "PACKAGE", 0, "Exclude a package from being updated", 0 },
58 { NULL },
59};
60
61static error_t parse(int key, char* arg, struct argp_state* state, void* data) {
62 struct config* config = data;
63
64 switch (key) {
65 case OPT_ALLOW_DOWNGRADE:
66 config->transaction_flags |= PAKFIRE_TRANSACTION_ALLOW_DOWNGRADE;
67 break;
68
69 case OPT_ALLOW_UNINSTALL:
70 config->transaction_flags |= PAKFIRE_TRANSACTION_ALLOW_UNINSTALL;
71 break;
72
73 case 'x':
74 if (config->num_excludes >= MAX_EXCLUDES)
75 return -ENOBUFS;
76
77 config->excludes[config->num_excludes++] = arg;
78 break;
79
80 case ARGP_KEY_ARG:
81 if (config->num_packages >= MAX_PACKAGES)
82 return -ENOBUFS;
83
84 config->packages[config->num_packages++] = arg;
85 break;
86
87 default:
88 return ARGP_ERR_UNKNOWN;
89 }
90
91 return 0;
92}
93
94static int __cli_update(struct pakfire_transaction* transaction, int argc, char* argv[], void* data) {
95 struct config* config = (struct config*)data;
96 int r;
97
98 // Exclude any packages
99 for (unsigned int i = 0; i < config->num_excludes; i++) {
100 r = pakfire_transaction_request(transaction, PAKFIRE_JOB_LOCK, config->excludes[i], 0);
101 if (r)
102 return r;
103 }
104
105 // Did the user pass any packages?
106 if (argc) {
107 // Add the remaining command line options as packages
108 for (unsigned int i = 0; i < config->num_packages; i++) {
109 r = pakfire_transaction_request(transaction,
110 PAKFIRE_JOB_UPDATE, config->packages[i], 0);
111 if (r) {
112 fprintf(stderr, "Could not find '%s': %m\n", argv[i]);
113 return r;
114 }
115 }
116
117 // Otherwise update everything
118 } else {
119 r = pakfire_transaction_request(transaction, PAKFIRE_JOB_UPDATE_ALL, NULL, 0);
120 if (r)
121 return r;
122 }
123
124 return 0;
125}
126
127int cli_update(void* data, int argc, char* argv[]) {
128 struct pakfire* pakfire = NULL;
129 struct config config = {};
130 int r;
131
132 struct cli_config* cli_config = data;
133
134 // Parse the command line
135 r = cli_parse(options, NULL, args_doc, doc, parse, 0, argc, argv, &config);
136 if (r)
137 goto ERROR;
138
139 // Setup Pakfire
140 r = cli_setup_pakfire(&pakfire, cli_config);
141 if (r)
142 goto ERROR;
143
144 r = cli_transaction(pakfire, argc, argv, config.transaction_flags, __cli_update, &config);
145
146ERROR:
147 if (pakfire)
148 pakfire_unref(pakfire);
149
150 return r;
151}