/* * 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 * (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, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ #include "config.h" #include <stdlib.h> #include <string.h> #include <unistd.h> #include <limits.h> #include <sys/types.h> #include <stdarg.h> #include <syslog.h> #include <libintl.h> #include <time.h> #include <ftplib.h> /* pacman */ #include "util.h" #include "log.h" #include "list.h" #include "error.h" #include "trans.h" #include "alpm.h" #include "server.h" #include "handle.h" 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); } memset(handle, 0, sizeof(pmhandle_t)); handle->lckfd = -1; #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")) { #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->dbpath = strdup(PM_DBPATH); handle->cachedir = strdup(PM_CACHEDIR); return(handle); } int _alpm_handle_free(pmhandle_t *handle) { ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); /* close logfiles */ if(handle->logfd) { fclose(handle->logfd); handle->logfd = NULL; } if(handle->usesyslog) { handle->usesyslog = 0; closelog(); } /* free memory */ FREETRANS(handle->trans); FREE(handle->root); FREE(handle->dbpath); FREE(handle->cachedir); FREE(handle->logfile); FREE(handle->proxyhost); FREE(handle->xfercommand); FREELIST(handle->dbs_sync); FREELIST(handle->noupgrade); FREELIST(handle->noextract); FREELIST(handle->ignorepkg); FREELIST(handle->holdpkg); FREELIST(handle->needles); free(handle); return(0); } int _alpm_handle_set_option(pmhandle_t *handle, unsigned char val, unsigned long data) { /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); char *p; switch(val) { case PM_OPT_DBPATH: if(handle->dbpath) { FREE(handle->dbpath); } handle->dbpath = strdup((data && strlen((char *)data) != 0) ? (char *)data : PM_DBPATH); _alpm_log(PM_LOG_FLOW2, _("PM_OPT_DBPATH set to '%s'"), handle->dbpath); break; case PM_OPT_CACHEDIR: if(handle->cachedir) { FREE(handle->cachedir); } handle->cachedir = strdup((data && strlen((char *)data) != 0) ? (char *)data : PM_CACHEDIR); _alpm_log(PM_LOG_FLOW2, _("PM_OPT_CACHEDIR set to '%s'"), handle->cachedir); break; case PM_OPT_LOGFILE: if((char *)data == NULL || handle->uid != 0) { return(0); } if(handle->logfile) { FREE(handle->logfile); } if(handle->logfd) { if(fclose(handle->logfd) != 0) { handle->logfd = NULL; RET_ERR(PM_ERR_OPT_LOGFILE, -1); } handle->logfd = NULL; } if((handle->logfd = fopen((char *)data, "a")) == NULL) { _alpm_log(PM_LOG_ERROR, _("can't open log file %s"), (char *)data); RET_ERR(PM_ERR_OPT_LOGFILE, -1); } handle->logfile = strdup((char *)data); _alpm_log(PM_LOG_FLOW2, _("PM_OPT_LOGFILE set to '%s'"), (char *)data); break; case PM_OPT_NOUPGRADE: if((char *)data && strlen((char *)data) != 0) { handle->noupgrade = _alpm_list_add(handle->noupgrade, strdup((char *)data)); _alpm_log(PM_LOG_FLOW2, _("'%s' added to PM_OPT_NOUPGRADE"), (char *)data); } else { FREELIST(handle->noupgrade); _alpm_log(PM_LOG_FLOW2, _("PM_OPT_NOUPGRADE flushed")); } break; case PM_OPT_NOEXTRACT: if((char *)data && strlen((char *)data) != 0) { handle->noextract = _alpm_list_add(handle->noextract, strdup((char *)data)); _alpm_log(PM_LOG_FLOW2, _("'%s' added to PM_OPT_NOEXTRACT"), (char *)data); } else { FREELIST(handle->noextract); _alpm_log(PM_LOG_FLOW2, _("PM_OPT_NOEXTRACT flushed")); } break; case PM_OPT_IGNOREPKG: if((char *)data && strlen((char *)data) != 0) { handle->ignorepkg = _alpm_list_add(handle->ignorepkg, strdup((char *)data)); _alpm_log(PM_LOG_FLOW2, _("'%s' added to PM_OPT_IGNOREPKG"), (char *)data); } else { FREELIST(handle->ignorepkg); _alpm_log(PM_LOG_FLOW2, _("PM_OPT_IGNOREPKG flushed")); } break; case PM_OPT_HOLDPKG: if((char *)data && strlen((char *)data) != 0) { handle->holdpkg = _alpm_list_add(handle->holdpkg, strdup((char *)data)); _alpm_log(PM_LOG_FLOW2, _("'%s' added to PM_OPT_HOLDPKG"), (char *)data); } else { FREELIST(handle->holdpkg); _alpm_log(PM_LOG_FLOW2, _("PM_OPT_HOLDPKG flushed")); } break; case PM_OPT_NEEDLES: if((char *)data && strlen((char *)data) != 0) { handle->needles = _alpm_list_add(handle->needles, strdup((char *)data)); _alpm_log(PM_LOG_FLOW2, _("'%s' added to PM_OPT_NEEDLES"), (char *)data); } else { FREELIST(handle->needles); _alpm_log(PM_LOG_FLOW2, _("PM_OPT_NEEDLES flushed")); } break; case PM_OPT_USESYSLOG: if(data != 0 && data != 1) { RET_ERR(PM_ERR_OPT_USESYSLOG, -1); } if(handle->usesyslog == data) { return(0); } if(handle->usesyslog) { closelog(); } else { openlog("alpm", 0, LOG_USER); } handle->usesyslog = (unsigned short)data; _alpm_log(PM_LOG_FLOW2, _("PM_OPT_USESYSLOG set to '%d'"), handle->usesyslog); break; case PM_OPT_LOGCB: pm_logcb = (alpm_cb_log)data; break; case PM_OPT_DLCB: pm_dlcb = (FtpCallback)data; break; case PM_OPT_DLFNM: pm_dlfnm = (char *)data; break; case PM_OPT_DLOFFSET: pm_dloffset = (int *)data; break; case PM_OPT_DLT0: pm_dlt0 = (struct timeval *)data; break; case PM_OPT_DLT: pm_dlt = (struct timeval *)data; break; case PM_OPT_DLRATE: pm_dlrate = (float *)data; break; case PM_OPT_DLXFERED1: pm_dlxfered1 = (int *)data; break; case PM_OPT_DLETA_H: pm_dleta_h = (unsigned char *)data; break; case PM_OPT_DLETA_M: pm_dleta_m = (unsigned char *)data; break; case PM_OPT_DLETA_S: pm_dleta_s = (unsigned char *)data; break; case PM_OPT_UPGRADEDELAY: handle->upgradedelay = data; break; case PM_OPT_LOGMASK: pm_logmask = (unsigned char)data; _alpm_log(PM_LOG_FLOW2, _("PM_OPT_LOGMASK set to '%02x'"), (unsigned char)data); break; case PM_OPT_PROXYHOST: if(handle->proxyhost) { FREE(handle->proxyhost); } p = strstr((char*)data, "://"); if(p) { p += 3; if(p == NULL || *p == '\0') { RET_ERR(PM_ERR_SERVER_BAD_LOCATION, -1); } data = (long)p; } #if defined(__APPLE__) || defined(__OpenBSD__) handle->proxyhost = strdup((char*)data); #else handle->proxyhost = strndup((char*)data, PATH_MAX); #endif _alpm_log(PM_LOG_FLOW2, _("PM_OPT_PROXYHOST set to '%s'"), handle->proxyhost); break; case PM_OPT_PROXYPORT: handle->proxyport = (unsigned short)data; _alpm_log(PM_LOG_FLOW2, _("PM_OPT_PROXYPORT set to '%d'"), handle->proxyport); break; case PM_OPT_XFERCOMMAND: if(handle->xfercommand) { FREE(handle->xfercommand); } #if defined(__APPLE__) || defined(__OpenBSD__) handle->xfercommand = strdup((char*)data); #else handle->xfercommand = strndup((char*)data, PATH_MAX); #endif _alpm_log(PM_LOG_FLOW2, _("PM_OPT_XFERCOMMAND set to '%s'"), handle->xfercommand); break; case PM_OPT_NOPASSIVEFTP: handle->nopassiveftp = (unsigned short)data; _alpm_log(PM_LOG_FLOW2, _("PM_OPT_NOPASSIVEFTP set to '%d'"), handle->nopassiveftp); break; case PM_OPT_CHOMP: handle->chomp = (unsigned short)data; _alpm_log(PM_LOG_FLOW2, _("PM_OPT_CHOMP set to '%d'"), handle->chomp); break; default: RET_ERR(PM_ERR_WRONG_ARGS, -1); } return(0); } int _alpm_handle_get_option(pmhandle_t *handle, unsigned char val, long *data) { /* Sanity checks */ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1)); switch(val) { case PM_OPT_ROOT: *data = (long)handle->root; break; case PM_OPT_DBPATH: *data = (long)handle->dbpath; break; case PM_OPT_CACHEDIR: *data = (long)handle->cachedir; break; case PM_OPT_LOCALDB: *data = (long)handle->db_local; break; case PM_OPT_SYNCDB: *data = (long)handle->dbs_sync; break; case PM_OPT_LOGFILE: *data = (long)handle->logfile; break; case PM_OPT_NOUPGRADE: *data = (long)handle->noupgrade; break; case PM_OPT_NOEXTRACT: *data = (long)handle->noextract; break; case PM_OPT_IGNOREPKG: *data = (long)handle->ignorepkg; break; case PM_OPT_HOLDPKG: *data = (long)handle->holdpkg; break; case PM_OPT_NEEDLES: *data = (long)handle->needles; break; case PM_OPT_USESYSLOG: *data = handle->usesyslog; break; case PM_OPT_LOGCB: *data = (long)pm_logcb; break; case PM_OPT_DLCB: *data = (long)pm_dlcb; break; case PM_OPT_UPGRADEDELAY: *data = (long)handle->upgradedelay; break; case PM_OPT_LOGMASK: *data = pm_logmask; break; case PM_OPT_DLFNM: *data = (long)pm_dlfnm; break; case PM_OPT_DLOFFSET: *data = (long)pm_dloffset; break; case PM_OPT_DLT0: *data = (long)pm_dlt0; break; case PM_OPT_DLT: *data = (long)pm_dlt; break; case PM_OPT_DLRATE: *data = (long)pm_dlrate; break; case PM_OPT_DLXFERED1: *data = (long)pm_dlxfered1; break; case PM_OPT_DLETA_H: *data = (long)pm_dleta_h; break; case PM_OPT_DLETA_M: *data = (long)pm_dleta_m; break; case PM_OPT_DLETA_S: *data = (long)pm_dleta_s; break; case PM_OPT_PROXYHOST: *data = (long)handle->proxyhost; break; case PM_OPT_PROXYPORT: *data = handle->proxyport; break; case PM_OPT_XFERCOMMAND: *data = (long)handle->xfercommand; break; case PM_OPT_NOPASSIVEFTP: *data = handle->nopassiveftp; break; case PM_OPT_CHOMP: *data = handle->chomp; break; default: RET_ERR(PM_ERR_WRONG_ARGS, -1); break; } return(0); } /* vim: set ts=2 sw=2 noet: */