Don't null-check handle lists before setting
[pacman-ng.git] / lib / libalpm / handle.c
blob2d6766a538d25318b0ea9d2478dcbc3d9cab66b8
1 /*
2 * handle.c
4 * Copyright (c) 2006-2011 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>
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.
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.
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/>.
23 #include "config.h"
25 #include <stdlib.h>
26 #include <string.h>
27 #include <limits.h>
28 #include <sys/types.h>
29 #include <syslog.h>
30 #include <sys/stat.h>
32 /* libalpm */
33 #include "handle.h"
34 #include "alpm_list.h"
35 #include "util.h"
36 #include "log.h"
37 #include "trans.h"
38 #include "alpm.h"
40 /* global var for handle (private to libalpm) */
41 pmhandle_t *handle = NULL;
43 pmhandle_t *_alpm_handle_new()
45 pmhandle_t *handle;
47 ALPM_LOG_FUNC;
49 CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL));
51 handle->sigverify = PM_PGP_VERIFY_OPTIONAL;
53 return handle;
56 void _alpm_handle_free(pmhandle_t *handle)
58 ALPM_LOG_FUNC;
60 if(handle == NULL) {
61 return;
64 /* close logfile */
65 if(handle->logstream) {
66 fclose(handle->logstream);
67 handle->logstream= NULL;
69 if(handle->usesyslog) {
70 handle->usesyslog = 0;
71 closelog();
74 #ifdef HAVE_LIBCURL
75 /* release curl handle */
76 curl_easy_cleanup(handle->curl);
77 #endif
79 /* free memory */
80 _alpm_trans_free(handle->trans);
81 FREE(handle->root);
82 FREE(handle->dbpath);
83 FREELIST(handle->cachedirs);
84 FREE(handle->logfile);
85 FREE(handle->lockfile);
86 FREE(handle->arch);
87 FREE(handle->signaturedir);
88 FREELIST(handle->dbs_sync);
89 FREELIST(handle->noupgrade);
90 FREELIST(handle->noextract);
91 FREELIST(handle->ignorepkg);
92 FREELIST(handle->ignoregrp);
93 FREE(handle);
97 alpm_cb_log SYMEXPORT alpm_option_get_logcb()
99 if(handle == NULL) {
100 pm_errno = PM_ERR_HANDLE_NULL;
101 return NULL;
103 return handle->logcb;
106 alpm_cb_download SYMEXPORT alpm_option_get_dlcb()
108 if(handle == NULL) {
109 pm_errno = PM_ERR_HANDLE_NULL;
110 return NULL;
112 return handle->dlcb;
115 alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb()
117 if(handle == NULL) {
118 pm_errno = PM_ERR_HANDLE_NULL;
119 return NULL;
121 return handle->fetchcb;
124 alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb()
126 if(handle == NULL) {
127 pm_errno = PM_ERR_HANDLE_NULL;
128 return NULL;
130 return handle->totaldlcb;
133 const char SYMEXPORT *alpm_option_get_root()
135 if(handle == NULL) {
136 pm_errno = PM_ERR_HANDLE_NULL;
137 return NULL;
139 return handle->root;
142 const char SYMEXPORT *alpm_option_get_dbpath()
144 if(handle == NULL) {
145 pm_errno = PM_ERR_HANDLE_NULL;
146 return NULL;
148 return handle->dbpath;
151 alpm_list_t SYMEXPORT *alpm_option_get_cachedirs()
153 if(handle == NULL) {
154 pm_errno = PM_ERR_HANDLE_NULL;
155 return NULL;
157 return handle->cachedirs;
160 const char SYMEXPORT *alpm_option_get_logfile()
162 if(handle == NULL) {
163 pm_errno = PM_ERR_HANDLE_NULL;
164 return NULL;
166 return handle->logfile;
169 const char SYMEXPORT *alpm_option_get_lockfile()
171 if(handle == NULL) {
172 pm_errno = PM_ERR_HANDLE_NULL;
173 return NULL;
175 return handle->lockfile;
178 const char SYMEXPORT *alpm_option_get_signaturedir()
180 if(handle == NULL) {
181 pm_errno = PM_ERR_HANDLE_NULL;
182 return NULL;
184 return handle->signaturedir;
187 int SYMEXPORT alpm_option_get_usesyslog()
189 if(handle == NULL) {
190 pm_errno = PM_ERR_HANDLE_NULL;
191 return -1;
193 return handle->usesyslog;
196 alpm_list_t SYMEXPORT *alpm_option_get_noupgrades()
198 if(handle == NULL) {
199 pm_errno = PM_ERR_HANDLE_NULL;
200 return NULL;
202 return handle->noupgrade;
205 alpm_list_t SYMEXPORT *alpm_option_get_noextracts()
207 if(handle == NULL) {
208 pm_errno = PM_ERR_HANDLE_NULL;
209 return NULL;
211 return handle->noextract;
214 alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs()
216 if(handle == NULL) {
217 pm_errno = PM_ERR_HANDLE_NULL;
218 return NULL;
220 return handle->ignorepkg;
223 alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps()
225 if(handle == NULL) {
226 pm_errno = PM_ERR_HANDLE_NULL;
227 return NULL;
229 return handle->ignoregrp;
232 const char SYMEXPORT *alpm_option_get_arch()
234 if(handle == NULL) {
235 pm_errno = PM_ERR_HANDLE_NULL;
236 return NULL;
238 return handle->arch;
241 int SYMEXPORT alpm_option_get_usedelta()
243 if(handle == NULL) {
244 pm_errno = PM_ERR_HANDLE_NULL;
245 return -1;
247 return handle->usedelta;
250 int SYMEXPORT alpm_option_get_checkspace()
252 if(handle == NULL) {
253 pm_errno = PM_ERR_HANDLE_NULL;
254 return -1;
256 return handle->checkspace;
259 pmdb_t SYMEXPORT *alpm_option_get_localdb()
261 if(handle == NULL) {
262 pm_errno = PM_ERR_HANDLE_NULL;
263 return NULL;
265 return handle->db_local;
268 alpm_list_t SYMEXPORT *alpm_option_get_syncdbs()
270 if(handle == NULL) {
271 pm_errno = PM_ERR_HANDLE_NULL;
272 return NULL;
274 return handle->dbs_sync;
277 int SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb)
279 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
280 handle->logcb = cb;
281 return 0;
284 int SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb)
286 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
287 handle->dlcb = cb;
288 return 0;
291 int SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb)
293 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
294 handle->fetchcb = cb;
295 return 0;
298 int SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb)
300 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
301 handle->totaldlcb = cb;
302 return 0;
305 int SYMEXPORT alpm_option_set_root(const char *root)
307 struct stat st;
308 char *realroot;
309 size_t rootlen;
311 ALPM_LOG_FUNC;
313 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
315 if(!root) {
316 pm_errno = PM_ERR_WRONG_ARGS;
317 return -1;
319 if(stat(root, &st) == -1 || !S_ISDIR(st.st_mode)) {
320 pm_errno = PM_ERR_NOT_A_DIR;
321 return -1;
324 realroot = calloc(PATH_MAX+1, sizeof(char));
325 if(!realpath(root, realroot)) {
326 FREE(realroot);
327 pm_errno = PM_ERR_NOT_A_DIR;
328 return -1;
331 /* verify root ends in a '/' */
332 rootlen = strlen(realroot);
333 if(realroot[rootlen-1] != '/') {
334 rootlen += 1;
336 if(handle->root) {
337 FREE(handle->root);
339 handle->root = calloc(rootlen + 1, sizeof(char));
340 strncpy(handle->root, realroot, rootlen);
341 handle->root[rootlen-1] = '/';
342 FREE(realroot);
343 _alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root);
344 return 0;
347 int SYMEXPORT alpm_option_set_dbpath(const char *dbpath)
349 struct stat st;
350 size_t dbpathlen, lockfilelen;
351 const char *lf = "db.lck";
353 ALPM_LOG_FUNC;
355 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
356 if(!dbpath) {
357 pm_errno = PM_ERR_WRONG_ARGS;
358 return -1;
360 if(stat(dbpath, &st) == -1 || !S_ISDIR(st.st_mode)) {
361 pm_errno = PM_ERR_NOT_A_DIR;
362 return -1;
364 /* verify dbpath ends in a '/' */
365 dbpathlen = strlen(dbpath);
366 if(dbpath[dbpathlen-1] != '/') {
367 dbpathlen += 1;
369 if(handle->dbpath) {
370 FREE(handle->dbpath);
372 handle->dbpath = calloc(dbpathlen+1, sizeof(char));
373 strncpy(handle->dbpath, dbpath, dbpathlen);
374 handle->dbpath[dbpathlen-1] = '/';
375 _alpm_log(PM_LOG_DEBUG, "option 'dbpath' = %s\n", handle->dbpath);
377 if(handle->lockfile) {
378 FREE(handle->lockfile);
380 lockfilelen = strlen(handle->dbpath) + strlen(lf) + 1;
381 handle->lockfile = calloc(lockfilelen, sizeof(char));
382 snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf);
383 _alpm_log(PM_LOG_DEBUG, "option 'lockfile' = %s\n", handle->lockfile);
384 return 0;
387 int SYMEXPORT alpm_option_add_cachedir(const char *cachedir)
389 char *newcachedir;
390 size_t cachedirlen;
392 ALPM_LOG_FUNC;
394 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
395 if(!cachedir) {
396 pm_errno = PM_ERR_WRONG_ARGS;
397 return -1;
399 /* don't stat the cachedir yet, as it may not even be needed. we can
400 * fail later if it is needed and the path is invalid. */
402 /* verify cachedir ends in a '/' */
403 cachedirlen = strlen(cachedir);
404 if(cachedir[cachedirlen-1] != '/') {
405 cachedirlen += 1;
407 newcachedir = calloc(cachedirlen + 1, sizeof(char));
408 strncpy(newcachedir, cachedir, cachedirlen);
409 newcachedir[cachedirlen-1] = '/';
410 handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir);
411 _alpm_log(PM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir);
412 return 0;
415 int SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs)
417 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
418 if(handle->cachedirs) FREELIST(handle->cachedirs);
419 handle->cachedirs = cachedirs;
420 return 0;
423 int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir)
425 char *vdata = NULL;
426 char *newcachedir;
427 size_t cachedirlen;
428 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
429 /* verify cachedir ends in a '/' */
430 cachedirlen = strlen(cachedir);
431 if(cachedir[cachedirlen-1] != '/') {
432 cachedirlen += 1;
434 newcachedir = calloc(cachedirlen + 1, sizeof(char));
435 strncpy(newcachedir, cachedir, cachedirlen);
436 newcachedir[cachedirlen-1] = '/';
437 handle->cachedirs = alpm_list_remove_str(handle->cachedirs, newcachedir, &vdata);
438 FREE(newcachedir);
439 if(vdata != NULL) {
440 FREE(vdata);
441 return 1;
443 return 0;
446 int SYMEXPORT alpm_option_set_logfile(const char *logfile)
448 char *oldlogfile = handle->logfile;
450 ALPM_LOG_FUNC;
452 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
453 if(!logfile) {
454 pm_errno = PM_ERR_WRONG_ARGS;
455 return -1;
458 handle->logfile = strdup(logfile);
460 /* free the old logfile path string, and close the stream so logaction
461 * will reopen a new stream on the new logfile */
462 if(oldlogfile) {
463 FREE(oldlogfile);
465 if(handle->logstream) {
466 fclose(handle->logstream);
467 handle->logstream = NULL;
469 _alpm_log(PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile);
470 return 0;
473 int SYMEXPORT alpm_option_set_signaturedir(const char *signaturedir)
475 ALPM_LOG_FUNC;
477 if(!signaturedir) {
478 pm_errno = PM_ERR_WRONG_ARGS;
479 return -1;
482 if(handle->signaturedir) {
483 FREE(handle->signaturedir);
485 handle->signaturedir = strdup(signaturedir);
487 _alpm_log(PM_LOG_DEBUG, "option 'signaturedir' = %s\n", handle->signaturedir);
488 return 0;
491 int SYMEXPORT alpm_option_set_usesyslog(int usesyslog)
493 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
494 handle->usesyslog = usesyslog;
495 return 0;
498 int SYMEXPORT alpm_option_add_noupgrade(const char *pkg)
500 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
501 handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg));
502 return 0;
505 int SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade)
507 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
508 if(handle->noupgrade) FREELIST(handle->noupgrade);
509 handle->noupgrade = noupgrade;
510 return 0;
513 int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg)
515 char *vdata = NULL;
516 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
517 handle->noupgrade = alpm_list_remove_str(handle->noupgrade, pkg, &vdata);
518 if(vdata != NULL) {
519 FREE(vdata);
520 return 1;
522 return 0;
525 int SYMEXPORT alpm_option_add_noextract(const char *pkg)
527 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
528 handle->noextract = alpm_list_add(handle->noextract, strdup(pkg));
529 return 0;
532 int SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract)
534 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
535 if(handle->noextract) FREELIST(handle->noextract);
536 handle->noextract = noextract;
537 return 0;
540 int SYMEXPORT alpm_option_remove_noextract(const char *pkg)
542 char *vdata = NULL;
543 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
544 handle->noextract = alpm_list_remove_str(handle->noextract, pkg, &vdata);
545 if(vdata != NULL) {
546 FREE(vdata);
547 return 1;
549 return 0;
552 int SYMEXPORT alpm_option_add_ignorepkg(const char *pkg)
554 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
555 handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg));
556 return 0;
559 int SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs)
561 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
562 if(handle->ignorepkg) FREELIST(handle->ignorepkg);
563 handle->ignorepkg = ignorepkgs;
564 return 0;
567 int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg)
569 char *vdata = NULL;
570 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
571 handle->ignorepkg = alpm_list_remove_str(handle->ignorepkg, pkg, &vdata);
572 if(vdata != NULL) {
573 FREE(vdata);
574 return 1;
576 return 0;
579 int SYMEXPORT alpm_option_add_ignoregrp(const char *grp)
581 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
582 handle->ignoregrp = alpm_list_add(handle->ignoregrp, strdup(grp));
583 return 0;
586 int SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps)
588 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
589 if(handle->ignoregrp) FREELIST(handle->ignoregrp);
590 handle->ignoregrp = ignoregrps;
591 return 0;
594 int SYMEXPORT alpm_option_remove_ignoregrp(const char *grp)
596 char *vdata = NULL;
597 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
598 handle->ignoregrp = alpm_list_remove_str(handle->ignoregrp, grp, &vdata);
599 if(vdata != NULL) {
600 FREE(vdata);
601 return 1;
603 return 0;
606 int SYMEXPORT alpm_option_set_arch(const char *arch)
608 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
609 if(handle->arch) FREE(handle->arch);
610 if(arch) {
611 handle->arch = strdup(arch);
612 } else {
613 handle->arch = NULL;
615 return 0;
618 int SYMEXPORT alpm_option_set_usedelta(int usedelta)
620 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
621 handle->usedelta = usedelta;
622 return 0;
625 int SYMEXPORT alpm_option_set_checkspace(int checkspace)
627 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
628 handle->checkspace = checkspace;
629 return 0;
632 int SYMEXPORT alpm_option_set_default_sigverify(pgp_verify_t level)
634 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
635 ASSERT(level != PM_PGP_VERIFY_UNKNOWN, RET_ERR(PM_ERR_WRONG_ARGS, -1));
636 handle->sigverify = level;
637 return 0;
640 pgp_verify_t SYMEXPORT alpm_option_get_default_sigverify()
642 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, PM_PGP_VERIFY_UNKNOWN));
643 return handle->sigverify;
646 /* vim: set ts=2 sw=2 noet: */