1
0
mirror of https://github.com/moparisthebest/pacman synced 2024-08-13 17:03:46 -04:00
pacman/lib/libalpm/handle.c
Dan McGee fb4b422fc4 New signatures for alpm initialize and release
These new method signatures return and take handle objects to operate on
so we can move away from the idea of one global handle in the API. There
is also another important change and that deals with the setting of root
and dbpaths. These are now done at initialization time instead of using
setter methods. This allows the library to operate more safely knowing
that paths won't change underneath it.

Signed-off-by: Dan McGee <dan@archlinux.org>
2011-06-07 11:37:05 -05:00

601 lines
13 KiB
C

/*
* handle.c
*
* Copyright (c) 2006-2011 Pacman Development Team <pacman-dev@archlinux.org>
* Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org>
* Copyright (c) 2005 by Aurelien Foret <orelien@chez.com>
* Copyright (c) 2005, 2006 by Miklos Vajna <vmiklos@frugalware.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <syslog.h>
#include <sys/stat.h>
/* libalpm */
#include "handle.h"
#include "alpm_list.h"
#include "util.h"
#include "log.h"
#include "trans.h"
#include "alpm.h"
/* global var for handle (private to libalpm) */
pmhandle_t *handle = NULL;
pmhandle_t *_alpm_handle_new()
{
pmhandle_t *handle;
CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL));
handle->sigverify = PM_PGP_VERIFY_OPTIONAL;
return handle;
}
void _alpm_handle_free(pmhandle_t *handle)
{
if(handle == NULL) {
return;
}
/* close logfile */
if(handle->logstream) {
fclose(handle->logstream);
handle->logstream= NULL;
}
if(handle->usesyslog) {
handle->usesyslog = 0;
closelog();
}
#ifdef HAVE_LIBCURL
/* release curl handle */
curl_easy_cleanup(handle->curl);
#endif
/* free memory */
_alpm_trans_free(handle->trans);
FREE(handle->root);
FREE(handle->dbpath);
FREELIST(handle->cachedirs);
FREE(handle->logfile);
FREE(handle->lockfile);
FREE(handle->arch);
FREE(handle->signaturedir);
FREELIST(handle->dbs_sync);
FREELIST(handle->noupgrade);
FREELIST(handle->noextract);
FREELIST(handle->ignorepkg);
FREELIST(handle->ignoregrp);
FREE(handle);
}
alpm_cb_log SYMEXPORT alpm_option_get_logcb()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->logcb;
}
alpm_cb_download SYMEXPORT alpm_option_get_dlcb()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->dlcb;
}
alpm_cb_fetch SYMEXPORT alpm_option_get_fetchcb()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->fetchcb;
}
alpm_cb_totaldl SYMEXPORT alpm_option_get_totaldlcb()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->totaldlcb;
}
const char SYMEXPORT *alpm_option_get_root()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->root;
}
const char SYMEXPORT *alpm_option_get_dbpath()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->dbpath;
}
alpm_list_t SYMEXPORT *alpm_option_get_cachedirs()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->cachedirs;
}
const char SYMEXPORT *alpm_option_get_logfile()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->logfile;
}
const char SYMEXPORT *alpm_option_get_lockfile()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->lockfile;
}
const char SYMEXPORT *alpm_option_get_signaturedir()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->signaturedir;
}
int SYMEXPORT alpm_option_get_usesyslog()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return -1;
}
return handle->usesyslog;
}
alpm_list_t SYMEXPORT *alpm_option_get_noupgrades()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->noupgrade;
}
alpm_list_t SYMEXPORT *alpm_option_get_noextracts()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->noextract;
}
alpm_list_t SYMEXPORT *alpm_option_get_ignorepkgs()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->ignorepkg;
}
alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->ignoregrp;
}
const char SYMEXPORT *alpm_option_get_arch()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->arch;
}
int SYMEXPORT alpm_option_get_usedelta()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return -1;
}
return handle->usedelta;
}
int SYMEXPORT alpm_option_get_checkspace()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return -1;
}
return handle->checkspace;
}
pmdb_t SYMEXPORT *alpm_option_get_localdb()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->db_local;
}
alpm_list_t SYMEXPORT *alpm_option_get_syncdbs()
{
if(handle == NULL) {
pm_errno = PM_ERR_HANDLE_NULL;
return NULL;
}
return handle->dbs_sync;
}
int SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->logcb = cb;
return 0;
}
int SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->dlcb = cb;
return 0;
}
int SYMEXPORT alpm_option_set_fetchcb(alpm_cb_fetch cb)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->fetchcb = cb;
return 0;
}
int SYMEXPORT alpm_option_set_totaldlcb(alpm_cb_totaldl cb)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->totaldlcb = cb;
return 0;
}
static char *canonicalize_path(const char *path) {
char *new_path;
size_t len;
/* verify path ends in a '/' */
len = strlen(path);
if(path[len - 1] != '/') {
len += 1;
}
new_path = calloc(len + 1, sizeof(char));
strncpy(new_path, path, len);
new_path[len - 1] = '/';
return new_path;
}
enum _pmerrno_t _alpm_set_directory_option(const char *value,
char **storage, int must_exist)
{
struct stat st;
char *real = NULL;
const char *path;
path = value;
if(!path) {
return PM_ERR_WRONG_ARGS;
}
if(must_exist) {
if(stat(path, &st) == -1 || !S_ISDIR(st.st_mode)) {
return PM_ERR_NOT_A_DIR;
}
real = calloc(PATH_MAX + 1, sizeof(char));
if(!realpath(path, real)) {
free(real);
return PM_ERR_NOT_A_DIR;
}
path = real;
}
if(*storage) {
FREE(*storage);
}
*storage = canonicalize_path(path);
free(real);
return 0;
}
int SYMEXPORT alpm_option_add_cachedir(const char *cachedir)
{
char *newcachedir;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(!cachedir) {
pm_errno = PM_ERR_WRONG_ARGS;
return -1;
}
/* don't stat the cachedir yet, as it may not even be needed. we can
* fail later if it is needed and the path is invalid. */
newcachedir = canonicalize_path(cachedir);
handle->cachedirs = alpm_list_add(handle->cachedirs, newcachedir);
_alpm_log(PM_LOG_DEBUG, "backend option 'cachedir' = %s\n", newcachedir);
return 0;
}
int SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs)
{
alpm_list_t *i;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(handle->cachedirs) {
FREELIST(handle->cachedirs);
}
for(i = cachedirs; i; i = i->next) {
int ret = alpm_option_add_cachedir(i->data);
if(ret) {
return ret;
}
}
return 0;
}
int SYMEXPORT alpm_option_remove_cachedir(const char *cachedir)
{
char *vdata = NULL;
char *newcachedir;
size_t cachedirlen;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
/* verify cachedir ends in a '/' */
cachedirlen = strlen(cachedir);
if(cachedir[cachedirlen-1] != '/') {
cachedirlen += 1;
}
newcachedir = calloc(cachedirlen + 1, sizeof(char));
strncpy(newcachedir, cachedir, cachedirlen);
newcachedir[cachedirlen-1] = '/';
handle->cachedirs = alpm_list_remove_str(handle->cachedirs, newcachedir, &vdata);
FREE(newcachedir);
if(vdata != NULL) {
FREE(vdata);
return 1;
}
return 0;
}
int SYMEXPORT alpm_option_set_logfile(const char *logfile)
{
char *oldlogfile = handle->logfile;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(!logfile) {
pm_errno = PM_ERR_WRONG_ARGS;
return -1;
}
handle->logfile = strdup(logfile);
/* free the old logfile path string, and close the stream so logaction
* will reopen a new stream on the new logfile */
if(oldlogfile) {
FREE(oldlogfile);
}
if(handle->logstream) {
fclose(handle->logstream);
handle->logstream = NULL;
}
_alpm_log(PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile);
return 0;
}
int SYMEXPORT alpm_option_set_signaturedir(const char *signaturedir)
{
if(!signaturedir) {
pm_errno = PM_ERR_WRONG_ARGS;
return -1;
}
if(handle->signaturedir) {
FREE(handle->signaturedir);
}
handle->signaturedir = strdup(signaturedir);
_alpm_log(PM_LOG_DEBUG, "option 'signaturedir' = %s\n", handle->signaturedir);
return 0;
}
int SYMEXPORT alpm_option_set_usesyslog(int usesyslog)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->usesyslog = usesyslog;
return 0;
}
int SYMEXPORT alpm_option_add_noupgrade(const char *pkg)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg));
return 0;
}
int SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(handle->noupgrade) FREELIST(handle->noupgrade);
handle->noupgrade = alpm_list_strdup(noupgrade);
return 0;
}
int SYMEXPORT alpm_option_remove_noupgrade(const char *pkg)
{
char *vdata = NULL;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->noupgrade = alpm_list_remove_str(handle->noupgrade, pkg, &vdata);
if(vdata != NULL) {
FREE(vdata);
return 1;
}
return 0;
}
int SYMEXPORT alpm_option_add_noextract(const char *pkg)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->noextract = alpm_list_add(handle->noextract, strdup(pkg));
return 0;
}
int SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(handle->noextract) FREELIST(handle->noextract);
handle->noextract = alpm_list_strdup(noextract);
return 0;
}
int SYMEXPORT alpm_option_remove_noextract(const char *pkg)
{
char *vdata = NULL;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->noextract = alpm_list_remove_str(handle->noextract, pkg, &vdata);
if(vdata != NULL) {
FREE(vdata);
return 1;
}
return 0;
}
int SYMEXPORT alpm_option_add_ignorepkg(const char *pkg)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg));
return 0;
}
int SYMEXPORT alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(handle->ignorepkg) FREELIST(handle->ignorepkg);
handle->ignorepkg = alpm_list_strdup(ignorepkgs);
return 0;
}
int SYMEXPORT alpm_option_remove_ignorepkg(const char *pkg)
{
char *vdata = NULL;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->ignorepkg = alpm_list_remove_str(handle->ignorepkg, pkg, &vdata);
if(vdata != NULL) {
FREE(vdata);
return 1;
}
return 0;
}
int SYMEXPORT alpm_option_add_ignoregrp(const char *grp)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->ignoregrp = alpm_list_add(handle->ignoregrp, strdup(grp));
return 0;
}
int SYMEXPORT alpm_option_set_ignoregrps(alpm_list_t *ignoregrps)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(handle->ignoregrp) FREELIST(handle->ignoregrp);
handle->ignoregrp = alpm_list_strdup(ignoregrps);
return 0;
}
int SYMEXPORT alpm_option_remove_ignoregrp(const char *grp)
{
char *vdata = NULL;
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->ignoregrp = alpm_list_remove_str(handle->ignoregrp, grp, &vdata);
if(vdata != NULL) {
FREE(vdata);
return 1;
}
return 0;
}
int SYMEXPORT alpm_option_set_arch(const char *arch)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
if(handle->arch) FREE(handle->arch);
if(arch) {
handle->arch = strdup(arch);
} else {
handle->arch = NULL;
}
return 0;
}
int SYMEXPORT alpm_option_set_usedelta(int usedelta)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->usedelta = usedelta;
return 0;
}
int SYMEXPORT alpm_option_set_checkspace(int checkspace)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
handle->checkspace = checkspace;
return 0;
}
int SYMEXPORT alpm_option_set_default_sigverify(pgp_verify_t level)
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
ASSERT(level != PM_PGP_VERIFY_UNKNOWN, RET_ERR(PM_ERR_WRONG_ARGS, -1));
handle->sigverify = level;
return 0;
}
pgp_verify_t SYMEXPORT alpm_option_get_default_sigverify()
{
ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, PM_PGP_VERIFY_UNKNOWN));
return handle->sigverify;
}
/* vim: set ts=2 sw=2 noet: */