diff options
Diffstat (limited to 'lib/libalpm/handle.c')
-rw-r--r-- | lib/libalpm/handle.c | 483 |
1 files changed, 344 insertions, 139 deletions
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c index a6bb5bc8..755eefb3 100644 --- a/lib/libalpm/handle.c +++ b/lib/libalpm/handle.c @@ -1,10 +1,10 @@ /* * handle.c - * + * * 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 @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ @@ -29,8 +29,9 @@ #include <limits.h> #include <sys/types.h> #include <syslog.h> -#include <libintl.h> #include <time.h> +#include <sys/stat.h> +#include <errno.h> /* libalpm */ #include "handle.h" @@ -42,62 +43,44 @@ #include "alpm.h" #include "server.h" +/* global var for handle (private to libalpm) */ +pmhandle_t *handle = NULL; + pmhandle_t *_alpm_handle_new() { pmhandle_t *handle; - handle = (pmhandle_t *)malloc(sizeof(pmhandle_t)); - if(handle == NULL) { - _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(pmhandle_t)); - RET_ERR(PM_ERR_MEMORY, NULL); - } + ALPM_LOG_FUNC; + + CALLOC(handle, 1, sizeof(pmhandle_t), RET_ERR(PM_ERR_MEMORY, NULL)); - memset(handle, 0, sizeof(pmhandle_t)); handle->lckfd = -1; + handle->logstream = NULL; -#ifndef CYGWIN /* see if we're root or not */ handle->uid = geteuid(); -//#ifndef FAKEROOT -// if(!handle->uid && getenv("FAKEROOTKEY")) { -// /* fakeroot doesn't count, we're non-root */ -// handle->uid = 99; -// } -//#endif -// -// /* see if we're root or not (fakeroot does not count) */ -//#ifndef FAKEROOT -// if(handle->uid == 0 && !getenv("FAKEROOTKEY")) { -// /* } make vim indent work - stupid ifdef's */ -//#else -// if(handle->uid == 0) { -//#endif -// handle->access = PM_ACCESS_RW; -// } else { -// handle->access = PM_ACCESS_RO; -// } -//#else - handle->access = PM_ACCESS_RW; -#endif - - handle->root = strdup(PM_ROOT); - handle->dbpath = strdup(PM_DBPATH); - handle->cachedir = strdup(PM_CACHEDIR); - handle->logmask = PM_LOG_ERROR | PM_LOG_WARNING; + handle->root = NULL; + handle->dbpath = NULL; + handle->cachedirs = NULL; + handle->lockfile = NULL; + handle->logfile = NULL; + handle->usedelta = 0; return(handle); } -int _alpm_handle_free(pmhandle_t *handle) +void _alpm_handle_free(pmhandle_t *handle) { ALPM_LOG_FUNC; - ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); + if(handle == NULL) { + return; + } - /* close logfiles */ - if(handle->logfd) { - fclose(handle->logfd); - handle->logfd = NULL; + /* close logfile */ + if(handle->logstream) { + fclose(handle->logstream); + handle->logstream= NULL; } if(handle->usesyslog) { handle->usesyslog = 0; @@ -105,197 +88,419 @@ int _alpm_handle_free(pmhandle_t *handle) } /* free memory */ - FREETRANS(handle->trans); + _alpm_trans_free(handle->trans); FREE(handle->root); FREE(handle->dbpath); - FREE(handle->cachedir); + FREELIST(handle->cachedirs); FREE(handle->logfile); + FREE(handle->lockfile); FREE(handle->xfercommand); FREELIST(handle->dbs_sync); FREELIST(handle->noupgrade); FREELIST(handle->noextract); FREELIST(handle->ignorepkg); FREELIST(handle->holdpkg); + FREELIST(handle->ignoregrp); FREE(handle); +} - return(0); +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; +} + +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; +} + +unsigned short 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_holdpkgs() +{ + if (handle == NULL) { + pm_errno = PM_ERR_HANDLE_NULL; + return NULL; + } + return handle->holdpkg; +} + +alpm_list_t SYMEXPORT *alpm_option_get_ignoregrps() +{ + if (handle == NULL) { + pm_errno = PM_ERR_HANDLE_NULL; + return NULL; + } + return handle->ignoregrp; +} + +time_t SYMEXPORT alpm_option_get_upgradedelay() +{ + if (handle == NULL) { + pm_errno = PM_ERR_HANDLE_NULL; + return -1; + } + return handle->upgradedelay; +} + +const char SYMEXPORT *alpm_option_get_xfercommand() +{ + if (handle == NULL) { + pm_errno = PM_ERR_HANDLE_NULL; + return NULL; + } + return handle->xfercommand; +} + +unsigned short SYMEXPORT alpm_option_get_nopassiveftp() +{ + if (handle == NULL) { + pm_errno = PM_ERR_HANDLE_NULL; + return -1; + } + return handle->nopassiveftp; +} + +pmdb_t SYMEXPORT *alpm_option_get_localdb() +{ + if (handle == NULL) { + pm_errno = PM_ERR_HANDLE_NULL; + return NULL; + } + return handle->db_local; } -alpm_cb_log alpm_option_get_logcb() { return (handle ? handle->logcb : NULL); } -alpm_cb_download alpm_option_get_dlcb() { return (handle ? handle->dlcb : NULL); } -unsigned short SYMEXPORT alpm_option_get_logmask() { return handle->logmask; } -const char SYMEXPORT *alpm_option_get_root() { return handle->root; } -const char SYMEXPORT *alpm_option_get_dbpath() { return handle->dbpath; } -const char SYMEXPORT *alpm_option_get_cachedir() { return handle->cachedir; } -const char *alpm_option_get_logfile() { return handle->logfile; } -unsigned short alpm_option_get_usesyslog() { return handle->usesyslog; } -alpm_list_t *alpm_option_get_noupgrades() { return handle->noupgrade; } -alpm_list_t *alpm_option_get_noextracts() { return handle->noextract; } -alpm_list_t *alpm_option_get_ignorepkgs() { return handle->ignorepkg; } -alpm_list_t *alpm_option_get_holdpkgs() { return handle->holdpkg; } -time_t alpm_option_get_upgradedelay() { return handle->upgradedelay; } -const char *alpm_option_get_xfercommand() { return handle->xfercommand; } -unsigned short alpm_option_get_nopassiveftp() { return handle->nopassiveftp; } -unsigned short SYMEXPORT alpm_option_get_chomp() { return handle->chomp; } -unsigned short alpm_option_get_usecolor() { return handle->use_color; } - -pmdb_t SYMEXPORT *alpm_option_get_localdb() { 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; } -void SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb) { handle->logcb = cb; } - -void SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb) { handle->dlcb = cb; } +void SYMEXPORT alpm_option_set_logcb(alpm_cb_log cb) +{ + if (handle == NULL) { + pm_errno = PM_ERR_HANDLE_NULL; + return; + } + handle->logcb = cb; +} -void SYMEXPORT alpm_option_set_logmask(unsigned short mask) { handle->logmask = mask; } +void SYMEXPORT alpm_option_set_dlcb(alpm_cb_download cb) +{ + if (handle == NULL) { + pm_errno = PM_ERR_HANDLE_NULL; + return; + } + handle->dlcb = cb; +} -void SYMEXPORT alpm_option_set_root(const char *root) +int SYMEXPORT alpm_option_set_root(const char *root) { - if(handle->root) FREE(handle->root); - /* According to the man page, realpath is safe to use IFF the second arg is - * NULL. */ - char *realroot = realpath(root, NULL); - if(realroot) { - root = realroot; - } else { - _alpm_log(PM_LOG_ERROR, _("cannot canonicalize specified root path '%s'"), root); + struct stat st; + char *realroot; + size_t rootlen; + + ALPM_LOG_FUNC; + + if(!root) { + pm_errno = PM_ERR_WRONG_ARGS; + return(-1); + } + if(stat(root, &st) == -1 || !S_ISDIR(st.st_mode)) { + pm_errno = PM_ERR_NOT_A_DIR; + return(-1); } - if(root) { - /* verify root ends in a '/' */ - int rootlen = strlen(realroot); - if(realroot[rootlen-1] != '/') { - rootlen += 1; - } - handle->root = calloc(rootlen+1, sizeof(char)); - strncpy(handle->root, realroot, rootlen); - handle->root[rootlen-1] = '/'; - _alpm_log(PM_LOG_DEBUG, _("option 'root' = %s"), handle->root); + realroot = calloc(PATH_MAX+1, sizeof(char)); + if(!realpath(root, realroot)) { + pm_errno = PM_ERR_NOT_A_DIR; + return(-1); + } + /* verify root ends in a '/' */ + rootlen = strlen(realroot); + if(realroot[rootlen-1] != '/') { + rootlen += 1; } - if(realroot) { - free(realroot); + if(handle->root) { + FREE(handle->root); } + handle->root = calloc(rootlen + 1, sizeof(char)); + strncpy(handle->root, realroot, rootlen); + handle->root[rootlen-1] = '/'; + FREE(realroot); + _alpm_log(PM_LOG_DEBUG, "option 'root' = %s\n", handle->root); + return(0); } -void SYMEXPORT alpm_option_set_dbpath(const char *dbpath) +int SYMEXPORT alpm_option_set_dbpath(const char *dbpath) { - if(handle->dbpath) FREE(handle->dbpath); - if(dbpath) { - /* verify dbpath ends in a '/' */ - int dbpathlen = strlen(dbpath); - if(dbpath[dbpathlen-1] != '/') { - dbpathlen += 1; - } - handle->dbpath = calloc(dbpathlen+1, sizeof(char)); - strncpy(handle->dbpath, dbpath, dbpathlen); - handle->dbpath[dbpathlen-1] = '/'; - _alpm_log(PM_LOG_DEBUG, _("option 'dbpath' = %s"), handle->dbpath); + struct stat st; + size_t dbpathlen, lockfilelen; + const char *lf = "db.lck"; + + ALPM_LOG_FUNC; + + if(!dbpath) { + pm_errno = PM_ERR_WRONG_ARGS; + return(-1); + } + if(stat(dbpath, &st) == -1 || !S_ISDIR(st.st_mode)) { + pm_errno = PM_ERR_NOT_A_DIR; + return(-1); + } + /* verify dbpath ends in a '/' */ + dbpathlen = strlen(dbpath); + if(dbpath[dbpathlen-1] != '/') { + dbpathlen += 1; + } + if(handle->dbpath) { + FREE(handle->dbpath); } + handle->dbpath = calloc(dbpathlen+1, sizeof(char)); + strncpy(handle->dbpath, dbpath, dbpathlen); + handle->dbpath[dbpathlen-1] = '/'; + _alpm_log(PM_LOG_DEBUG, "option 'dbpath' = %s\n", handle->dbpath); + + if(handle->lockfile) { + FREE(handle->lockfile); + } + lockfilelen = strlen(handle->dbpath) + strlen(lf) + 1; + handle->lockfile = calloc(lockfilelen, sizeof(char)); + snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf); + _alpm_log(PM_LOG_DEBUG, "option 'lockfile' = %s\n", handle->lockfile); + return(0); } -void SYMEXPORT alpm_option_set_cachedir(const char *cachedir) +int SYMEXPORT alpm_option_add_cachedir(const char *cachedir) { - if(handle->cachedir) FREE(handle->cachedir); - if(cachedir) { - /* verify cachedir ends in a '/' */ - int cachedirlen = strlen(cachedir); - if(cachedir[cachedirlen-1] != '/') { - cachedirlen += 1; - } - handle->cachedir = calloc(cachedirlen+1, sizeof(char)); - strncpy(handle->cachedir, cachedir, cachedirlen); - handle->cachedir[cachedirlen-1] = '/'; - _alpm_log(PM_LOG_DEBUG, _("option 'cachedir' = %s"), handle->cachedir); + struct stat st; + char *newcachedir; + size_t cachedirlen; + + ALPM_LOG_FUNC; + + if(!cachedir) { + pm_errno = PM_ERR_WRONG_ARGS; + return(-1); + } + if(stat(cachedir, &st) == -1 || !S_ISDIR(st.st_mode)) { + pm_errno = PM_ERR_NOT_A_DIR; + return(-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_add(handle->cachedirs, newcachedir); + _alpm_log(PM_LOG_DEBUG, "option 'cachedir' = %s\n", newcachedir); + return(0); +} + +void SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs) +{ + if(handle->cachedirs) FREELIST(handle->cachedirs); + if(cachedirs) handle->cachedirs = cachedirs; } -void alpm_option_set_logfile(const char *logfile) +int SYMEXPORT alpm_option_set_logfile(const char *logfile) { + char *oldlogfile = handle->logfile; + ALPM_LOG_FUNC; - if(handle->logfile) { - FREE(handle->logfile); - if(handle->logfd) { - fclose(handle->logfd); - handle->logfd = NULL; - } + 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(logfile) { - handle->logfile = strdup(logfile); - handle->logfd = fopen(logfile, "a"); + if(handle->logstream) { + fclose(handle->logstream); } + _alpm_log(PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile); + return(0); } -void alpm_option_set_usesyslog(unsigned short usesyslog) +void SYMEXPORT alpm_option_set_usesyslog(unsigned short usesyslog) { handle->usesyslog = usesyslog; } -void alpm_option_add_noupgrade(char *pkg) +void SYMEXPORT alpm_option_add_noupgrade(const char *pkg) { handle->noupgrade = alpm_list_add(handle->noupgrade, strdup(pkg)); } -void alpm_option_set_noupgrades(alpm_list_t *noupgrade) +void SYMEXPORT alpm_option_set_noupgrades(alpm_list_t *noupgrade) { if(handle->noupgrade) FREELIST(handle->noupgrade); if(noupgrade) handle->noupgrade = noupgrade; } -void alpm_option_add_noextract(char *pkg) +void SYMEXPORT alpm_option_add_noextract(const char *pkg) { handle->noextract = alpm_list_add(handle->noextract, strdup(pkg)); } -void alpm_option_set_noextracts(alpm_list_t *noextract) + +void SYMEXPORT alpm_option_set_noextracts(alpm_list_t *noextract) { if(handle->noextract) FREELIST(handle->noextract); if(noextract) handle->noextract = noextract; } -void SYMEXPORT alpm_option_add_ignorepkg(char *pkg) +void SYMEXPORT alpm_option_add_ignorepkg(const char *pkg) { handle->ignorepkg = alpm_list_add(handle->ignorepkg, strdup(pkg)); } + void alpm_option_set_ignorepkgs(alpm_list_t *ignorepkgs) { if(handle->ignorepkg) FREELIST(handle->ignorepkg); if(ignorepkgs) handle->ignorepkg = ignorepkgs; } -void alpm_option_add_holdpkg(char *pkg) +void SYMEXPORT alpm_option_add_holdpkg(const char *pkg) { handle->holdpkg = alpm_list_add(handle->holdpkg, strdup(pkg)); } -void alpm_option_set_holdpkgs(alpm_list_t *holdpkgs) + +void SYMEXPORT alpm_option_set_holdpkgs(alpm_list_t *holdpkgs) { if(handle->holdpkg) FREELIST(handle->holdpkg); if(holdpkgs) handle->holdpkg = holdpkgs; } -void alpm_option_set_upgradedelay(time_t delay) +void SYMEXPORT alpm_option_add_ignoregrp(const char *grp) +{ + handle->ignoregrp = alpm_list_add(handle->ignoregrp, strdup(grp)); +} + +void alpm_option_set_ignoregrps(alpm_list_t *ignoregrps) +{ + if(handle->ignoregrp) FREELIST(handle->ignoregrp); + if(ignoregrps) handle->ignoregrp = ignoregrps; +} + +void SYMEXPORT alpm_option_set_upgradedelay(time_t delay) { handle->upgradedelay = delay; } -void alpm_option_set_xfercommand(const char *cmd) +void SYMEXPORT alpm_option_set_xfercommand(const char *cmd) { if(handle->xfercommand) FREE(handle->xfercommand); if(cmd) handle->xfercommand = strdup(cmd); } -void alpm_option_set_nopassiveftp(unsigned short nopasv) +void SYMEXPORT alpm_option_set_nopassiveftp(unsigned short nopasv) { handle->nopassiveftp = nopasv; } -void alpm_option_set_chomp(unsigned short chomp) { handle->chomp = chomp; } - -void alpm_option_set_usecolor(unsigned short usecolor) +void SYMEXPORT alpm_option_set_usedelta(unsigned short usedelta) { - handle->use_color = usecolor; + handle->usedelta = usedelta; } /* vim: set ts=2 sw=2 noet: */ |