Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/lib/libalpm/handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/handle.c')
-rw-r--r--lib/libalpm/handle.c214
1 files changed, 130 insertions, 84 deletions
diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c
index 7cee5020..ea252adb 100644
--- a/lib/libalpm/handle.c
+++ b/lib/libalpm/handle.c
@@ -30,6 +30,8 @@
#include <sys/types.h>
#include <syslog.h>
#include <time.h>
+#include <sys/stat.h>
+#include <errno.h>
/* libalpm */
#include "handle.h"
@@ -47,37 +49,16 @@ pmhandle_t *_alpm_handle_new()
handle = malloc(sizeof(pmhandle_t));
if(handle == NULL) {
- _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(pmhandle_t));
+ _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes\n"), 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 = NULL;
handle->dbpath = NULL;
handle->cachedirs = NULL;
@@ -95,10 +76,10 @@ void _alpm_handle_free(pmhandle_t *handle)
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;
@@ -147,76 +128,112 @@ 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_root(const char *root)
+int SYMEXPORT alpm_option_set_root(const char *root)
{
+ struct stat st;
+ char *realroot;
+ size_t rootlen;
+
ALPM_LOG_FUNC;
- if(handle->root) FREE(handle->root);
+ 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);
+ }
/* 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);
+ realroot = realpath(root, NULL);
+ if(!realroot) {
+ 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] = '/';
+ /* 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)
{
+ struct stat st;
+ size_t dbpathlen, lockfilelen;
+ const char *lf = "db.lck";
+
ALPM_LOG_FUNC;
- if(handle->dbpath) FREE(handle->dbpath);
- if(handle->lockfile) FREE(handle->lockfile);
- 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] = '/';
-
- const char *lf = "db.lck";
- int lockfilelen = strlen(handle->dbpath) + strlen(lf);
- handle->lockfile = calloc(lockfilelen + 1, sizeof(char));
- snprintf(handle->lockfile, lockfilelen, "%s%s", handle->dbpath, lf);
+ 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_add_cachedir(const char *cachedir)
+int SYMEXPORT alpm_option_add_cachedir(const char *cachedir)
{
+ struct stat st;
+ char *newcachedir;
+ size_t cachedirlen;
+
ALPM_LOG_FUNC;
- if(cachedir) {
- char *newcachedir;
- /* verify cachedir ends in a '/' */
- int 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"), newcachedir);
+ 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)
@@ -225,21 +242,48 @@ void SYMEXPORT alpm_option_set_cachedirs(alpm_list_t *cachedirs)
if(cachedirs) handle->cachedirs = cachedirs;
}
-void SYMEXPORT alpm_option_set_logfile(const char *logfile)
+int SYMEXPORT alpm_option_set_logfile(const char *logfile)
{
+ char *oldlogfile = handle->logfile;
+ FILE *oldlogstream = handle->logstream;
+
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);
+ handle->logstream = fopen(logfile, "a");
+ if(handle->logstream == NULL) {
+ /* TODO we probably want to do this at some point, but right now
+ * it just blows up when a user calls pacman without privilages */
+ _alpm_log(PM_LOG_DEBUG, "couldn't open logfile for writing, ignoring\n");
+ /*
+ if(errno == EACCES) {
+ pm_errno = PM_ERR_BADPERMS;
+ } else if(errno == ENOENT) {
+ pm_errno = PM_ERR_NOT_A_DIR;
+ } else {
+ pm_errno = PM_ERR_SYSTEM;
}
+ * reset logfile to its previous value *
+ FREE(handle->logfile);
+ handle->logfile = oldlogfile;
+ handle->logstream = oldlogstream;
+ return(-1);
+ */
+ }
+
+ if(oldlogfile) {
+ FREE(oldlogfile);
}
- if(logfile) {
- handle->logfile = strdup(logfile);
- handle->logfd = fopen(logfile, "a");
+ if(oldlogstream) {
+ fclose(oldlogstream);
}
+ _alpm_log(PM_LOG_DEBUG, "option 'logfile' = %s\n", handle->logfile);
+ return(0);
}
void SYMEXPORT alpm_option_set_usesyslog(unsigned short usesyslog)
@@ -273,6 +317,7 @@ 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);
@@ -283,6 +328,7 @@ void SYMEXPORT alpm_option_add_holdpkg(const char *pkg)
{
handle->holdpkg = alpm_list_add(handle->holdpkg, strdup(pkg));
}
+
void SYMEXPORT alpm_option_set_holdpkgs(alpm_list_t *holdpkgs)
{
if(handle->holdpkg) FREELIST(handle->holdpkg);