1 /*
2 * handle.c
3 *
4 * Copyright (c) 2006-2018 Pacman Development Team <pacman-dev@archlinux.org>
5 * Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
6 * Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
7 * Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include <errno.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <limits.h>
27 #include <sys/types.h>
28 #include <syslog.h>
29 #include <sys/stat.h>
30 #include <fcntl.h>
31
32 /* libalpm */
33 #include "handle.h"
34 #include "alpm_list.h"
35 #include "util.h"
36 #include "log.h"
37 #include "delta.h"
38 #include "trans.h"
39 #include "alpm.h"
40 #include "deps.h"
41
_alpm_handle_new(void)42 alpm_handle_t *_alpm_handle_new(void)
43 {
44 alpm_handle_t *handle;
45
46 CALLOC(handle, 1, sizeof(alpm_handle_t), return NULL);
47 handle->deltaratio = 0.0;
48 handle->lockfd = -1;
49
50 return handle;
51 }
52
_alpm_handle_free(alpm_handle_t * handle)53 void _alpm_handle_free(alpm_handle_t *handle)
54 {
55 if(handle == NULL) {
56 return;
57 }
58
59 /* close logfile */
60 if(handle->logstream) {
61 fclose(handle->logstream);
62 handle->logstream = NULL;
63 }
64 if(handle->usesyslog) {
65 handle->usesyslog = 0;
66 closelog();
67 }
68
69 #ifdef HAVE_LIBCURL
70 /* release curl handle */
71 curl_easy_cleanup(handle->curl);
72 #endif
73
74 #ifdef HAVE_LIBGPGME
75 FREELIST(handle->known_keys);
76 #endif
77
78 regfree(&handle->delta_regex);
79
80 /* free memory */
81 _alpm_trans_free(handle->trans);
82 FREE(handle->root);
83 FREE(handle->dbpath);
84 FREE(handle->dbext);
85 FREELIST(handle->cachedirs);
86 FREELIST(handle->hookdirs);
87 FREE(handle->logfile);
88 FREE(handle->lockfile);
89 FREE(handle->arch);
90 FREE(handle->gpgdir);
91 FREELIST(handle->noupgrade);
92 FREELIST(handle->noextract);
93 FREELIST(handle->ignorepkg);
94 FREELIST(handle->ignoregroup);
95 FREELIST(handle->overwrite_files);
96
97 alpm_list_free_inner(handle->assumeinstalled, (alpm_list_fn_free)alpm_dep_free);
98 alpm_list_free(handle->assumeinstalled);
99
100 FREE(handle);
101 }
102
103 /** Lock the database */
_alpm_handle_lock(alpm_handle_t * handle)104 int _alpm_handle_lock(alpm_handle_t *handle)
105 {
106 char *dir, *ptr;
107
108 ASSERT(handle->lockfile != NULL, return -1);
109 ASSERT(handle->lockfd < 0, return 0);
110
111 /* create the dir of the lockfile first */
112 dir = strdup(handle->lockfile);
113 ptr = strrchr(dir, '/');
114 if(ptr) {
115 *ptr = '\0';
116 }
117 if(_alpm_makepath(dir)) {
118 FREE(dir);
119 return -1;
120 }
121 FREE(dir);
122
123 do {
124 handle->lockfd = open(handle->lockfile, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, 0000);
125 } while(handle->lockfd == -1 && errno == EINTR);
126
127 return (handle->lockfd >= 0 ? 0 : -1);
128 }
129
130 /** Remove the database lock file
131 * @param handle the context handle
132 * @return 0 on success, -1 on error
133 *
134 * @note Safe to call from inside signal handlers.
135 */
alpm_unlock(alpm_handle_t * handle)136 int SYMEXPORT alpm_unlock(alpm_handle_t *handle)
137 {
138 ASSERT(handle != NULL, return -1);
139 ASSERT(handle->lockfile != NULL, return 0);
140 ASSERT(handle->lockfd >= 0, return 0);
141
142 close(handle->lockfd);
143 handle->lockfd = -1;
144
145 if(unlink(handle->lockfile) != 0) {
146 RET_ERR_ASYNC_SAFE(handle, ALPM_ERR_SYSTEM, -1);
147 } else {
148 return 0;
149 }
150 }
151
_alpm_handle_unlock(alpm_handle_t * handle)152 int _alpm_handle_unlock(alpm_handle_t *handle)
153 {
154 if(alpm_unlock(handle) != 0) {
155 if(errno == ENOENT) {
156 _alpm_log(handle, ALPM_LOG_WARNING,
157 _("lock file missing %s\n"), handle->lockfile);
158 alpm_logaction(handle, ALPM_CALLER_PREFIX,
159 "warning: lock file missing %s\n", handle->lockfile);
160 return 0;
161 } else {
162 _alpm_log(handle, ALPM_LOG_WARNING,
163 _("could not remove lock file %s\n"), handle->lockfile);
164 alpm_logaction(handle, ALPM_CALLER_PREFIX,
165 "warning: could not remove lock file %s\n", handle->lockfile);
166 return -1;
167 }
168 }
169
170 return 0;
171 }
172
173
alpm_option_get_logcb(alpm_handle_t * handle)174 alpm_cb_log SYMEXPORT alpm_option_get_logcb(alpm_handle_t *handle)
175 {
176 CHECK_HANDLE(handle, return NULL);
177 return handle->logcb;
178 }
179
alpm_option_get_dlcb(alpm_handle_t * handle)180 alpm_cb_download SYMEXPORT alpm_option_get_dlcb(alpm_handle_t *handle)
181 {
182 CHECK_HANDLE(handle, return NULL);
183 return handle->dlcb;
184 }
185
alpm_option_get_fetchcb(alpm_handle_t * handle)186 alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb(alpm_handle_t *handle)
187 {
188 CHECK_HANDLE(handle, return NULL);
189 return handle->fetchcb;
190 }
191
alpm_option_get_totaldlcb(alpm_handle_t * handle)192 alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb(alpm_handle_t *handle)
193 {
194 CHECK_HANDLE(handle, return NULL);
195 return handle->totaldlcb;
196 }
197
alpm_option_get_eventcb(alpm_handle_t * handle)198 alpm_cb_event SYMEXPORT alpm_option_get_eventcb(alpm_handle_t *handle)
199 {
200 CHECK_HANDLE(handle, return NULL);
201 return handle->eventcb;
202 }
203
alpm_option_get_questioncb(alpm_handle_t * handle)204 alpm_cb_question SYMEXPORT alpm_option_get_questioncb(alpm_handle_t *handle)
205 {
206 CHECK_HANDLE(handle, return NULL);
207 return handle->questioncb;
208 }
209
alpm_option_get_progresscb(alpm_handle_t * handle)210 alpm_cb_progress SYMEXPORT alpm_option_get_progresscb(alpm_handle_t *handle)
211 {
212 CHECK_HANDLE(handle, return NULL);
213 return handle->progresscb;
214 }
215
alpm_option_get_root(alpm_handle_t * handle)216 const char SYMEXPORT *alpm_option_get_root(alpm_handle_t *handle)
217 {
218 CHECK_HANDLE(handle, return NULL);
219 return handle->root;
220 }
221
alpm_option_get_dbpath(alpm_handle_t * handle)222 const char SYMEXPORT *alpm_option_get_dbpath(alpm_handle_t *handle)
223 {
224 CHECK_HANDLE(handle, return NULL);
225 return handle->dbpath;
226 }
227
alpm_option_get_hookdirs(alpm_handle_t * handle)228 alpm_list_t SYMEXPORT *alpm_option_get_hookdirs(alpm_handle_t *handle)
229 {
230 CHECK_HANDLE(handle, return NULL);
231 return handle->hookdirs;
232 }
233
alpm_option_get_cachedirs(alpm_handle_t * handle)234 alpm_list_t SYMEXPORT *alpm_option_get_cachedirs(alpm_handle_t *handle)
235 {
236 CHECK_HANDLE(handle, return NULL);
237 return handle->cachedirs;
238 }
239
alpm_option_get_logfile(alpm_handle_t * handle)240 const char SYMEXPORT *alpm_option_get_logfile(alpm_handle_t *handle)
241 {
242 CHECK_HANDLE(handle, return NULL);
243 return handle->logfile;
244 }
245
alpm_option_get_lockfile(alpm_handle_t * handle)246 const char SYMEXPORT *alpm_option_get_lockfile(alpm_handle_t *handle)
247 {
248 CHECK_HANDLE(handle, return NULL);
249 return handle->lockfile;
250 }
251
alpm_option_get_gpgdir(alpm_handle_t * handle)252 const char SYMEXPORT *alpm_option_get_gpgdir(alpm_handle_t *handle)
253 {
254 CHECK_HANDLE(handle, return NULL);
255 return handle->gpgdir;
256 }
257
alpm_option_get_usesyslog(alpm_handle_t * handle)258 int SYMEXPORT alpm_option_get_usesyslog(alpm_handle_t *handle)
259 {
260 CHECK_HANDLE(handle, return -1);
261 return handle->usesyslog;
262 }
263
alpm_option_get_noupgrades(alpm_handle_t * handle)264 alpm_list_t SYMEXPORT *alpm_option_get_noupgrades(alpm_handle_t *handle)
265 {
266 CHECK_HANDLE(handle, return NULL);
267 return handle->noupgrade;
268 }
269
alpm_option_get_noextracts(alpm_handle_t * handle)270 alpm_list_t SYMEXPORT *alpm_option_get_noextracts(alpm_handle_t *handle)
271 {
272 CHECK_HANDLE(handle, return NULL);
273 return handle->noextract;
274 }
275
alpm_option_get_ignorepkgs(alpm_handle_t * handle)276 alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs(alpm_handle_t *handle)
277 {
278 CHECK_HANDLE(handle, return NULL);
279 return handle->ignorepkg;
280 }
281
alpm_option_get_ignoregroups(alpm_handle_t * handle)282 alpm_list_t SYMEXPORT *alpm_option_get_ignoregroups(alpm_handle_t *handle)
283 {
284 CHECK_HANDLE(handle, return NULL);
285 return handle->ignoregroup;
286 }
287
alpm_option_get_overwrite_files(alpm_handle_t * handle)288 alpm_list_t SYMEXPORT *alpm_option_get_overwrite_files(alpm_handle_t *handle)
289 {
290 CHECK_HANDLE(handle, return NULL);
291 return handle->overwrite_files;
292 }
293
alpm_option_get_assumeinstalled(alpm_handle_t * handle)294 alpm_list_t SYMEXPORT *alpm_option_get_assumeinstalled(alpm_handle_t *handle)
295 {
296 CHECK_HANDLE(handle, return NULL);
297 return handle->assumeinstalled;
298 }
299
alpm_option_get_arch(alpm_handle_t * handle)300 const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle)
301 {
302 CHECK_HANDLE(handle, return NULL);
303 return handle->arch;
304 }
305
alpm_option_get_deltaratio(alpm_handle_t * handle)306 double SYMEXPORT alpm_option_get_deltaratio(alpm_handle_t *handle)
307 {
308 CHECK_HANDLE(handle, return -1);
309 return handle->deltaratio;
310 }
311
alpm_option_get_checkspace(alpm_handle_t * handle)312 int SYMEXPORT alpm_option_get_checkspace(alpm_handle_t *handle)
313 {
314 CHECK_HANDLE(handle, return -1);
315 return handle->checkspace;
316 }
317
alpm_option_get_dbext(alpm_handle_t * handle)318 const char SYMEXPORT *alpm_option_get_dbext(alpm_handle_t *handle)
319 {
320 CHECK_HANDLE(handle, return NULL);
321 return handle->dbext;
322 }
323
alpm_option_set_logcb(alpm_handle_t * handle,alpm_cb_log cb)324 int SYMEXPORT alpm_option_set_logcb(alpm_handle_t *handle, alpm_cb_log cb)
325 {
326 CHECK_HANDLE(handle, return -1);
327 handle->logcb = cb;
328 return 0;
329 }
330
alpm_option_set_dlcb(alpm_handle_t * handle,alpm_cb_download cb)331 int SYMEXPORT alpm_option_set_dlcb(alpm_handle_t *handle, alpm_cb_download cb)
332 {
333 CHECK_HANDLE(handle, return -1);
334 handle->dlcb = cb;
335 return 0;
336 }
337
alpm_option_set_fetchcb(alpm_handle_t * handle,alpm_cb_fetch cb)338 int SYMEXPORT alpm_option_set_fetchcb(alpm_handle_t *handle, alpm_cb_fetch cb)
339 {
340 CHECK_HANDLE(handle, return -1);
341 handle->fetchcb = cb;
342 return 0;
343 }
344
alpm_option_set_totaldlcb(alpm_handle_t * handle,alpm_cb_totaldl cb)345 int SYMEXPORT alpm_option_set_totaldlcb(alpm_handle_t *handle, alpm_cb_totaldl cb)
346 {
347 CHECK_HANDLE(handle, return -1);
348 handle->totaldlcb = cb;
349 return 0;
350 }
351
alpm_option_set_eventcb(alpm_handle_t * handle,alpm_cb_event cb)352 int SYMEXPORT alpm_option_set_eventcb(alpm_handle_t *handle, alpm_cb_event cb)
353 {
354 CHECK_HANDLE(handle, return -1);
355 handle->eventcb = cb;
356 return 0;
357 }
358
alpm_option_set_questioncb(alpm_handle_t * handle,alpm_cb_question cb)359 int SYMEXPORT alpm_option_set_questioncb(alpm_handle_t *handle, alpm_cb_question cb)
360 {
361 CHECK_HANDLE(handle, return -1);
362 handle->questioncb = cb;
363 return 0;
364 }
365
alpm_option_set_progresscb(alpm_handle_t * handle,alpm_cb_progress cb)366 int SYMEXPORT alpm_option_set_progresscb(alpm_handle_t *handle, alpm_cb_progress cb)
367 {
368 CHECK_HANDLE(handle, return -1);
369 handle->progresscb = cb;
370 return 0;
371 }
372
canonicalize_path(const char * path)373 static char *canonicalize_path(const char *path)
374 {
375 char *new_path;
376 size_t len;
377
378 /* verify path ends in a '/' */
379 len = strlen(path);
380 if(path[len - 1] != '/') {
381 len += 1;
382 }
383 CALLOC(new_path, len + 1, sizeof(char), return NULL);
384 strcpy(new_path, path);
385 new_path[len - 1] = '/';
386 return new_path;
387 }
388
_alpm_set_directory_option(const char * value,char ** storage,int must_exist)389 alpm_errno_t _alpm_set_directory_option(const char *value,
390 char **storage, int must_exist)
391 {
392 struct stat st;
393 char real[PATH_MAX];
394 const char *path;
395
396 path = value;
397 if(!path) {
398 return ALPM_ERR_WRONG_ARGS;
399 }
400 if(must_exist) {
401 if(stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) {
402 return ALPM_ERR_NOT_A_DIR;
403 }
404 if(!realpath(path, real)) {
405 return ALPM_ERR_NOT_A_DIR;
406 }
407 path = real;
408 }
409
410 if(*storage) {
411 FREE(*storage);
412 }
413 *storage = canonicalize_path(path);
414 if(!*storage) {
415 return ALPM_ERR_MEMORY;
416 }
417 return 0;
418 }
419
alpm_option_add_hookdir(alpm_handle_t * handle,const char * hookdir)420 int SYMEXPORT alpm_option_add_hookdir(alpm_handle_t *handle, const char *hookdir)
421 {
422 char *newhookdir;
423
424 CHECK_HANDLE(handle, return -1);
425 ASSERT(hookdir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
426
427 newhookdir = canonicalize_path(hookdir);
428 if(!newhookdir) {
429 RET_ERR(handle, ALPM_ERR_MEMORY, -1);
430 }
431 handle->hookdirs = alpm_list_add(handle->hookdirs, newhookdir);
432 _alpm_log(handle, ALPM_LOG_DEBUG, "option 'hookdir' = %s\n", newhookdir);
433 return 0;
434 }
435
alpm_option_set_hookdirs(alpm_handle_t * handle,alpm_list_t * hookdirs)436 int SYMEXPORT alpm_option_set_hookdirs(alpm_handle_t *handle, alpm_list_t *hookdirs)
437 {
438 alpm_list_t *i;
439 CHECK_HANDLE(handle, return -1);
440 if(handle->hookdirs) {
441 FREELIST(handle->hookdirs);
442 }
443 for(i = hookdirs; i; i = i->next) {
444 int ret = alpm_option_add_hookdir(handle, i->data);
445 if(ret) {
446 return ret;
447 }
448 }
449 return 0;
450 }
451
alpm_option_remove_hookdir(alpm_handle_t * handle,const char * hookdir)452 int SYMEXPORT alpm_option_remove_hookdir(alpm_handle_t *handle, const char *hookdir)
453 {
454 char *vdata = NULL;
455 char *newhookdir;
456 CHECK_HANDLE(handle, return -1);
457 ASSERT(hookdir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
458
459 newhookdir = canonicalize_path(hookdir);
460 if(!newhookdir) {
461 RET_ERR(handle, ALPM_ERR_MEMORY, -1);
462 }
463 handle->hookdirs = alpm_list_remove_str(handle->hookdirs, newhookdir, &vdata);
464 FREE(newhookdir);
465 if(vdata != NULL) {
466 FREE(vdata);
467 return 1;
468 }
469 return 0;
470 }
471
alpm_option_add_cachedir(alpm_handle_t * handle,const char * cachedir)472 int SYMEXPORT alpm_option_add_cachedir(alpm_handle_t *handle, const char *cachedir)
473 {
474 char *newcachedir;
475
476 CHECK_HANDLE(handle, return -1);
477 ASSERT(cachedir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
478 /* don't stat the cachedir yet, as it may not even be needed. we can
479 * fail later if it is needed and the path is invalid. */
480
481 newcachedir = canonicalize_path(cachedir);
482 if(!newcachedir) {
483 RET_ERR(handle, ALPM_ERR_MEMORY, -1);
484 }
485 handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir);
486 _alpm_log(handle, ALPM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir);
487 return 0;
488 }
489
alpm_option_set_cachedirs(alpm_handle_t * handle,alpm_list_t * cachedirs)490 int SYMEXPORT alpm_option_set_cachedirs(alpm_handle_t *handle, alpm_list_t *cachedirs)
491 {
492 alpm_list_t *i;
493 CHECK_HANDLE(handle, return -1);
494 if(handle->cachedirs) {
495 FREELIST(handle->cachedirs);
496 }
497 for(i = cachedirs; i; i = i->next) {
498 int ret = alpm_option_add_cachedir(handle, i->data);
499 if(ret) {
500 return ret;
501 }
502 }
503 return 0;
504 }
505
alpm_option_remove_cachedir(alpm_handle_t * handle,const char * cachedir)506 int SYMEXPORT alpm_option_remove_cachedir(alpm_handle_t *handle, const char *cachedir)
507 {
508 char *vdata = NULL;
509 char *newcachedir;
510 CHECK_HANDLE(handle, return -1);
511 ASSERT(cachedir != NULL, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
512
513 newcachedir = canonicalize_path(cachedir);
514 if(!newcachedir) {
515 RET_ERR(handle, ALPM_ERR_MEMORY, -1);
516 }
517 handle->cachedirs = alpm_list_remove_str(handle->cachedirs, newcachedir, &vdata);
518 FREE(newcachedir);
519 if(vdata != NULL) {
520 FREE(vdata);
521 return 1;
522 }
523 return 0;
524 }
525
alpm_option_set_logfile(alpm_handle_t * handle,const char * logfile)526 int SYMEXPORT alpm_option_set_logfile(alpm_handle_t *handle, const char *logfile)
527 {
528 char *oldlogfile = handle->logfile;
529
530 CHECK_HANDLE(handle, return -1);
531 if(!logfile) {
532 handle->pm_errno = ALPM_ERR_WRONG_ARGS;
533 return -1;
534 }
535
536 STRDUP(handle->logfile, logfile, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
537
538 /* free the old logfile path string, and close the stream so logaction
539 * will reopen a new stream on the new logfile */
540 if(oldlogfile) {
541 FREE(oldlogfile);
542 }
543 if(handle->logstream) {
544 fclose(handle->logstream);
545 handle->logstream = NULL;
546 }
547 _alpm_log(handle, ALPM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile);
548 return 0;
549 }
550
alpm_option_set_gpgdir(alpm_handle_t * handle,const char * gpgdir)551 int SYMEXPORT alpm_option_set_gpgdir(alpm_handle_t *handle, const char *gpgdir)
552 {
553 int err;
554 CHECK_HANDLE(handle, return -1);
555 if((err = _alpm_set_directory_option(gpgdir, &(handle->gpgdir), 0))) {
556 RET_ERR(handle, err, -1);
557 }
558 _alpm_log(handle, ALPM_LOG_DEBUG, "option 'gpgdir' = %s\n", handle->gpgdir);
559 return 0;
560 }
561
alpm_option_set_usesyslog(alpm_handle_t * handle,int usesyslog)562 int SYMEXPORT alpm_option_set_usesyslog(alpm_handle_t *handle, int usesyslog)
563 {
564 CHECK_HANDLE(handle, return -1);
565 handle->usesyslog = usesyslog;
566 return 0;
567 }
568
_alpm_option_strlist_add(alpm_handle_t * handle,alpm_list_t ** list,const char * str)569 static int _alpm_option_strlist_add(alpm_handle_t *handle, alpm_list_t **list, const char *str)
570 {
571 char *dup;
572 CHECK_HANDLE(handle, return -1);
573 STRDUP(dup, str, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
574 *list = alpm_list_add(*list, dup);
575 return 0;
576 }
577
_alpm_option_strlist_set(alpm_handle_t * handle,alpm_list_t ** list,alpm_list_t * newlist)578 static int _alpm_option_strlist_set(alpm_handle_t *handle, alpm_list_t **list, alpm_list_t *newlist)
579 {
580 CHECK_HANDLE(handle, return -1);
581 FREELIST(*list);
582 *list = alpm_list_strdup(newlist);
583 return 0;
584 }
585
_alpm_option_strlist_rem(alpm_handle_t * handle,alpm_list_t ** list,const char * str)586 static int _alpm_option_strlist_rem(alpm_handle_t *handle, alpm_list_t **list, const char *str)
587 {
588 char *vdata = NULL;
589 CHECK_HANDLE(handle, return -1);
590 *list = alpm_list_remove_str(*list, str, &vdata);
591 if(vdata != NULL) {
592 FREE(vdata);
593 return 1;
594 }
595 return 0;
596 }
597
alpm_option_add_noupgrade(alpm_handle_t * handle,const char * pkg)598 int SYMEXPORT alpm_option_add_noupgrade(alpm_handle_t *handle, const char *pkg)
599 {
600 return _alpm_option_strlist_add(handle, &(handle->noupgrade), pkg);
601 }
602
alpm_option_set_noupgrades(alpm_handle_t * handle,alpm_list_t * noupgrade)603 int SYMEXPORT alpm_option_set_noupgrades(alpm_handle_t *handle, alpm_list_t *noupgrade)
604 {
605 return _alpm_option_strlist_set(handle, &(handle->noupgrade), noupgrade);
606 }
607
alpm_option_remove_noupgrade(alpm_handle_t * handle,const char * pkg)608 int SYMEXPORT alpm_option_remove_noupgrade(alpm_handle_t *handle, const char *pkg)
609 {
610 return _alpm_option_strlist_rem(handle, &(handle->noupgrade), pkg);
611 }
612
alpm_option_match_noupgrade(alpm_handle_t * handle,const char * path)613 int SYMEXPORT alpm_option_match_noupgrade(alpm_handle_t *handle, const char *path)
614 {
615 return _alpm_fnmatch_patterns(handle->noupgrade, path);
616 }
617
alpm_option_add_noextract(alpm_handle_t * handle,const char * path)618 int SYMEXPORT alpm_option_add_noextract(alpm_handle_t *handle, const char *path)
619 {
620 return _alpm_option_strlist_add(handle, &(handle->noextract), path);
621 }
622
alpm_option_set_noextracts(alpm_handle_t * handle,alpm_list_t * noextract)623 int SYMEXPORT alpm_option_set_noextracts(alpm_handle_t *handle, alpm_list_t *noextract)
624 {
625 return _alpm_option_strlist_set(handle, &(handle->noextract), noextract);
626 }
627
alpm_option_remove_noextract(alpm_handle_t * handle,const char * path)628 int SYMEXPORT alpm_option_remove_noextract(alpm_handle_t *handle, const char *path)
629 {
630 return _alpm_option_strlist_rem(handle, &(handle->noextract), path);
631 }
632
alpm_option_match_noextract(alpm_handle_t * handle,const char * path)633 int SYMEXPORT alpm_option_match_noextract(alpm_handle_t *handle, const char *path)
634 {
635 return _alpm_fnmatch_patterns(handle->noextract, path);
636 }
637
alpm_option_add_ignorepkg(alpm_handle_t * handle,const char * pkg)638 int SYMEXPORT alpm_option_add_ignorepkg(alpm_handle_t *handle, const char *pkg)
639 {
640 return _alpm_option_strlist_add(handle, &(handle->ignorepkg), pkg);
641 }
642
alpm_option_set_ignorepkgs(alpm_handle_t * handle,alpm_list_t * ignorepkgs)643 int SYMEXPORT alpm_option_set_ignorepkgs(alpm_handle_t *handle, alpm_list_t *ignorepkgs)
644 {
645 return _alpm_option_strlist_set(handle, &(handle->ignorepkg), ignorepkgs);
646 }
647
alpm_option_remove_ignorepkg(alpm_handle_t * handle,const char * pkg)648 int SYMEXPORT alpm_option_remove_ignorepkg(alpm_handle_t *handle, const char *pkg)
649 {
650 return _alpm_option_strlist_rem(handle, &(handle->ignorepkg), pkg);
651 }
652
alpm_option_add_ignoregroup(alpm_handle_t * handle,const char * grp)653 int SYMEXPORT alpm_option_add_ignoregroup(alpm_handle_t *handle, const char *grp)
654 {
655 return _alpm_option_strlist_add(handle, &(handle->ignoregroup), grp);
656 }
657
alpm_option_set_ignoregroups(alpm_handle_t * handle,alpm_list_t * ignoregrps)658 int SYMEXPORT alpm_option_set_ignoregroups(alpm_handle_t *handle, alpm_list_t *ignoregrps)
659 {
660 return _alpm_option_strlist_set(handle, &(handle->ignoregroup), ignoregrps);
661 }
662
alpm_option_remove_ignoregroup(alpm_handle_t * handle,const char * grp)663 int SYMEXPORT alpm_option_remove_ignoregroup(alpm_handle_t *handle, const char *grp)
664 {
665 return _alpm_option_strlist_rem(handle, &(handle->ignoregroup), grp);
666 }
667
alpm_option_add_overwrite_file(alpm_handle_t * handle,const char * glob)668 int SYMEXPORT alpm_option_add_overwrite_file(alpm_handle_t *handle, const char *glob)
669 {
670 return _alpm_option_strlist_add(handle, &(handle->overwrite_files), glob);
671 }
672
alpm_option_set_overwrite_files(alpm_handle_t * handle,alpm_list_t * globs)673 int SYMEXPORT alpm_option_set_overwrite_files(alpm_handle_t *handle, alpm_list_t *globs)
674 {
675 return _alpm_option_strlist_set(handle, &(handle->overwrite_files), globs);
676 }
677
alpm_option_remove_overwrite_file(alpm_handle_t * handle,const char * glob)678 int SYMEXPORT alpm_option_remove_overwrite_file(alpm_handle_t *handle, const char *glob)
679 {
680 return _alpm_option_strlist_rem(handle, &(handle->overwrite_files), glob);
681 }
682
alpm_option_add_assumeinstalled(alpm_handle_t * handle,const alpm_depend_t * dep)683 int SYMEXPORT alpm_option_add_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep)
684 {
685 alpm_depend_t *depcpy;
686 CHECK_HANDLE(handle, return -1);
687 ASSERT(dep->mod == ALPM_DEP_MOD_EQ || dep->mod == ALPM_DEP_MOD_ANY,
688 RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
689 ASSERT((depcpy = _alpm_dep_dup(dep)), RET_ERR(handle, ALPM_ERR_MEMORY, -1));
690
691 /* fill in name_hash in case dep was built by hand */
692 depcpy->name_hash = _alpm_hash_sdbm(dep->name);
693 handle->assumeinstalled = alpm_list_add(handle->assumeinstalled, depcpy);
694 return 0;
695 }
696
alpm_option_set_assumeinstalled(alpm_handle_t * handle,alpm_list_t * deps)697 int SYMEXPORT alpm_option_set_assumeinstalled(alpm_handle_t *handle, alpm_list_t *deps)
698 {
699 CHECK_HANDLE(handle, return -1);
700 if(handle->assumeinstalled) {
701 alpm_list_free_inner(handle->assumeinstalled, (alpm_list_fn_free)alpm_dep_free);
702 alpm_list_free(handle->assumeinstalled);
703 }
704 while(deps) {
705 if(alpm_option_add_assumeinstalled(handle, deps->data) != 0) {
706 return -1;
707 }
708 deps = deps->next;
709 }
710 return 0;
711 }
712
assumeinstalled_cmp(const void * d1,const void * d2)713 static int assumeinstalled_cmp(const void *d1, const void *d2)
714 {
715 const alpm_depend_t *dep1 = d1;
716 const alpm_depend_t *dep2 = d2;
717
718 if(dep1->name_hash != dep2->name_hash
719 || strcmp(dep1->name, dep2->name) != 0) {
720 return -1;
721 }
722
723 if(dep1->version && dep2->version
724 && strcmp(dep1->version, dep2->version) == 0) {
725 return 0;
726 }
727
728 if(dep1->version == NULL && dep2->version == NULL) {
729 return 0;
730 }
731
732
733 return -1;
734 }
735
alpm_option_remove_assumeinstalled(alpm_handle_t * handle,const alpm_depend_t * dep)736 int SYMEXPORT alpm_option_remove_assumeinstalled(alpm_handle_t *handle, const alpm_depend_t *dep)
737 {
738 alpm_depend_t *vdata = NULL;
739 CHECK_HANDLE(handle, return -1);
740
741 handle->assumeinstalled = alpm_list_remove(handle->assumeinstalled, dep, &assumeinstalled_cmp, (void **)&vdata);
742 if(vdata != NULL) {
743 alpm_dep_free(vdata);
744 return 1;
745 }
746
747 return 0;
748 }
749
alpm_option_set_arch(alpm_handle_t * handle,const char * arch)750 int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch)
751 {
752 CHECK_HANDLE(handle, return -1);
753 if(handle->arch) FREE(handle->arch);
754 STRDUP(handle->arch, arch, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
755 return 0;
756 }
757
alpm_option_set_deltaratio(alpm_handle_t * handle,double ratio)758 int SYMEXPORT alpm_option_set_deltaratio(alpm_handle_t *handle, double ratio)
759 {
760 CHECK_HANDLE(handle, return -1);
761 if(ratio < 0.0 || ratio > 2.0) {
762 RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
763 }
764 handle->deltaratio = ratio;
765 return 0;
766 }
767
alpm_get_localdb(alpm_handle_t * handle)768 alpm_db_t SYMEXPORT *alpm_get_localdb(alpm_handle_t *handle)
769 {
770 CHECK_HANDLE(handle, return NULL);
771 return handle->db_local;
772 }
773
alpm_get_syncdbs(alpm_handle_t * handle)774 alpm_list_t SYMEXPORT *alpm_get_syncdbs(alpm_handle_t *handle)
775 {
776 CHECK_HANDLE(handle, return NULL);
777 return handle->dbs_sync;
778 }
779
alpm_option_set_checkspace(alpm_handle_t * handle,int checkspace)780 int SYMEXPORT alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace)
781 {
782 CHECK_HANDLE(handle, return -1);
783 handle->checkspace = checkspace;
784 return 0;
785 }
786
alpm_option_set_dbext(alpm_handle_t * handle,const char * dbext)787 int SYMEXPORT alpm_option_set_dbext(alpm_handle_t *handle, const char *dbext)
788 {
789 CHECK_HANDLE(handle, return -1);
790 ASSERT(dbext, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1));
791
792 if(handle->dbext) {
793 FREE(handle->dbext);
794 }
795
796 STRDUP(handle->dbext, dbext, RET_ERR(handle, ALPM_ERR_MEMORY, -1));
797
798 _alpm_log(handle, ALPM_LOG_DEBUG, "option 'dbext' = %s\n", handle->dbext);
799 return 0;
800 }
801
alpm_option_set_default_siglevel(alpm_handle_t * handle,int level)802 int SYMEXPORT alpm_option_set_default_siglevel(alpm_handle_t *handle,
803 int level)
804 {
805 CHECK_HANDLE(handle, return -1);
806 #ifdef HAVE_LIBGPGME
807 handle->siglevel = level;
808 #else
809 if(level != 0 && level != ALPM_SIG_USE_DEFAULT) {
810 RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
811 }
812 #endif
813 return 0;
814 }
815
alpm_option_get_default_siglevel(alpm_handle_t * handle)816 int SYMEXPORT alpm_option_get_default_siglevel(alpm_handle_t *handle)
817 {
818 CHECK_HANDLE(handle, return -1);
819 return handle->siglevel;
820 }
821
alpm_option_set_local_file_siglevel(alpm_handle_t * handle,int level)822 int SYMEXPORT alpm_option_set_local_file_siglevel(alpm_handle_t *handle,
823 int level)
824 {
825 CHECK_HANDLE(handle, return -1);
826 #ifdef HAVE_LIBGPGME
827 handle->localfilesiglevel = level;
828 #else
829 if(level != 0 && level != ALPM_SIG_USE_DEFAULT) {
830 RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
831 }
832 #endif
833 return 0;
834 }
835
alpm_option_get_local_file_siglevel(alpm_handle_t * handle)836 int SYMEXPORT alpm_option_get_local_file_siglevel(alpm_handle_t *handle)
837 {
838 CHECK_HANDLE(handle, return -1);
839 if(handle->localfilesiglevel & ALPM_SIG_USE_DEFAULT) {
840 return handle->siglevel;
841 } else {
842 return handle->localfilesiglevel;
843 }
844 }
845
alpm_option_set_remote_file_siglevel(alpm_handle_t * handle,int level)846 int SYMEXPORT alpm_option_set_remote_file_siglevel(alpm_handle_t *handle,
847 int level)
848 {
849 CHECK_HANDLE(handle, return -1);
850 #ifdef HAVE_LIBGPGME
851 handle->remotefilesiglevel = level;
852 #else
853 if(level != 0 && level != ALPM_SIG_USE_DEFAULT) {
854 RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
855 }
856 #endif
857 return 0;
858 }
859
alpm_option_get_remote_file_siglevel(alpm_handle_t * handle)860 int SYMEXPORT alpm_option_get_remote_file_siglevel(alpm_handle_t *handle)
861 {
862 CHECK_HANDLE(handle, return -1);
863 if(handle->remotefilesiglevel & ALPM_SIG_USE_DEFAULT) {
864 return handle->siglevel;
865 } else {
866 return handle->remotefilesiglevel;
867 }
868 }
869
alpm_option_set_disable_dl_timeout(alpm_handle_t * handle,unsigned short disable_dl_timeout)870 int SYMEXPORT alpm_option_set_disable_dl_timeout(alpm_handle_t *handle,
871 unsigned short disable_dl_timeout)
872 {
873 CHECK_HANDLE(handle, return -1);
874 #ifdef HAVE_LIBCURL
875 handle->disable_dl_timeout = disable_dl_timeout;
876 #endif
877 return 0;
878 }
879