summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/be_files.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/be_files.c')
-rw-r--r--lib/libalpm/be_files.c635
1 files changed, 352 insertions, 283 deletions
diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c
index 4cd0985e..f5d4e826 100644
--- a/lib/libalpm/be_files.c
+++ b/lib/libalpm/be_files.c
@@ -25,7 +25,7 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
-#include <stdint.h> /* uintmax_t */
+#include <stdint.h> /* uintmax_t, intmax_t */
#include <sys/stat.h>
#include <dirent.h>
#include <ctype.h>
@@ -36,32 +36,182 @@
/* libalpm */
#include "db.h"
#include "alpm_list.h"
+#include "cache.h"
#include "log.h"
#include "util.h"
#include "alpm.h"
-#include "error.h"
#include "handle.h"
#include "package.h"
#include "delta.h"
#include "deps.h"
+#include "dload.h"
-/* This function is used to convert the downloaded db file to the proper backend
- * format
+/*
+ * Return the last update time as number of seconds from the epoch.
+ * Returns 0 if the value is unknown or can't be read.
*/
-int _alpm_db_install(pmdb_t *db, const char *dbfile)
+time_t getlastupdate(const pmdb_t *db)
{
+ FILE *fp;
+ char *file;
+ time_t ret = 0;
+
ALPM_LOG_FUNC;
- /* TODO we should not simply unpack the archive, but better parse it and
- * db_write each entry (see sync_load_dbarchive to get archive content) */
- _alpm_log(PM_LOG_DEBUG, "unpacking database '%s'\n", dbfile);
+ if(db == NULL) {
+ return(ret);
+ }
+
+ /* db->path + '.lastupdate' + NULL */
+ MALLOC(file, strlen(db->path) + 12, RET_ERR(PM_ERR_MEMORY, ret));
+ sprintf(file, "%s.lastupdate", db->path);
- if(_alpm_unpack(dbfile, db->path, NULL)) {
- RET_ERR(PM_ERR_SYSTEM, -1);
+ /* get the last update time, if it's there */
+ if((fp = fopen(file, "r")) == NULL) {
+ free(file);
+ return(ret);
+ } else {
+ char line[64];
+ if(fgets(line, sizeof(line), fp)) {
+ ret = atol(line);
+ }
}
+ fclose(fp);
+ free(file);
+ return(ret);
+}
- return unlink(dbfile);
+/*
+ * writes the dbpath/.lastupdate file with the value in time
+ */
+int setlastupdate(const pmdb_t *db, time_t time)
+{
+ FILE *fp;
+ char *file;
+ int ret = 0;
+
+ ALPM_LOG_FUNC;
+
+ if(db == NULL || time == 0) {
+ return(-1);
+ }
+
+ /* db->path + '.lastupdate' + NULL */
+ MALLOC(file, strlen(db->path) + 12, RET_ERR(PM_ERR_MEMORY, ret));
+ sprintf(file, "%s.lastupdate", db->path);
+
+ if((fp = fopen(file, "w")) == NULL) {
+ free(file);
+ return(-1);
+ }
+ if(fprintf(fp, "%ju", (uintmax_t)time) <= 0) {
+ ret = -1;
+ }
+ fclose(fp);
+ free(file);
+ return(ret);
+}
+
+/** Update a package database
+ * @param force if true, then forces the update, otherwise update only in case
+ * the database isn't up to date
+ * @param db pointer to the package database to update
+ * @return 0 on success, > 0 on error (pm_errno is set accordingly), < 0 if up
+ * to date
+ */
+int SYMEXPORT alpm_db_update(int force, pmdb_t *db)
+{
+ alpm_list_t *lp;
+ char *dbfile, *dbfilepath;
+ time_t newmtime = 0, lastupdate = 0;
+ const char *dbpath;
+ size_t len;
+
+ int ret;
+
+ ALPM_LOG_FUNC;
+
+ /* Sanity checks */
+ ASSERT(handle != NULL, RET_ERR(PM_ERR_HANDLE_NULL, -1));
+ ASSERT(db != NULL && db != handle->db_local, RET_ERR(PM_ERR_WRONG_ARGS, -1));
+ /* Verify we are in a transaction. This is done _mainly_ because we need a DB
+ * lock - if we update without a db lock, we may kludge some other pacman
+ * process that _has_ a lock.
+ */
+ ASSERT(handle->trans != NULL, RET_ERR(PM_ERR_TRANS_NULL, -1));
+ ASSERT(handle->trans->state == STATE_INITIALIZED, RET_ERR(PM_ERR_TRANS_NOT_INITIALIZED, -1));
+ ASSERT(handle->trans->type == PM_TRANS_TYPE_SYNC, RET_ERR(PM_ERR_TRANS_TYPE, -1));
+
+ if(!alpm_list_find_ptr(handle->dbs_sync, db)) {
+ RET_ERR(PM_ERR_DB_NOT_FOUND, -1);
+ }
+
+ if(!force) {
+ /* get the lastupdate time */
+ lastupdate = getlastupdate(db);
+ if(lastupdate == 0) {
+ _alpm_log(PM_LOG_DEBUG, "failed to get lastupdate time for %s\n",
+ db->treename);
+ }
+ }
+
+ len = strlen(db->treename) + strlen(DBEXT) + 1;
+ MALLOC(dbfile, len, RET_ERR(PM_ERR_MEMORY, -1));
+ sprintf(dbfile, "%s" DBEXT, db->treename);
+
+ dbpath = alpm_option_get_dbpath();
+
+ ret = _alpm_download_single_file(dbfile, db->servers, dbpath,
+ lastupdate, &newmtime);
+ free(dbfile);
+
+ if(ret == 1) {
+ /* mtimes match, do nothing */
+ pm_errno = 0;
+ return(1);
+ } else if(ret == -1) {
+ /* pm_errno was set by the download code */
+ _alpm_log(PM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerrorlast());
+ return(-1);
+ } else {
+ /* remove the old dir */
+ _alpm_log(PM_LOG_DEBUG, "flushing database %s\n", db->path);
+ for(lp = _alpm_db_get_pkgcache(db); lp; lp = lp->next) {
+ pmpkg_t *pkg = lp->data;
+ if(pkg && _alpm_db_remove(db, pkg) == -1) {
+ _alpm_log(PM_LOG_ERROR, _("could not remove database entry %s%s\n"),
+ db->treename, pkg->name);
+ RET_ERR(PM_ERR_DB_REMOVE, -1);
+ }
+ }
+
+ /* Cache needs to be rebuilt */
+ _alpm_db_free_pkgcache(db);
+
+ /* form the path to the db location */
+ len = strlen(dbpath) + strlen(db->treename) + strlen(DBEXT) + 1;
+ MALLOC(dbfilepath, len, RET_ERR(PM_ERR_MEMORY, -1));
+ sprintf(dbfilepath, "%s%s" DBEXT, dbpath, db->treename);
+
+ /* uncompress the sync database */
+ ret = _alpm_unpack(dbfilepath, db->path, NULL);
+ if(ret) {
+ free(dbfilepath);
+ RET_ERR(PM_ERR_SYSTEM, -1);
+ }
+ unlink(dbfilepath);
+ free(dbfilepath);
+
+ /* if we have a new mtime, set the DB last update value */
+ if(newmtime) {
+ _alpm_log(PM_LOG_DEBUG, "sync: new mtime for %s: %ju\n",
+ db->treename, (uintmax_t)newmtime);
+ setlastupdate(db, newmtime);
+ }
+ }
+
+ return(0);
}
int _alpm_db_open(pmdb_t *db)
@@ -95,18 +245,7 @@ void _alpm_db_close(pmdb_t *db)
}
}
-void _alpm_db_rewind(pmdb_t *db)
-{
- ALPM_LOG_FUNC;
-
- if(db == NULL || db->handle == NULL) {
- return;
- }
-
- rewinddir(db->handle);
-}
-
-static int _alpm_db_splitname(const char *target, char *name, char *version)
+static int splitname(const char *target, pmpkg_t *pkg)
{
/* the format of a db entry is as follows:
* package-version-rel/
@@ -115,10 +254,10 @@ static int _alpm_db_splitname(const char *target, char *name, char *version)
*/
char *tmp, *p, *q;
- if(target == NULL) {
+ if(target == NULL || pkg == NULL) {
return(-1);
}
- tmp = strdup(target);
+ STRDUP(tmp, target, RET_ERR(PM_ERR_MEMORY, -1));
p = tmp + strlen(tmp);
/* do the magic parsing- find the beginning of the version string
@@ -130,120 +269,95 @@ static int _alpm_db_splitname(const char *target, char *name, char *version)
}
/* copy into fields and return */
- if(version) {
- strncpy(version, p+1, PKG_VERSION_LEN);
+ if(pkg->version) {
+ FREE(pkg->version);
}
+ STRDUP(pkg->version, p+1, RET_ERR(PM_ERR_MEMORY, -1));
/* insert a terminator at the end of the name (on hyphen)- then copy it */
*p = '\0';
- if(name) {
- strncpy(name, tmp, PKG_NAME_LEN);
+ if(pkg->name) {
+ FREE(pkg->name);
}
+ STRDUP(pkg->name, tmp, RET_ERR(PM_ERR_MEMORY, -1));
free(tmp);
return(0);
}
-pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target)
+int _alpm_db_populate(pmdb_t *db)
{
+ int count = 0;
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 = NULL;
ALPM_LOG_FUNC;
- if(db == NULL) {
- RET_ERR(PM_ERR_DB_NULL, NULL);
- }
+ ASSERT(db != NULL, RET_ERR(PM_ERR_DB_NULL, -1));
- /* We loop here until we read a valid package. When an iteration of this loop
- * fails, it means alpm_db_read failed to read a valid package, so we'll read
- * the next so as not to abort whole-db operations early
- */
- while(!pkg) {
- if(target != NULL) {
- /* search for a specific package (by name only) */
- rewinddir(db->handle);
- while(!found && (ent = readdir(db->handle)) != NULL) {
- if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
- continue;
- }
- /* 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)) {
- continue;
- }
- strncpy(name, ent->d_name, PKG_FULLNAME_LEN);
- /* 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 { /* target == NULL, full scan */
- int isdir = 0;
- while(!isdir) {
- ent = readdir(db->handle);
- if(ent == NULL) {
- return(NULL);
- }
- if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
- isdir = 0;
- continue;
- }
- /* 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;
- }
- }
+ rewinddir(db->handle);
+ while((ent = readdir(db->handle)) != NULL) {
+ const char *name = ent->d_name;
+ pmpkg_t *pkg;
+
+ if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
+ continue;
+ }
+ /* stat the entry, make sure it's a directory */
+ snprintf(path, PATH_MAX, "%s%s", db->path, name);
+ if(stat(path, &sbuf) != 0 || !S_ISDIR(sbuf.st_mode)) {
+ continue;
}
- pkg = _alpm_pkg_new(NULL, NULL);
+ pkg = _alpm_pkg_new();
if(pkg == NULL) {
- _alpm_log(PM_LOG_DEBUG, "db scan could not find package: %s\n", target);
- return(NULL);
+ return(-1);
}
/* split the db entry name */
- if(_alpm_db_splitname(ent->d_name, pkg->name, pkg->version) != 0) {
+ if(splitname(name, pkg) != 0) {
_alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
- ent->d_name);
- alpm_pkg_free(pkg);
- pkg = NULL;
+ name);
+ _alpm_pkg_free(pkg);
continue;
}
/* explicitly read with only 'BASE' data, accessors will handle the rest */
if(_alpm_db_read(db, pkg, INFRQ_BASE) == -1) {
- /* TODO removed corrupt entry from the FS here */
+ _alpm_log(PM_LOG_ERROR, _("corrupted database entry '%s'\n"), name);
_alpm_pkg_free(pkg);
- } else {
- pkg->origin = PKG_FROM_CACHE;
- pkg->origin_data.db = db;
+ continue;
}
+ pkg->origin = PKG_FROM_CACHE;
+ pkg->origin_data.db = db;
+ /* add to the collection */
+ _alpm_log(PM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n",
+ pkg->name, db->treename);
+ db->pkgcache = alpm_list_add(db->pkgcache, pkg);
+ count++;
}
- return(pkg);
+ db->pkgcache = alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp);
+ return(count);
+}
+
+/* Note: the return value must be freed by the caller */
+static char *get_pkgpath(pmdb_t *db, pmpkg_t *info)
+{
+ size_t len;
+ char *pkgpath;
+
+ len = strlen(db->path) + strlen(info->name) + strlen(info->version) + 3;
+ MALLOC(pkgpath, len, RET_ERR(PM_ERR_MEMORY, NULL));
+ sprintf(pkgpath, "%s%s-%s/", db->path, info->name, info->version);
+ return(pkgpath);
}
int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
{
FILE *fp = NULL;
- struct stat buf;
- char path[PATH_MAX+1];
+ char path[PATH_MAX];
char line[513];
+ char *pkgpath = NULL;
ALPM_LOG_FUNC;
@@ -251,7 +365,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
RET_ERR(PM_ERR_DB_NULL, -1);
}
- if(info == NULL || info->name[0] == 0 || info->version[0] == 0) {
+ if(info == NULL || info->name == NULL || info->version == NULL) {
_alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_db_read, skipping\n");
return(-1);
}
@@ -276,17 +390,18 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
/* clear out 'line', to be certain - and to make valgrind happy */
memset(line, 0, 513);
- snprintf(path, PATH_MAX, "%s/%s-%s", db->path, info->name, info->version);
- if(stat(path, &buf)) {
+ pkgpath = get_pkgpath(db, info);
+
+ if(access(pkgpath, F_OK)) {
/* directory doesn't exist or can't be opened */
_alpm_log(PM_LOG_DEBUG, "cannot find '%s-%s' in db '%s'\n",
info->name, info->version, db->treename);
- return(-1);
+ goto error;
}
/* DESC */
if(inforeq & INFRQ_DESC) {
- snprintf(path, PATH_MAX, "%s/%s-%s/desc", db->path, info->name, info->version);
+ snprintf(path, PATH_MAX, "%sdesc", pkgpath);
if((fp = fopen(path, "r")) == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
goto error;
@@ -296,120 +411,131 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
break;
}
_alpm_strtrim(line);
- if(!strcmp(line, "%FILENAME%")) {
- if(fgets(info->filename, sizeof(info->filename), fp) == NULL) {
+ if(strcmp(line, "%NAME%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
+ goto error;
+ }
+ if(strcmp(_alpm_strtrim(line), info->name) != 0) {
+ _alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: name "
+ "mismatch on package %s\n"), db->treename, info->name);
+ }
+ } else if(strcmp(line, "%VERSION%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
+ goto error;
+ }
+ if(strcmp(_alpm_strtrim(line), info->version) != 0) {
+ _alpm_log(PM_LOG_ERROR, _("%s database is inconsistent: version "
+ "mismatch on package %s\n"), db->treename, info->name);
+ }
+ } else if(strcmp(line, "%FILENAME%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(info->filename);
- } else if(!strcmp(line, "%DESC%")) {
- if(fgets(info->desc, sizeof(info->desc), fp) == NULL) {
+ STRDUP(info->filename, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%DESC%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(info->desc);
- } else if(!strcmp(line, "%GROUPS%")) {
+ STRDUP(info->desc, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%GROUPS%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->groups = alpm_list_add(info->groups, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->groups = alpm_list_add(info->groups, linedup);
}
- } else if(!strcmp(line, "%URL%")) {
- if(fgets(info->url, sizeof(info->url), fp) == NULL) {
+ } else if(strcmp(line, "%URL%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(info->url);
- } else if(!strcmp(line, "%LICENSE%")) {
+ STRDUP(info->url, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%LICENSE%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->licenses = alpm_list_add(info->licenses, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->licenses = alpm_list_add(info->licenses, linedup);
}
- } else if(!strcmp(line, "%ARCH%")) {
- if(fgets(info->arch, sizeof(info->arch), fp) == NULL) {
+ } else if(strcmp(line, "%ARCH%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(info->arch);
- } else if(!strcmp(line, "%BUILDDATE%")) {
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ STRDUP(info->arch, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%BUILDDATE%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(tmp);
+ _alpm_strtrim(line);
- char first = tolower(tmp[0]);
+ char first = tolower(line[0]);
if(first > 'a' && first < 'z') {
struct tm tmp_tm = {0}; //initialize to null incase of failure
setlocale(LC_TIME, "C");
- strptime(tmp, "%a %b %e %H:%M:%S %Y", &tmp_tm);
+ strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm);
info->builddate = mktime(&tmp_tm);
setlocale(LC_TIME, "");
} else {
- info->builddate = atol(tmp);
+ info->builddate = atol(line);
}
- } else if(!strcmp(line, "%INSTALLDATE%")) {
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ } else if(strcmp(line, "%INSTALLDATE%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(tmp);
+ _alpm_strtrim(line);
- char first = tolower(tmp[0]);
+ char first = tolower(line[0]);
if(first > 'a' && first < 'z') {
struct tm tmp_tm = {0}; //initialize to null incase of failure
setlocale(LC_TIME, "C");
- strptime(tmp, "%a %b %e %H:%M:%S %Y", &tmp_tm);
+ strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm);
info->installdate = mktime(&tmp_tm);
setlocale(LC_TIME, "");
} else {
- info->installdate = atol(tmp);
+ info->installdate = atol(line);
}
- } else if(!strcmp(line, "%PACKAGER%")) {
- if(fgets(info->packager, sizeof(info->packager), fp) == NULL) {
+ } else if(strcmp(line, "%PACKAGER%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(info->packager);
- } else if(!strcmp(line, "%REASON%")) {
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ STRDUP(info->packager, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%REASON%") == 0) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(tmp);
- info->reason = atol(tmp);
- } else if(!strcmp(line, "%SIZE%") || !strcmp(line, "%CSIZE%")) {
+ info->reason = atol(_alpm_strtrim(line));
+ } else if(strcmp(line, "%SIZE%") == 0 || strcmp(line, "%CSIZE%") == 0) {
/* 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) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(tmp);
- info->size = atol(tmp);
+ info->size = atol(_alpm_strtrim(line));
/* also store this value to isize if isize is unset */
if(info->isize == 0) {
- info->isize = atol(tmp);
+ info->isize = info->size;
}
- } else if(!strcmp(line, "%ISIZE%")) {
+ } else if(strcmp(line, "%ISIZE%") == 0) {
/* ISIZE (installed size) tag only appears in sync repositories,
* not the local one. */
- char tmp[32];
- if(fgets(tmp, sizeof(tmp), fp) == NULL) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- _alpm_strtrim(tmp);
- info->isize = atol(tmp);
- } else if(!strcmp(line, "%MD5SUM%")) {
+ info->isize = atol(_alpm_strtrim(line));
+ } else if(strcmp(line, "%MD5SUM%") == 0) {
/* MD5SUM tag only appears in sync repositories,
* not the local one. */
- if(fgets(info->md5sum, sizeof(info->md5sum), fp) == NULL) {
+ if(fgets(line, 512, fp) == NULL) {
goto error;
}
- } else if(!strcmp(line, "%REPLACES%")) {
- /* the REPLACES tag is special -- it only appears in sync repositories,
- * not the local one. */
+ STRDUP(info->md5sum, _alpm_strtrim(line), goto error);
+ } else if(strcmp(line, "%REPLACES%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->replaces = alpm_list_add(info->replaces, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->replaces = alpm_list_add(info->replaces, linedup);
}
- } else if(!strcmp(line, "%FORCE%")) {
- /* FORCE tag only appears in sync repositories,
- * not the local one. */
+ } else if(strcmp(line, "%FORCE%") == 0) {
info->force = 1;
}
}
@@ -419,20 +545,24 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
/* FILES */
if(inforeq & INFRQ_FILES) {
- snprintf(path, PATH_MAX, "%s/%s-%s/files", db->path, info->name, info->version);
+ snprintf(path, PATH_MAX, "%sfiles", pkgpath);
if((fp = fopen(path, "r")) == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
goto error;
}
while(fgets(line, 256, fp)) {
_alpm_strtrim(line);
- if(!strcmp(line, "%FILES%")) {
+ if(strcmp(line, "%FILES%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->files = alpm_list_add(info->files, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->files = alpm_list_add(info->files, linedup);
}
- } else if(!strcmp(line, "%BACKUP%")) {
+ } else if(strcmp(line, "%BACKUP%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->backup = alpm_list_add(info->backup, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->backup = alpm_list_add(info->backup, linedup);
}
}
}
@@ -442,7 +572,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
/* DEPENDS */
if(inforeq & INFRQ_DEPENDS) {
- snprintf(path, PATH_MAX, "%s/%s-%s/depends", db->path, info->name, info->version);
+ snprintf(path, PATH_MAX, "%sdepends", pkgpath);
if((fp = fopen(path, "r")) == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
goto error;
@@ -450,37 +580,30 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
while(!feof(fp)) {
fgets(line, 255, fp);
_alpm_strtrim(line);
- if(!strcmp(line, "%DEPENDS%")) {
+ if(strcmp(line, "%DEPENDS%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- pmdepend_t *dep = alpm_splitdep(line);
+ pmdepend_t *dep = _alpm_splitdep(_alpm_strtrim(line));
info->depends = alpm_list_add(info->depends, dep);
}
- } else if(!strcmp(line, "%OPTDEPENDS%")) {
+ } else if(strcmp(line, "%OPTDEPENDS%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->optdepends = alpm_list_add(info->optdepends, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->optdepends = alpm_list_add(info->optdepends, linedup);
}
- } else if(!strcmp(line, "%CONFLICTS%")) {
+ } else if(strcmp(line, "%CONFLICTS%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->conflicts = alpm_list_add(info->conflicts, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->conflicts = alpm_list_add(info->conflicts, linedup);
}
- } else if(!strcmp(line, "%PROVIDES%")) {
+ } else if(strcmp(line, "%PROVIDES%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
- info->provides = alpm_list_add(info->provides, strdup(line));
+ char *linedup;
+ STRDUP(linedup, _alpm_strtrim(line), goto error);
+ info->provides = alpm_list_add(info->provides, linedup);
}
}
- /* TODO: we were going to move these things here, but it should wait.
- * A better change would be to figure out how to restructure the DB. */
- /* 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;
@@ -488,12 +611,12 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
/* DELTAS */
if(inforeq & INFRQ_DELTAS) {
- snprintf(path, PATH_MAX, "%s/%s-%s/deltas", db->path, info->name, info->version);
+ snprintf(path, PATH_MAX, "%sdeltas", pkgpath);
if((fp = fopen(path, "r"))) {
while(!feof(fp)) {
fgets(line, 255, fp);
_alpm_strtrim(line);
- if(!strcmp(line, "%DELTAS%")) {
+ if(strcmp(line, "%DELTAS%") == 0) {
while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
info->deltas = alpm_list_add(info->deltas, _alpm_delta_parse(line));
}
@@ -506,8 +629,8 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
/* INSTALL */
if(inforeq & INFRQ_SCRIPTLET) {
- snprintf(path, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version);
- if(!stat(path, &buf)) {
+ snprintf(path, PATH_MAX, "%sinstall", pkgpath);
+ if(access(path, F_OK) == 0) {
info->scriptlet = 1;
}
}
@@ -515,9 +638,11 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
/* internal */
info->infolevel |= inforeq;
+ free(pkgpath);
return(0);
error:
+ free(pkgpath);
if(fp) {
fclose(fp);
}
@@ -532,6 +657,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
alpm_list_t *lp = NULL;
int retval = 0;
int local = 0;
+ char *pkgpath = NULL;
ALPM_LOG_FUNC;
@@ -539,9 +665,10 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
return(-1);
}
- snprintf(path, PATH_MAX, "%s/%s-%s", db->path, info->name, info->version);
+ pkgpath = get_pkgpath(db, info);
+
oldmask = umask(0000);
- mkdir(path, 0755);
+ mkdir(pkgpath, 0755);
/* make sure we have a sane umask */
umask(0022);
@@ -553,7 +680,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
if(inforeq & INFRQ_DESC) {
_alpm_log(PM_LOG_DEBUG, "writing %s-%s DESC information back to db\n",
info->name, info->version);
- snprintf(path, PATH_MAX, "%s/%s-%s/desc", db->path, info->name, info->version);
+ snprintf(path, PATH_MAX, "%sdesc", pkgpath);
if((fp = fopen(path, "w")) == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
retval = -1;
@@ -561,7 +688,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
}
fprintf(fp, "%%NAME%%\n%s\n\n"
"%%VERSION%%\n%s\n\n", info->name, info->version);
- if(info->desc[0]) {
+ if(info->desc) {
fprintf(fp, "%%DESC%%\n"
"%s\n\n", info->desc);
}
@@ -572,8 +699,18 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
}
fprintf(fp, "\n");
}
+ 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");
+ }
if(local) {
- if(info->url[0]) {
+ if(info->url) {
fprintf(fp, "%%URL%%\n"
"%s\n\n", info->url);
}
@@ -584,7 +721,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
}
fprintf(fp, "\n");
}
- if(info->arch[0]) {
+ if(info->arch) {
fprintf(fp, "%%ARCH%%\n"
"%s\n\n", info->arch);
}
@@ -596,14 +733,14 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
fprintf(fp, "%%INSTALLDATE%%\n"
"%ju\n\n", (uintmax_t)info->installdate);
}
- if(info->packager[0]) {
+ if(info->packager) {
fprintf(fp, "%%PACKAGER%%\n"
"%s\n\n", info->packager);
}
- if(info->size) {
+ if(info->isize) {
/* only write installed size, csize is irrelevant once installed */
fprintf(fp, "%%SIZE%%\n"
- "%lu\n\n", info->isize);
+ "%ju\n\n", (intmax_t)info->isize);
}
if(info->reason) {
fprintf(fp, "%%REASON%%\n"
@@ -612,11 +749,11 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
} else {
if(info->size) {
fprintf(fp, "%%CSIZE%%\n"
- "%lu\n\n", info->size);
+ "%ju\n\n", (intmax_t)info->size);
}
if(info->isize) {
fprintf(fp, "%%ISIZE%%\n"
- "%lu\n\n", info->isize);
+ "%ju\n\n", (intmax_t)info->isize);
}
if(info->md5sum) {
fprintf(fp, "%%MD5SUM%%\n"
@@ -631,7 +768,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
if(local && (inforeq & INFRQ_FILES)) {
_alpm_log(PM_LOG_DEBUG, "writing %s-%s FILES information back to db\n",
info->name, info->version);
- snprintf(path, PATH_MAX, "%s/%s-%s/files", db->path, info->name, info->version);
+ snprintf(path, PATH_MAX, "%sfiles", pkgpath);
if((fp = fopen(path, "w")) == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
retval = -1;
@@ -659,7 +796,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
if(inforeq & INFRQ_DEPENDS) {
_alpm_log(PM_LOG_DEBUG, "writing %s-%s DEPENDS information back to db\n",
info->name, info->version);
- snprintf(path, PATH_MAX, "%s/%s-%s/depends", db->path, info->name, info->version);
+ snprintf(path, PATH_MAX, "%sdepends", pkgpath);
if((fp = fopen(path, "w")) == NULL) {
_alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
retval = -1;
@@ -695,19 +832,6 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
}
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;
}
@@ -717,6 +841,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
cleanup:
umask(oldmask);
+ free(pkgpath);
if(fp) {
fclose(fp);
@@ -727,7 +852,8 @@ cleanup:
int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
{
- char path[PATH_MAX];
+ int ret = 0;
+ char *pkgpath = NULL;
ALPM_LOG_FUNC;
@@ -735,70 +861,13 @@ int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
RET_ERR(PM_ERR_DB_NULL, -1);
}
- snprintf(path, PATH_MAX, "%s%s-%s", db->path, info->name, info->version);
- if(_alpm_rmrf(path) == -1) {
- return(-1);
- }
-
- return(0);
-}
-
-/*
- * Return the last update time as number of seconds from the epoch.
- * Returns 0 if the value is unknown or can't be read.
- */
-time_t _alpm_db_getlastupdate(const pmdb_t *db)
-{
- FILE *fp;
- char file[PATH_MAX];
- time_t ret = 0;
-
- ALPM_LOG_FUNC;
-
- if(db == NULL) {
- return(ret);
- }
-
- snprintf(file, PATH_MAX, "%s.lastupdate", db->path);
-
- /* get the last update time, if it's there */
- if((fp = fopen(file, "r")) == NULL) {
- return(ret);
- } else {
- char line[64];
- if(fgets(line, sizeof(line), fp)) {
- ret = atol(line);
- }
- }
- fclose(fp);
- return(ret);
-}
-
-/*
- * writes the dbpath/.lastupdate file with the value in time
- */
-int _alpm_db_setlastupdate(const pmdb_t *db, time_t time)
-{
- FILE *fp;
- char file[PATH_MAX];
- int ret = 0;
-
- ALPM_LOG_FUNC;
-
- if(db == NULL || time == 0) {
- return(-1);
- }
-
- snprintf(file, PATH_MAX, "%s.lastupdate", db->path);
+ pkgpath = get_pkgpath(db, info);
- if((fp = fopen(file, "w")) == NULL) {
- return(-1);
- }
- if(fprintf(fp, "%ju", (uintmax_t)time) <= 0) {
+ ret = _alpm_rmrf(pkgpath);
+ free(pkgpath);
+ if(ret != 0) {
ret = -1;
}
- fclose(fp);
-
return(ret);
}