summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/db.c
diff options
context:
space:
mode:
authorAurelien Foret <aurelien@archlinux.org>2006-03-02 20:06:52 +0100
committerAurelien Foret <aurelien@archlinux.org>2006-03-02 20:06:52 +0100
commite2faeb46e108395f6efab06472ef9bb72e64431a (patch)
tree1567d106ecd2250611f55cbc04d809fdcf1ca87c /lib/libalpm/db.c
parent5261c7fafb142135d01458b083013580a9d035cc (diff)
downloadpacman-e2faeb46e108395f6efab06472ef9bb72e64431a.tar.gz
pacman-e2faeb46e108395f6efab06472ef9bb72e64431a.tar.xz
reworked the db object to prepare future integration with different backends
Diffstat (limited to 'lib/libalpm/db.c')
-rw-r--r--lib/libalpm/db.c560
1 files changed, 11 insertions, 549 deletions
diff --git a/lib/libalpm/db.c b/lib/libalpm/db.c
index 437715e8..6b1ceffe 100644
--- a/lib/libalpm/db.c
+++ b/lib/libalpm/db.c
@@ -26,6 +26,7 @@
#include <errno.h>
#include <string.h>
#include <sys/stat.h>
+#include <dirent.h>
#ifdef CYGWIN
#include <limits.h> /* PATH_MAX */
#endif
@@ -33,48 +34,28 @@
#include "log.h"
#include "util.h"
#include "error.h"
-#include "group.h"
-#include "cache.h"
#include "db.h"
#include "alpm.h"
-/* Open a database and return a pmdb_t handle */
-pmdb_t *_alpm_db_open(char *dbpath, char *treename, int mode)
+pmdb_t *_alpm_db_new(char *root, char* dbpath, char *treename)
{
pmdb_t *db;
- if(dbpath == NULL || treename == NULL) {
- return(NULL);
- }
-
- _alpm_log(PM_LOG_DEBUG, "opening database '%s'", treename);
-
db = (pmdb_t *)malloc(sizeof(pmdb_t));
if(db == NULL) {
+ _alpm_log(PM_LOG_ERROR, "malloc failed: could not allocate %d bytes",
+ sizeof(pmdb_t));
RET_ERR(PM_ERR_MEMORY, NULL);
}
- db->path = (char *)malloc(strlen(dbpath)+strlen(treename)+2);
+ db->path = (char *)malloc(strlen(root)+strlen(dbpath)+1);
if(db->path == NULL) {
+ _alpm_log(PM_LOG_ERROR, "malloc failed: could not allocate %d bytes",
+ strlen(root)+strlen(dbpath)+1);
+ FREE(db);
RET_ERR(PM_ERR_MEMORY, NULL);
}
- sprintf(db->path, "%s/%s", dbpath, treename);
-
- db->dir = opendir(db->path);
- if(db->dir == NULL) {
- if(mode & DB_O_CREATE) {
- _alpm_log(PM_LOG_WARNING, "could not open database '%s' -- try creating it", treename);
- _alpm_log(PM_LOG_DEBUG, "creating database '%s'", treename);
- if(mkdir(db->path, 0755) == 0) {
- db->dir = opendir(db->path);
- }
- }
- if(!(mode & DB_O_CREATE) || db->dir == NULL) {
- FREE(db->path);
- FREE(db);
- return(NULL);
- }
- }
+ sprintf(db->path, "%s%s", root, dbpath);
STRNCPY(db->treename, treename, DB_TREENAME_LEN);
@@ -84,7 +65,7 @@ pmdb_t *_alpm_db_open(char *dbpath, char *treename, int mode)
return(db);
}
-void _alpm_db_close(void *data)
+void _alpm_db_free(void *data)
{
pmdb_t *db = data;
@@ -92,527 +73,8 @@ void _alpm_db_close(void *data)
return;
}
- _alpm_log(PM_LOG_DEBUG, "closing database '%s'", db->treename);
-
- if(db->dir) {
- closedir(db->dir);
- db->dir = NULL;
- }
- FREE(db->path);
-
- _alpm_db_free_pkgcache(db);
- _alpm_db_free_grpcache(db);
-
+ free(db->path);
free(db);
-
- return;
-}
-
-void _alpm_db_rewind(pmdb_t *db)
-{
- if(db == NULL || db->dir == NULL) {
- return;
- }
-
- rewinddir(db->dir);
-}
-
-pmpkg_t *_alpm_db_scan(pmdb_t *db, char *target, unsigned int inforeq)
-{
- struct dirent *ent = NULL;
- struct stat sbuf;
- char path[PATH_MAX];
- char name[PKG_FULLNAME_LEN];
- char *ptr = NULL;
- int found = 0;
- pmpkg_t *pkg;
-
- if(db == NULL) {
- return(NULL);
- }
-
- if(target != NULL) {
- /* search for a specific package (by name only) */
- _alpm_db_rewind(db);
- while(!found && (ent = readdir(db->dir)) != NULL) {
- if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
- continue;
- }
- STRNCPY(name, ent->d_name, PKG_FULLNAME_LEN);
- /* stat the entry, make sure it's a directory */
- snprintf(path, PATH_MAX, "%s/%s", db->path, name);
- if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) {
- continue;
- }
- /* truncate the string at the second-to-last hyphen, */
- /* which will give us the package name */
- if((ptr = rindex(name, '-'))) {
- *ptr = '\0';
- }
- if((ptr = rindex(name, '-'))) {
- *ptr = '\0';
- }
- if(!strcmp(name, target)) {
- found = 1;
- }
- }
- if(!found) {
- return(NULL);
- }
- } else {
- /* normal iteration */
- int isdir = 0;
- while(!isdir) {
- ent = readdir(db->dir);
- if(ent == NULL) {
- return(NULL);
- }
- /* stat the entry, make sure it's a directory */
- snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name);
- if(!stat(path, &sbuf) && S_ISDIR(sbuf.st_mode)) {
- isdir = 1;
- }
- if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
- isdir = 0;
- continue;
- }
- }
- }
-
- pkg = _alpm_pkg_new(NULL, NULL);
- if(pkg == NULL) {
- return(NULL);
- }
- if(_alpm_db_read(db, ent->d_name, inforeq, pkg) == -1) {
- FREEPKG(pkg);
- }
-
- return(pkg);
-}
-
-int _alpm_db_read(pmdb_t *db, char *name, unsigned int inforeq, pmpkg_t *info)
-{
- FILE *fp = NULL;
- struct stat buf;
- char path[PATH_MAX];
- char line[512];
-
- if(db == NULL || name == NULL || info == NULL) {
- return(-1);
- }
-
- snprintf(path, PATH_MAX, "%s/%s", db->path, name);
- if(stat(path, &buf)) {
- /* directory doesn't exist or can't be opened */
- return(-1);
- }
-
- if(info->name[0] == 0) {
- if(_alpm_pkg_splitname(name, info->name, info->version) == -1) {
- return(-1);
- }
- }
-
- /* DESC */
- if(inforeq & INFRQ_DESC) {
- snprintf(path, PATH_MAX, "%s/%s/desc", db->path, name);
- fp = fopen(path, "r");
- if(fp == NULL) {
- _alpm_log(PM_LOG_ERROR, "%s (%s)", path, strerror(errno));
- goto error;
- }
- while(!feof(fp)) {
- if(fgets(line, 256, fp) == NULL) {
- break;
- }
- _alpm_strtrim(line);
- if(!strcmp(line, "%DESC%")) {
- if(fgets(info->desc, sizeof(info->desc), fp) == NULL) {
- goto error;
- }
- _alpm_strtrim(info->desc);
- } else if(!strcmp(line, "%GROUPS%")) {
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->groups = _alpm_list_add(info->groups, strdup(line));
- }
- } else if(!strcmp(line, "%URL%")) {
- if(fgets(info->url, sizeof(info->url), fp) == NULL) {
- goto error;
- }
- _alpm_strtrim(info->url);
- } else if(!strcmp(line, "%LICENSE%")) {
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->license = _alpm_list_add(info->license, strdup(line));
- }
- } else if(!strcmp(line, "%ARCH%")) {
- if(fgets(info->arch, sizeof(info->arch), fp) == NULL) {
- goto error;
- }
- _alpm_strtrim(info->arch);
- } else if(!strcmp(line, "%BUILDDATE%")) {
- if(fgets(info->builddate, sizeof(info->builddate), fp) == NULL) {
- goto error;
- }
- _alpm_strtrim(info->builddate);
- } else if(!strcmp(line, "%INSTALLDATE%")) {
- if(fgets(info->installdate, sizeof(info->installdate), fp) == NULL) {
- goto error;
- }
- _alpm_strtrim(info->installdate);
- } else if(!strcmp(line, "%PACKAGER%")) {
- if(fgets(info->packager, sizeof(info->packager), fp) == NULL) {
- goto error;
- }
- _alpm_strtrim(info->packager);
- } else if(!strcmp(line, "%REASON%")) {
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
- goto error;
- }
- _alpm_strtrim(tmp);
- info->reason = atol(tmp);
- } else if(!strcmp(line, "%SIZE%") || !strcmp(line, "%CSIZE%")) {
- /* NOTE: the CSIZE and SIZE fields both share the "size" field
- * in the pkginfo_t struct. This can be done b/c CSIZE
- * is currently only used in sync databases, and SIZE is
- * only used in local databases.
- */
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
- goto error;
- }
- _alpm_strtrim(tmp);
- info->size = atol(tmp);
- } else if(!strcmp(line, "%MD5SUM%")) {
- /* MD5SUM tag only appears in sync repositories,
- * not the local one. */
- if(fgets(info->md5sum, sizeof(info->md5sum), fp) == NULL) {
- goto error;
- }
- /* XXX: these are only here as backwards-compatibility for pacman 2.x
- * sync repos.... in pacman3, they have been moved to DEPENDS.
- * Remove this when we move to pacman3 repos.
- */
- } else if(!strcmp(line, "%REPLACES%")) {
- /* the REPLACES tag is special -- it only appears in sync repositories,
- * not the local one. */
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->replaces = _alpm_list_add(info->replaces, strdup(line));
- }
- } else if(!strcmp(line, "%FORCE%")) {
- /* FORCE tag only appears in sync repositories,
- * not the local one. */
- info->force = 1;
- }
- }
- fclose(fp);
- fp = NULL;
- }
-
- /* FILES */
- if(inforeq & INFRQ_FILES) {
- snprintf(path, PATH_MAX, "%s/%s/files", db->path, name);
- fp = fopen(path, "r");
- if(fp == NULL) {
- _alpm_log(PM_LOG_ERROR, "%s (%s)", path, strerror(errno));
- goto error;
- }
- while(fgets(line, 256, fp)) {
- _alpm_strtrim(line);
- if(!strcmp(line, "%FILES%")) {
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->files = _alpm_list_add(info->files, strdup(line));
- }
- } else if(!strcmp(line, "%BACKUP%")) {
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->backup = _alpm_list_add(info->backup, strdup(line));
- }
- }
- }
- fclose(fp);
- fp = NULL;
- }
-
- /* DEPENDS */
- if(inforeq & INFRQ_DEPENDS) {
- snprintf(path, PATH_MAX, "%s/%s/depends", db->path, name);
- fp = fopen(path, "r");
- if(fp == NULL) {
- _alpm_log(PM_LOG_ERROR, "%s (%s)", path, strerror(errno));
- goto error;
- }
- while(!feof(fp)) {
- fgets(line, 255, fp);
- _alpm_strtrim(line);
- if(!strcmp(line, "%DEPENDS%")) {
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->depends = _alpm_list_add(info->depends, strdup(line));
- }
- } else if(!strcmp(line, "%REQUIREDBY%")) {
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->requiredby = _alpm_list_add(info->requiredby, strdup(line));
- }
- } else if(!strcmp(line, "%CONFLICTS%")) {
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->conflicts = _alpm_list_add(info->conflicts, strdup(line));
- }
- } else if(!strcmp(line, "%PROVIDES%")) {
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->provides = _alpm_list_add(info->provides, strdup(line));
- }
- } else if(!strcmp(line, "%REPLACES%")) {
- /* the REPLACES tag is special -- it only appears in sync repositories,
- * not the local one. */
- while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->replaces = _alpm_list_add(info->replaces, strdup(line));
- }
- } else if(!strcmp(line, "%FORCE%")) {
- /* FORCE tag only appears in sync repositories,
- * not the local one. */
- info->force = 1;
- }
- }
- fclose(fp);
- fp = NULL;
- }
-
- /* INSTALL */
- if(inforeq & INFRQ_SCRIPLET) {
- snprintf(path, PATH_MAX, "%s/%s/install", db->path, name);
- if(!stat(path, &buf)) {
- info->scriptlet = 1;
- }
- }
-
- /* internal */
- info->infolevel |= inforeq;
-
- return(0);
-
-error:
- if(fp) {
- fclose(fp);
- }
- return(-1);
-}
-
-int _alpm_db_write(pmdb_t *db, pmpkg_t *info, unsigned int inforeq)
-{
- char topdir[PATH_MAX];
- FILE *fp = NULL;
- char path[PATH_MAX];
- mode_t oldmask;
- PMList *lp = NULL;
- int retval = 0;
- int local = 0;
-
- if(db == NULL || info == NULL) {
- return(-1);
- }
-
- snprintf(topdir, PATH_MAX, "%s/%s-%s", db->path, info->name, info->version);
- oldmask = umask(0000);
- mkdir(topdir, 0755);
- /* make sure we have a sane umask */
- umask(0022);
-
- if(strcmp(db->treename, "local") == 0) {
- local = 1;
- }
-
- /* DESC */
- if(inforeq & INFRQ_DESC) {
- snprintf(path, PATH_MAX, "%s/desc", topdir);
- if((fp = fopen(path, "w")) == NULL) {
- _alpm_log(PM_LOG_ERROR, "db_write: could not open file %s/desc", db->treename);
- retval = 1;
- goto cleanup;
- }
- fprintf(fp, "%%NAME%%\n%s\n\n"
- "%%VERSION%%\n%s\n\n", info->name, info->version);
- if(info->desc[0]) {
- fprintf(fp, "%%DESC%%\n"
- "%s\n\n", info->desc);
- }
- if(info->groups) {
- fputs("%GROUPS%\n", fp);
- for(lp = info->groups; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
- }
- fprintf(fp, "\n");
- }
- if(local) {
- if(info->url[0]) {
- fprintf(fp, "%%URL%%\n"
- "%s\n\n", info->url);
- }
- if(info->license) {
- fputs("%LICENSE%\n", fp);
- for(lp = info->license; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
- }
- fprintf(fp, "\n");
- }
- if(info->arch[0]) {
- fprintf(fp, "%%ARCH%%\n"
- "%s\n\n", info->arch);
- }
- if(info->builddate[0]) {
- fprintf(fp, "%%BUILDDATE%%\n"
- "%s\n\n", info->builddate);
- }
- if(info->installdate[0]) {
- fprintf(fp, "%%INSTALLDATE%%\n"
- "%s\n\n", info->installdate);
- }
- if(info->packager[0]) {
- fprintf(fp, "%%PACKAGER%%\n"
- "%s\n\n", info->packager);
- }
- if(info->size) {
- fprintf(fp, "%%SIZE%%\n"
- "%ld\n\n", info->size);
- }
- if(info->reason) {
- fprintf(fp, "%%REASON%%\n"
- "%d\n\n", info->reason);
- }
- } else {
- if(info->size) {
- fprintf(fp, "%%CSIZE%%\n"
- "%ld\n\n", info->size);
- }
- if(info->reason) {
- fprintf(fp, "%%MD5SUM%%\n"
- "%s\n\n", info->md5sum);
- }
- }
- fclose(fp);
- fp = NULL;
- }
-
- /* FILES */
- if(local && (inforeq & INFRQ_FILES)) {
- snprintf(path, PATH_MAX, "%s/files", topdir);
- if((fp = fopen(path, "w")) == NULL) {
- _alpm_log(PM_LOG_ERROR, "db_write: could not open file %s/files", db->treename);
- retval = -1;
- goto cleanup;
- }
- if(info->files) {
- fprintf(fp, "%%FILES%%\n");
- for(lp = info->files; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
- }
- fprintf(fp, "\n");
- }
- if(info->backup) {
- fprintf(fp, "%%BACKUP%%\n");
- for(lp = info->backup; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
- }
- fprintf(fp, "\n");
- }
- fclose(fp);
- fp = NULL;
- }
-
- /* DEPENDS */
- if(inforeq & INFRQ_DEPENDS) {
- snprintf(path, PATH_MAX, "%s/depends", topdir);
- if((fp = fopen(path, "w")) == NULL) {
- _alpm_log(PM_LOG_ERROR, "db_write: could not open file %s/depends", db->treename);
- retval = -1;
- goto cleanup;
- }
- if(info->depends) {
- fputs("%DEPENDS%\n", fp);
- for(lp = info->depends; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
- }
- fprintf(fp, "\n");
- }
- if(local && info->requiredby) {
- fputs("%REQUIREDBY%\n", fp);
- for(lp = info->requiredby; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
- }
- fprintf(fp, "\n");
- }
- if(info->conflicts) {
- fputs("%CONFLICTS%\n", fp);
- for(lp = info->conflicts; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
- }
- fprintf(fp, "\n");
- }
- if(info->provides) {
- fputs("%PROVIDES%\n", fp);
- for(lp = info->provides; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
- }
- fprintf(fp, "\n");
- }
- if(!local) {
- if(info->replaces) {
- fputs("%REPLACES%\n", fp);
- for(lp = info->replaces; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
- }
- fprintf(fp, "\n");
- }
- if(info->force) {
- fprintf(fp, "%%FORCE%%\n"
- "\n");
- }
- }
- fclose(fp);
- fp = NULL;
- }
-
- /* INSTALL */
- /* nothing needed here (script is automatically extracted) */
-
-cleanup:
- umask(oldmask);
-
- if(fp) {
- fclose(fp);
- }
-
- return(retval);
-}
-
-int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
-{
- char topdir[PATH_MAX];
- char file[PATH_MAX];
-
- if(db == NULL || info == NULL) {
- return(-1);
- }
-
- snprintf(topdir, PATH_MAX, "%s/%s-%s", db->path, info->name, info->version);
-
- /* DESC */
- snprintf(file, PATH_MAX, "%s/desc", topdir);
- unlink(file);
- /* FILES */
- snprintf(file, PATH_MAX, "%s/files", topdir);
- unlink(file);
- /* DEPENDS */
- snprintf(file, PATH_MAX, "%s/depends", topdir);
- unlink(file);
- /* INSTALL */
- snprintf(file, PATH_MAX, "%s/install", topdir);
- unlink(file);
-
- /* Package directory */
- if(rmdir(topdir) == -1) {
- return(-1);
- }
-
- return(0);
}
/* vim: set ts=2 sw=2 noet: */