Be consistent with memory treatment for plural option setters
[pacman-ng.git] / lib / libalpm / handle.c
blob68a65cefeb0b832a418822234e4e912d75d9b336
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 CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL));
49 handle->sigverify = PM_PGP_VERIFY_OPTIONAL;
51 return handle;
54 void _alpm_handle_free(pmhandle_t *handle)
56 if(handle == NULL) {
57 return;
60 /* close logfile */
61 if(handle->logstream) {
62 fclose(handle->logstream);
63 handle->logstream= NULL;
65 if(handle->usesyslog) {
66 handle->usesyslog = 0;
67 closelog();
70 #ifdef HAVE_LIBCURL
71 /* release curl handle */
72 curl_easy_cleanup(handle->curl);
73 #endif
75 /* free memory */
76 _alpm_trans_free(handle->trans);
77 FREE(handle->root);
78 FREE(handle->dbpath);
79 FREELIST(handle->cachedirs);
80 FREE(handle->logfile);
81 FREE(handle->lockfile);
82 FREE(handle->arch);
83 FREE(handle->signaturedir);
84 FREELIST(handle->dbs_sync);
85 FREELIST(handle->noupgrade);
86 FREELIST(handle->noextract);
87 FREELIST(handle->ignorepkg);
88 FREELIST(handle->ignoregrp);
89 FREE(handle);
93 alpm_cb_log SYMEXPORT alpm_option_get_logcb()
95 if(handle == NULL) {
96 pm_errno = PM_ERR_HANDLE_NULL;
97 return NULL;
99 return handle->logcb;
102 alpm_cb_download SYMEXPORT alpm_option_get_dlcb()
104 if(handle == NULL) {
105 pm_errno = PM_ERR_HANDLE_NULL;
106 return NULL;
108 return handle->dlcb;
111 alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb()
113 if(handle == NULL) {
114 pm_errno = PM_ERR_HANDLE_NULL;
115 return NULL;
117 return handle->fetchcb;
120 alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb()
122 if(handle == NULL) {
123 pm_errno = PM_ERR_HANDLE_NULL;
124 return NULL;
126 return handle->totaldlcb;
129 const char SYMEXPORT *alpm_option_get_root()
131 if(handle == NULL) {
132 pm_errno = PM_ERR_HANDLE_NULL;
133 return NULL;
135 return handle->root;
138 const char SYMEXPORT *alpm_option_get_dbpath()
140 if(handle == NULL) {
141 pm_errno = PM_ERR_HANDLE_NULL;
142 return NULL;
144 return handle->dbpath;
147 alpm_list_t SYMEXPORT *alpm_option_get_cachedirs()
149 if(handle == NULL) {
150 pm_errno = PM_ERR_HANDLE_NULL;
151 return NULL;
153 return handle->cachedirs;
156 const char SYMEXPORT *alpm_option_get_logfile()
158 if(handle == NULL) {
159 pm_errno = PM_ERR_HANDLE_NULL;
160 return NULL;
162 return handle->logfile;
165 const char SYMEXPORT *alpm_option_get_lockfile()
167 if(handle == NULL) {
168 pm_errno = PM_ERR_HANDLE_NULL;
169 return NULL;
171 return handle->lockfile;
174 const char SYMEXPORT *alpm_option_get_signaturedir()
176 if(handle == NULL) {
177 pm_errno = PM_ERR_HANDLE_NULL;
178 return NULL;
180 return handle->signaturedir;
183 int SYMEXPORT alpm_option_get_usesyslog()
185 if(handle == NULL) {
186 pm_errno = PM_ERR_HANDLE_NULL;
187 return -1;
189 return handle->usesyslog;
192 alpm_list_t SYMEXPORT *alpm_option_get_noupgrades()
194 if(handle == NULL) {
195 pm_errno = PM_ERR_HANDLE_NULL;
196 return NULL;
198 return handle->noupgrade;
201 alpm_list_t SYMEXPORT *alpm_option_get_noextracts()
203 if(handle == NULL) {
204 pm_errno = PM_ERR_HANDLE_NULL;
205 return NULL;
207 return handle->noextract;
210 alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs()
212 if(handle == NULL) {
213 pm_errno = PM_ERR_HANDLE_NULL;
214 return NULL;
216 return handle->ignorepkg;
219 alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps()
221 if(handle == NULL) {
222 pm_errno = PM_ERR_HANDLE_NULL;
223 return NULL;
225 return handle->ignoregrp;
228 const char SYMEXPORT *alpm_option_get_arch()
230 if(handle == NULL) {
231 pm_errno = PM_ERR_HANDLE_NULL;
232 return NULL;
234 return handle->arch;
237 int SYMEXPORT alpm_option_get_usedelta()
239 if(handle == NULL) {
240 pm_errno = PM_ERR_HANDLE_NULL;
241 return -1;
243 return handle->usedelta;
246 int SYMEXPORT alpm_option_get_checkspace()
248 if(handle == NULL) {
249 pm_errno = PM_ERR_HANDLE_NULL;
250 return -1;
252 return handle->checkspace;
255 pmdb_t SYMEXPORT *alpm_option_get_localdb()
257 if(handle == NULL) {
258 pm_errno = PM_ERR_HANDLE_NULL;
259 return NULL;
261 return handle->db_local;
264 alpm_list_t SYMEXPORT *alpm_option_get_syncdbs()
266 if(handle == NULL) {
267 pm_errno = PM_ERR_HANDLE_NULL;
268 return NULL;
270 return handle->dbs_sync;
273 int SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb)
275 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
276 handle->logcb = cb;
277 return 0;
280 int SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb)
282 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
283 handle->dlcb = cb;
284 return 0;
287 int SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb)
289 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
290 handle->fetchcb = cb;
291 return 0;
294 int SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb)
296 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
297 handle->totaldlcb = cb;
298 return 0;
301 static char *canonicalize_path(const char *path) {
302 char *new_path;
303 size_t len;
305 /* verify path ends in a '/' */
306 len = strlen(path);
307 if(path[len - 1] != '/') {
308 len += 1;
310 new_path = calloc(len + 1, sizeof(char));
311 strncpy(new_path, path, len);
312 new_path[len - 1] = '/';
313 return new_path;
316 int _alpm_set_directory_option(const char *value,
317 char **storage, int must_exist)
319 struct stat st;
320 char *real = NULL;
321 const char *path;
323 path = value;
324 if(!path) {
325 pm_errno = PM_ERR_WRONG_ARGS;
326 return -1;
328 if(must_exist) {
329 if(stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) {
330 pm_errno = PM_ERR_NOT_A_DIR;
331 return -1;
333 real = calloc(PATH_MAX + 1, sizeof(char));
334 if(!realpath(path, real)) {
335 free(real);
336 pm_errno = PM_ERR_NOT_A_DIR;
337 return -1;
339 path = real;
342 if(*storage) {
343 FREE(*storage);
345 *storage = canonicalize_path(path);
346 free(real);
347 return 0;
350 int SYMEXPORT alpm_option_set_root(const char *root)
352 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
354 if(_alpm_set_directory_option(root, &(handle->root), 1)) {
355 return -1;
357 _alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root);
358 return 0;
361 int SYMEXPORT alpm_option_set_dbpath(const char *dbpath)
363 const char *lf = "db.lck";
364 size_t lockfilelen;
366 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
368 if(_alpm_set_directory_option(dbpath, &(handle->dbpath), 1)) {
369 return -1;
371 _alpm_log(PM_LOG_DEBUG, "option 'dbpath' = %s\n", handle->dbpath);
373 if(handle->lockfile) {
374 FREE(handle->lockfile);
376 lockfilelen = strlen(handle->dbpath) + strlen(lf) + 1;
377 handle->lockfile = calloc(lockfilelen, sizeof(char));
378 snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf);
379 _alpm_log(PM_LOG_DEBUG, "option 'lockfile' = %s\n", handle->lockfile);
380 return 0;
383 int SYMEXPORT alpm_option_add_cachedir(const char *cachedir)
385 char *newcachedir;
387 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
388 if(!cachedir) {
389 pm_errno = PM_ERR_WRONG_ARGS;
390 return -1;
392 /* don't stat the cachedir yet, as it may not even be needed. we can
393 * fail later if it is needed and the path is invalid. */
395 newcachedir = canonicalize_path(cachedir);
396 handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir);
397 _alpm_log(PM_LOG_DEBUG, "backend option 'cachedir' = %s\n", newcachedir);
398 return 0;
401 int SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs)
403 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
404 if(handle->cachedirs) FREELIST(handle->cachedirs);
405 handle->cachedirs = alpm_list_strdup(cachedirs);
406 return 0;
409 int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir)
411 char *vdata = NULL;
412 char *newcachedir;
413 size_t cachedirlen;
414 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
415 /* verify cachedir ends in a '/' */
416 cachedirlen = strlen(cachedir);
417 if(cachedir[cachedirlen-1] != '/') {
418 cachedirlen += 1;
420 newcachedir = calloc(cachedirlen + 1, sizeof(char));
421 strncpy(newcachedir, cachedir, cachedirlen);
422 newcachedir[cachedirlen-1] = '/';
423 handle->cachedirs = alpm_list_remove_str(handle->cachedirs, newcachedir, &vdata);
424 FREE(newcachedir);
425 if(vdata != NULL) {
426 FREE(vdata);
427 return 1;
429 return 0;
432 int SYMEXPORT alpm_option_set_logfile(const char *logfile)
434 char *oldlogfile = handle->logfile;
436 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
437 if(!logfile) {
438 pm_errno = PM_ERR_WRONG_ARGS;
439 return -1;
442 handle->logfile = strdup(logfile);
444 /* free the old logfile path string, and close the stream so logaction
445 * will reopen a new stream on the new logfile */
446 if(oldlogfile) {
447 FREE(oldlogfile);
449 if(handle->logstream) {
450 fclose(handle->logstream);
451 handle->logstream = NULL;
453 _alpm_log(PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile);
454 return 0;
457 int SYMEXPORT alpm_option_set_signaturedir(const char *signaturedir)
459 if(!signaturedir) {
460 pm_errno = PM_ERR_WRONG_ARGS;
461 return -1;
464 if(handle->signaturedir) {
465 FREE(handle->signaturedir);
467 handle->signaturedir = strdup(signaturedir);
469 _alpm_log(PM_LOG_DEBUG, "option 'signaturedir' = %s\n", handle->signaturedir);
470 return 0;
473 int SYMEXPORT alpm_option_set_usesyslog(int usesyslog)
475 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
476 handle->usesyslog = usesyslog;
477 return 0;
480 int SYMEXPORT alpm_option_add_noupgrade(const char *pkg)
482 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
483 handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg));
484 return 0;
487 int SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade)
489 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
490 if(handle->noupgrade) FREELIST(handle->noupgrade);
491 handle->noupgrade = alpm_list_strdup(noupgrade);
492 return 0;
495 int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg)
497 char *vdata = NULL;
498 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
499 handle->noupgrade = alpm_list_remove_str(handle->noupgrade, pkg, &vdata);
500 if(vdata != NULL) {
501 FREE(vdata);
502 return 1;
504 return 0;
507 int SYMEXPORT alpm_option_add_noextract(const char *pkg)
509 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
510 handle->noextract = alpm_list_add(handle->noextract, strdup(pkg));
511 return 0;
514 int SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract)
516 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
517 if(handle->noextract) FREELIST(handle->noextract);
518 handle->noextract = alpm_list_strdup(noextract);
519 return 0;
522 int SYMEXPORT alpm_option_remove_noextract(const char *pkg)
524 char *vdata = NULL;
525 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
526 handle->noextract = alpm_list_remove_str(handle->noextract, pkg, &vdata);
527 if(vdata != NULL) {
528 FREE(vdata);
529 return 1;
531 return 0;
534 int SYMEXPORT alpm_option_add_ignorepkg(const char *pkg)
536 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
537 handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg));
538 return 0;
541 int SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs)
543 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
544 if(handle->ignorepkg) FREELIST(handle->ignorepkg);
545 handle->ignorepkg = alpm_list_strdup(ignorepkgs);
546 return 0;
549 int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg)
551 char *vdata = NULL;
552 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
553 handle->ignorepkg = alpm_list_remove_str(handle->ignorepkg, pkg, &vdata);
554 if(vdata != NULL) {
555 FREE(vdata);
556 return 1;
558 return 0;
561 int SYMEXPORT alpm_option_add_ignoregrp(const char *grp)
563 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
564 handle->ignoregrp = alpm_list_add(handle->ignoregrp, strdup(grp));
565 return 0;
568 int SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps)
570 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
571 if(handle->ignoregrp) FREELIST(handle->ignoregrp);
572 handle->ignoregrp = alpm_list_strdup(ignoregrps);
573 return 0;
576 int SYMEXPORT alpm_option_remove_ignoregrp(const char *grp)
578 char *vdata = NULL;
579 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
580 handle->ignoregrp = alpm_list_remove_str(handle->ignoregrp, grp, &vdata);
581 if(vdata != NULL) {
582 FREE(vdata);
583 return 1;
585 return 0;
588 int SYMEXPORT alpm_option_set_arch(const char *arch)
590 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
591 if(handle->arch) FREE(handle->arch);
592 if(arch) {
593 handle->arch = strdup(arch);
594 } else {
595 handle->arch = NULL;
597 return 0;
600 int SYMEXPORT alpm_option_set_usedelta(int usedelta)
602 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
603 handle->usedelta = usedelta;
604 return 0;
607 int SYMEXPORT alpm_option_set_checkspace(int checkspace)
609 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
610 handle->checkspace = checkspace;
611 return 0;
614 int SYMEXPORT alpm_option_set_default_sigverify(pgp_verify_t level)
616 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
617 ASSERT(level != PM_PGP_VERIFY_UNKNOWN, RET_ERR(PM_ERR_WRONG_ARGS, -1));
618 handle->sigverify = level;
619 return 0;
622 pgp_verify_t SYMEXPORT alpm_option_get_default_sigverify()
624 ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, PM_PGP_VERIFY_UNKNOWN));
625 return handle->sigverify;
628 /* vim: set ts=2 sw=2 noet: */