/* * alpm.c * * Copyright (c) 2002 by Judd Vinet * * 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 #include #include #include #include #include #include #include #include #include #include /* PATH_MAX */ #include /* pacman */ #include "log.h" #include "error.h" #include "rpmvercmp.h" #include "md5.h" #include "list.h" #include "package.h" #include "group.h" #include "util.h" #include "db.h" #include "cache.h" #include "deps.h" #include "backup.h" #include "add.h" #include "remove.h" #include "sync.h" #include "handle.h" #include "alpm.h" pmhandle_t *handle = NULL; enum __pmerrno_t pm_errno; /* * Library */ int alpm_initialize(char *root) { char str[PATH_MAX]; ASSERT(handle == NULL, PM_RET_ERR(PM_ERR_HANDLE_NOT_NULL, -1)); handle = handle_new(); /* lock db */ if(handle->access == PM_ACCESS_RW) { if(_alpm_lckmk(PACLOCK) == -1) { FREE(handle); PM_RET_ERR(PM_ERR_HANDLE_LOCK, -1); } } strncpy(str, (root) ? root : PACROOT, PATH_MAX); /* add a trailing '/' if there isn't one */ if(str[strlen(str)-1] != '/') { strcat(str, "/"); } handle->root = strdup(str); return(0); } int alpm_release() { PMList *i; ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); /* unlock db */ if(handle->access == PM_ACCESS_RW) { if(_alpm_lckrm(PACLOCK)) { _alpm_log(PM_LOG_WARNING, "could not remove lock file %s", PACLOCK); alpm_logaction("warning: could not remove lock file %s", PACLOCK); } } /* close local database */ if(handle->db_local) { db_close(handle->db_local); handle->db_local = NULL; } /* and also sync ones */ for(i = handle->dbs_sync; i; i = i->next) { if(i->data) { db_close(i->data); i->data = NULL; } } FREEHANDLE(handle); return(0); } /* * Options */ int alpm_set_option(unsigned char parm, unsigned long data) { /* Sanity checks */ ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); return(handle_set_option(handle, parm, data)); } int alpm_get_option(unsigned char parm, long *data) { /* Sanity checks */ ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); return(handle_get_option(handle, parm, data)); } /* * Databases */ int alpm_db_register(char *treename, PM_DB **db) { /* Sanity checks */ ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); ASSERT(treename != NULL && strlen(treename) != 0, PM_RET_ERR(PM_ERR_WRONG_ARGS, -1)); ASSERT(db != NULL, PM_RET_ERR(PM_ERR_WRONG_ARGS, -1)); /* check if the db if already registered */ *db = db_open(handle->root, handle->dbpath, treename); if(*db == NULL) { /* couldn't open the db directory - try creating it */ if(db_create(handle->root, handle->dbpath, treename) == -1) { PM_RET_ERR(PM_ERR_DB_CREATE, -1); } *db = db_open(handle->root, handle->dbpath, treename); if(*db == NULL) { /* couldn't open the db directory, try creating it */ PM_RET_ERR(PM_ERR_DB_OPEN, -1); } } if(strcmp(treename, "local") == 0) { handle->db_local = *db; } else { handle->dbs_sync = pm_list_add(handle->dbs_sync, *db); } return(0); } int alpm_db_unregister(PM_DB *db) { PMList *i; int found = 0; /* Sanity checks */ ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); ASSERT(db != NULL, PM_RET_ERR(PM_ERR_WRONG_ARGS, -1)); if(db == handle->db_local) { db_close(handle->db_local); handle->db_local = NULL; found = 1; } else { for(i = handle->dbs_sync; i && !found; i = i->next) { if(db == i->data) { db_close(i->data); i->data = NULL; /* ORE it should be _alpm_list_removed instead */ found = 1; } } } if(!found) { PM_RET_ERR(PM_ERR_DB_NOT_FOUND, -1); } return(0); } PM_PKG *alpm_db_readpkg(PM_DB *db, char *name) { /* Sanity checks */ ASSERT(handle != NULL, return(NULL)); ASSERT(db != NULL, return(NULL)); ASSERT(name != NULL && strlen(name) != 0, return(NULL)); return(db_get_pkgfromcache(db, name)); } PM_LIST *alpm_db_getpkgcache(PM_DB *db) { /* Sanity checks */ ASSERT(handle != NULL, return(NULL)); ASSERT(db != NULL, return(NULL)); return(db_get_pkgcache(db)); } PM_GRP *alpm_db_readgrp(PM_DB *db, char *name) { /* Sanity checks */ ASSERT(handle != NULL, return(NULL)); ASSERT(db != NULL, return(NULL)); ASSERT(name != NULL && strlen(name) != 0, return(NULL)); return(db_get_grpfromcache(db, name)); } PM_LIST *alpm_db_getgrpcache(PM_DB *db) { /* Sanity checks */ ASSERT(handle != NULL, return(NULL)); ASSERT(db != NULL, return(NULL)); return(db_get_grpcache(db)); } PM_LIST *alpm_db_nextgrp(PM_LIST *cache) { /* Sanity checks */ ASSERT(handle != NULL, return(NULL)); ASSERT(cache != NULL, return(NULL)); return(cache->next); } PM_GRP *alpm_db_getgrp(PM_LIST *cache) { /* Sanity checks */ ASSERT(handle != NULL, return(NULL)); ASSERT(cache != NULL, return(NULL)); return(cache->data); } /* * Packages */ void *alpm_pkg_getinfo(PM_PKG *pkg, unsigned char parm) { void *data; /* Sanity checks */ ASSERT(handle != NULL, return(NULL)); ASSERT(pkg != NULL, return(NULL)); /* Update the cache package entry if needed */ if(pkg->origin == PKG_FROM_CACHE && pkg->data == handle->db_local) { switch(parm) { case PM_PKG_FILES: case PM_PKG_BACKUP: if(!(pkg->infolevel & INFRQ_FILES)) { char target[321]; /* 256+1+64 */ snprintf(target, 321, "%s-%s", pkg->name, pkg->version); db_read(pkg->data, target, INFRQ_FILES, pkg); } break; case PM_PKG_SCRIPLET: if(!(pkg->infolevel & INFRQ_SCRIPLET)) { char target[321]; snprintf(target, 321, "%s-%s", pkg->name, pkg->version); db_read(pkg->data, target, INFRQ_SCRIPLET, pkg); } break; } } switch(parm) { case PM_PKG_NAME: data = pkg->name; break; case PM_PKG_VERSION: data = pkg->version; break; case PM_PKG_DESC: data = pkg->desc; break; case PM_PKG_GROUPS: data = pkg->groups; break; case PM_PKG_URL: data = pkg->url; break; case PM_PKG_LICENSE: data = pkg->license; break; case PM_PKG_ARCH: data = pkg->arch; break; case PM_PKG_BUILDDATE: data = pkg->builddate; break; case PM_PKG_INSTALLDATE: data = pkg->installdate; break; case PM_PKG_PACKAGER: data = pkg->packager; break; case PM_PKG_SIZE: data = (void *)pkg->size; break; case PM_PKG_REASON: data = (void *)(int)pkg->reason; break; case PM_PKG_REPLACES: data = pkg->replaces; break; case PM_PKG_MD5SUM: data = pkg->md5sum; break; case PM_PKG_DEPENDS: data = pkg->depends; break; case PM_PKG_REQUIREDBY: data = pkg->requiredby; break; case PM_PKG_PROVIDES: data = pkg->provides; break; case PM_PKG_CONFLICTS: data = pkg->conflicts; break; case PM_PKG_FILES: data = pkg->files; break; case PM_PKG_BACKUP: data = pkg->backup; break; case PM_PKG_SCRIPLET: data = (void *)(int)pkg->scriptlet; break; default: data = NULL; break; } return(data); } int alpm_pkg_load(char *filename, PM_PKG **pkg) { /* Sanity checks */ ASSERT(filename != NULL && strlen(filename) != 0, PM_RET_ERR(PM_ERR_WRONG_ARGS, -1)); ASSERT(pkg != NULL, PM_RET_ERR(PM_ERR_WRONG_ARGS, -1)); *pkg = pkg_load(filename); if(*pkg == NULL) { /* pm_errno is set by pkg_load */ return(-1); } return(0); } int alpm_pkg_free(PM_PKG *pkg) { /* Sanity checks */ ASSERT(pkg != NULL, PM_RET_ERR(PM_ERR_WRONG_ARGS, -1)); pkg_free(pkg); return(0); } int alpm_pkg_vercmp(const char *ver1, const char *ver2) { return(rpmvercmp(ver1, ver2)); } /* * Groups */ void *alpm_grp_getinfo(PM_GRP *grp, unsigned char parm) { void *data; /* Sanity checks */ ASSERT(grp != NULL, return(NULL)); switch(parm) { case PM_GRP_NAME: data = grp->name; break; case PM_GRP_PKGNAMES: data = grp->packages; break; default: data = NULL; break; } return(data); } /* * Sync operations */ void *alpm_sync_getinfo(PM_SYNC *sync, unsigned char parm) { void *data; /* Sanity checks */ ASSERT(sync != NULL, return(NULL)); switch(parm) { case PM_SYNC_TYPE: data = (void *)(int)sync->type; break; case PM_SYNC_LOCALPKG: data = sync->lpkg; break; case PM_SYNC_SYNCPKG: data = sync->spkg; break; default: data = NULL; break; } return(data); } int alpm_sync_sysupgrade(PM_LIST **data) { ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); ASSERT(data != NULL, PM_RET_ERR(PM_ERR_WRONG_ARGS, -1)); return(sync_sysupgrade(data)); } /* * Transactions */ void *alpm_trans_getinfo(unsigned char parm) { pmtrans_t *trans; void *data; /* Sanity checks */ ASSERT(handle != NULL, return(NULL)); trans = handle->trans; switch(parm) { case PM_TRANS_TYPE: data = (void *)(int)trans->type; break; case PM_TRANS_FLAGS: data = (void *)(int)trans->flags; break; case PM_TRANS_TARGETS: data = trans->targets; break; default: data = NULL; break; } return(data); } int alpm_trans_init(unsigned char type, unsigned char flags, alpm_trans_cb cb) { /* Sanity checks */ ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); ASSERT(handle->trans == NULL, PM_RET_ERR(PM_ERR_TRANS_NOT_NULL, -1)); handle->trans = trans_new(); if(handle->trans == NULL) { PM_RET_ERR(PM_ERR_MEMORY, -1); } return(trans_init(handle->trans, type, flags, cb)); } int alpm_trans_addtarget(char *target) { pmtrans_t *trans; /* Sanity checks */ ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); ASSERT(target != NULL && strlen(target) != 0, PM_RET_ERR(PM_ERR_WRONG_ARGS, -1)); trans = handle->trans; ASSERT(trans != NULL, PM_RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(trans->state == STATE_INITIALIZED, PM_RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); return(trans_addtarget(trans, target)); } int alpm_trans_prepare(PMList **data) { pmtrans_t *trans; /* Sanity checks */ ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); ASSERT(data != NULL, PM_RET_ERR(PM_ERR_WRONG_ARGS, -1)); trans = handle->trans; ASSERT(trans != NULL, PM_RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(trans->state == STATE_INITIALIZED, PM_RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1)); return(trans_prepare(handle->trans, data)); } int alpm_trans_commit() { pmtrans_t *trans; /* Sanity checks */ ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); trans = handle->trans; ASSERT(trans != NULL, PM_RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(trans->state == STATE_PREPARED, PM_RET_ERR(PM_ERR_TRANS_NOT_PREPARED, -1)); /* ORE ASSERT(handle->access != PM_ACCESS_RW, PM_RET_ERR(PM_ERR_BAD_PERMS, -1));*/ return(trans_commit(handle->trans)); } int alpm_trans_release() { pmtrans_t *trans; /* Sanity checks */ ASSERT(handle != NULL, PM_RET_ERR(PM_ERR_HANDLE_NULL, -1)); trans = handle->trans; ASSERT(trans != NULL, PM_RET_ERR(PM_ERR_TRANS_NULL, -1)); ASSERT(trans->state != STATE_IDLE, PM_RET_ERR(PM_ERR_TRANS_NULL, -1)); FREETRANS(handle->trans); return(0); } /* * Log facilities */ int alpm_logaction(char *fmt, ...) { char str[256]; va_list args; va_start(args, fmt); vsnprintf(str, 256, fmt, args); va_end(args); return(_alpm_log_action(handle->usesyslog, handle->logfd, str)); } /* * Lists wrappers */ PM_LIST *alpm_list_first(PM_LIST *list) { ASSERT(list != NULL, return(NULL)); return(list); } PM_LIST *alpm_list_next(PM_LIST *entry) { ASSERT(entry != NULL, return(NULL)); return(entry->next); } void *alpm_list_getdata(PM_LIST *entry) { ASSERT(entry != NULL, return(NULL)); return(entry->data); } int alpm_list_free(PM_LIST *entry) { if(entry) { /* ORE does not free all memory for packages... */ pm_list_free(entry); } return(0); } /* * Misc wrappers */ char *alpm_get_md5sum(char *name) { ASSERT(name != NULL, return(NULL)); return(MDFile(name)); } /* vim: set ts=2 sw=2 noet: */