summaryrefslogtreecommitdiffstats
path: root/lib/libalpm/package.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/package.c')
-rw-r--r--lib/libalpm/package.c201
1 files changed, 92 insertions, 109 deletions
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 287c2ce4..3277dd09 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -42,7 +42,6 @@
#include "alpm_list.h"
#include "log.h"
#include "util.h"
-#include "error.h"
#include "db.h"
#include "cache.h"
#include "delta.h"
@@ -105,8 +104,7 @@ int SYMEXPORT alpm_pkg_free(pmpkg_t *pkg)
int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
{
char *fpath;
- char *md5sum = NULL;
- int retval = 0;
+ int retval;
ALPM_LOG_FUNC;
@@ -116,28 +114,16 @@ int SYMEXPORT alpm_pkg_checkmd5sum(pmpkg_t *pkg)
ASSERT(pkg->origin_data.db != handle->db_local, RET_ERR(PM_ERR_PKG_INVALID, -1));
fpath = _alpm_filecache_find(alpm_pkg_get_filename(pkg));
- md5sum = alpm_get_md5sum(fpath);
- if(md5sum == NULL) {
- _alpm_log(PM_LOG_ERROR, _("could not get md5sum for package %s-%s\n"),
- alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
- pm_errno = PM_ERR_NOT_A_FILE;
+ retval = _alpm_test_md5sum(fpath, alpm_pkg_get_md5sum(pkg));
+
+ if(retval == 0) {
+ return(0);
+ } else if (retval == 1) {
+ pm_errno = PM_ERR_PKG_INVALID;
retval = -1;
- } else {
- if(strcmp(md5sum, alpm_pkg_get_md5sum(pkg)) == 0) {
- _alpm_log(PM_LOG_DEBUG, "md5sums for package %s-%s match\n",
- alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
- } else {
- _alpm_log(PM_LOG_ERROR, _("md5sums do not match for package %s-%s\n"),
- alpm_pkg_get_name(pkg), alpm_pkg_get_version(pkg));
- pm_errno = PM_ERR_PKG_INVALID;
- retval = -1;
- }
}
- FREE(fpath);
- FREE(md5sum);
-
return(retval);
}
@@ -166,15 +152,17 @@ const char SYMEXPORT *alpm_pkg_get_filename(pmpkg_t *pkg)
_alpm_db_read(pkg->origin_data.db, pkg, INFRQ_DESC);
}
- if(!strlen(pkg->filename)) {
+ if(pkg->filename == NULL || strlen(pkg->filename) == 0) {
/* construct the file name, it's not in the desc file */
+ char buffer[PATH_MAX];
if(pkg->arch && strlen(pkg->arch) > 0) {
- snprintf(pkg->filename, PKG_FILENAME_LEN, "%s-%s-%s" PKGEXT,
+ snprintf(buffer, PATH_MAX, "%s-%s-%s" PKGEXT,
pkg->name, pkg->version, pkg->arch);
} else {
- snprintf(pkg->filename, PKG_FILENAME_LEN, "%s-%s" PKGEXT,
+ snprintf(buffer, PATH_MAX, "%s-%s" PKGEXT,
pkg->name, pkg->version);
}
+ STRDUP(pkg->filename, buffer, RET_ERR(PM_ERR_MEMORY, NULL));
}
return pkg->filename;
@@ -520,7 +508,7 @@ void SYMEXPORT *alpm_pkg_changelog_open(pmpkg_t *pkg)
int ret = ARCHIVE_OK;
if((archive = archive_read_new()) == NULL) {
- RET_ERR(PM_ERR_LIBARCHIVE_ERROR, NULL);
+ RET_ERR(PM_ERR_LIBARCHIVE, NULL);
}
archive_read_support_compression_all(archive);
@@ -756,15 +744,12 @@ pmpkg_t *_alpm_pkg_new(const char *name, const char *version)
CALLOC(pkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL));
- if(name && name[0] != 0) {
- strncpy(pkg->name, name, PKG_NAME_LEN);
- } else {
- pkg->name[0] = '\0';
+ if(name) {
+ STRDUP(pkg->name, name, RET_ERR(PM_ERR_MEMORY, pkg));
}
- if(version && version[0] != 0) {
- strncpy(pkg->version, version, PKG_VERSION_LEN);
- } else {
- pkg->version[0] = '\0';
+
+ if(version) {
+ STRDUP(pkg->version, version, RET_ERR(PM_ERR_MEMORY, pkg));
}
return(pkg);
@@ -772,31 +757,51 @@ pmpkg_t *_alpm_pkg_new(const char *name, const char *version)
pmpkg_t *_alpm_pkg_dup(pmpkg_t *pkg)
{
- pmpkg_t* newpkg;
+ pmpkg_t *newpkg;
+ alpm_list_t *i;
ALPM_LOG_FUNC;
CALLOC(newpkg, 1, sizeof(pmpkg_t), RET_ERR(PM_ERR_MEMORY, NULL));
- memcpy(newpkg, pkg, sizeof(pmpkg_t));
+ STRDUP(newpkg->filename, pkg->filename, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->name, pkg->name, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->version, pkg->version, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->desc, pkg->desc, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->url, pkg->url, RET_ERR(PM_ERR_MEMORY, newpkg));
+ newpkg->builddate = pkg->builddate;
+ newpkg->installdate = pkg->installdate;
+ STRDUP(newpkg->packager, pkg->packager, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->md5sum, pkg->md5sum, RET_ERR(PM_ERR_MEMORY, newpkg));
+ STRDUP(newpkg->arch, pkg->arch, RET_ERR(PM_ERR_MEMORY, newpkg));
+ newpkg->size = pkg->size;
+ newpkg->isize = pkg->isize;
+ newpkg->scriptlet = pkg->scriptlet;
+ newpkg->force = pkg->force;
+ newpkg->reason = pkg->reason;
+
newpkg->licenses = alpm_list_strdup(alpm_pkg_get_licenses(pkg));
- newpkg->conflicts = alpm_list_strdup(alpm_pkg_get_conflicts(pkg));
+ newpkg->replaces = alpm_list_strdup(alpm_pkg_get_replaces(pkg));
+ newpkg->groups = alpm_list_strdup(alpm_pkg_get_groups(pkg));
newpkg->files = alpm_list_strdup(alpm_pkg_get_files(pkg));
newpkg->backup = alpm_list_strdup(alpm_pkg_get_backup(pkg));
- newpkg->depends = alpm_list_copy_data(alpm_pkg_get_depends(pkg),
- sizeof(pmdepend_t));
+ for(i = alpm_pkg_get_depends(pkg); i; i = alpm_list_next(i)) {
+ newpkg->depends = alpm_list_add(newpkg->depends, _alpm_dep_dup(i->data));
+ }
newpkg->optdepends = alpm_list_strdup(alpm_pkg_get_optdepends(pkg));
- newpkg->groups = alpm_list_strdup(alpm_pkg_get_groups(pkg));
+ newpkg->conflicts = alpm_list_strdup(alpm_pkg_get_conflicts(pkg));
newpkg->provides = alpm_list_strdup(alpm_pkg_get_provides(pkg));
- newpkg->replaces = alpm_list_strdup(alpm_pkg_get_replaces(pkg));
newpkg->deltas = alpm_list_copy_data(alpm_pkg_get_deltas(pkg),
- sizeof(pmdelta_t));
+ sizeof(pmdelta_t));
+
/* internal */
+ newpkg->origin = pkg->origin;
if(newpkg->origin == PKG_FROM_FILE) {
newpkg->origin_data.file = strdup(pkg->origin_data.file);
} else {
newpkg->origin_data.db = pkg->origin_data.db;
}
+ newpkg->infolevel = pkg->infolevel;
return(newpkg);
}
@@ -809,16 +814,27 @@ void _alpm_pkg_free(pmpkg_t *pkg)
return;
}
+ FREE(pkg->filename);
+ FREE(pkg->name);
+ FREE(pkg->version);
+ FREE(pkg->desc);
+ FREE(pkg->url);
+ FREE(pkg->packager);
+ FREE(pkg->md5sum);
+ FREE(pkg->arch);
FREELIST(pkg->licenses);
+ FREELIST(pkg->replaces);
+ FREELIST(pkg->groups);
FREELIST(pkg->files);
FREELIST(pkg->backup);
- FREELIST(pkg->depends);
+ alpm_list_free_inner(pkg->depends, (alpm_list_fn_free)_alpm_dep_free);
+ alpm_list_free(pkg->depends);
FREELIST(pkg->optdepends);
FREELIST(pkg->conflicts);
- FREELIST(pkg->groups);
FREELIST(pkg->provides);
- FREELIST(pkg->replaces);
- FREELIST(pkg->deltas);
+ alpm_list_free_inner(pkg->deltas, (alpm_list_fn_free)_alpm_delta_free);
+ alpm_list_free(pkg->deltas);
+
if(pkg->origin == PKG_FROM_FILE) {
FREE(pkg->origin_data.file);
}
@@ -866,15 +882,18 @@ int _alpm_pkg_cmp(const void *p1, const void *p2)
return(strcmp(alpm_pkg_get_name(pk1), alpm_pkg_get_name(pk2)));
}
-/* Parses the package description file for the current package
- * TODO: this should ALL be in a backend interface (be_files), we should
- * be dealing with the abstracted concepts only in this file
+int _alpm_pkgname_pkg_cmp(const void *pkgname, const void *package)
+{
+ return(strcmp(alpm_pkg_get_name((pmpkg_t *) package), (char *) pkgname));
+}
+
+
+/* Parses the package description file for the current package. This
+ * is handed the struct archive when the .PKGINFO file is open.
* Returns: 0 on success, 1 on error
- *
*/
-static int parse_descfile(const char *descfile, pmpkg_t *info)
+static int parse_descfile(struct archive *a, pmpkg_t *info)
{
- FILE* fp = NULL;
char line[PATH_MAX];
char *ptr = NULL;
char *key = NULL;
@@ -882,13 +901,8 @@ static int parse_descfile(const char *descfile, pmpkg_t *info)
ALPM_LOG_FUNC;
- if((fp = fopen(descfile, "r")) == NULL) {
- _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), descfile, strerror(errno));
- return(-1);
- }
-
- while(!feof(fp)) {
- fgets(line, PATH_MAX, fp);
+ /* loop until we reach EOF (where archive_fgets will return NULL) */
+ while(_alpm_archive_fgets(line, PATH_MAX, a) != NULL) {
linenum++;
_alpm_strtrim(line);
if(strlen(line) == 0 || line[0] == '#') {
@@ -898,26 +912,26 @@ static int parse_descfile(const char *descfile, pmpkg_t *info)
key = strsep(&ptr, "=");
if(key == NULL || ptr == NULL) {
_alpm_log(PM_LOG_DEBUG, "%s: syntax error in description file line %d\n",
- info->name[0] != '\0' ? info->name : "error", linenum);
+ info->name ? info->name : "error", linenum);
} else {
- _alpm_strtrim(key);
- _alpm_strtrim(ptr);
+ key = _alpm_strtrim(key);
+ ptr = _alpm_strtrim(ptr);
if(!strcmp(key, "pkgname")) {
- strncpy(info->name, ptr, sizeof(info->name));
+ STRDUP(info->name, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "pkgver")) {
- strncpy(info->version, ptr, sizeof(info->version));
+ STRDUP(info->version, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "pkgdesc")) {
- strncpy(info->desc, ptr, sizeof(info->desc));
+ STRDUP(info->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "group")) {
info->groups = alpm_list_add(info->groups, strdup(ptr));
} else if(!strcmp(key, "url")) {
- strncpy(info->url, ptr, sizeof(info->url));
+ STRDUP(info->url, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "license")) {
info->licenses = alpm_list_add(info->licenses, strdup(ptr));
} else if(!strcmp(key, "builddate")) {
char first = tolower(ptr[0]);
if(first > 'a' && first < 'z') {
- struct tm tmp_tm = {0}; //initialize to null incase of failure
+ struct tm tmp_tm = {0}; //initialize to null in case of failure
setlocale(LC_TIME, "C");
strptime(ptr, "%a %b %e %H:%M:%S %Y", &tmp_tm);
info->builddate = mktime(&tmp_tm);
@@ -926,14 +940,14 @@ static int parse_descfile(const char *descfile, pmpkg_t *info)
info->builddate = atol(ptr);
}
} else if(!strcmp(key, "packager")) {
- strncpy(info->packager, ptr, sizeof(info->packager));
+ STRDUP(info->packager, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "arch")) {
- strncpy(info->arch, ptr, sizeof(info->arch));
+ STRDUP(info->arch, ptr, RET_ERR(PM_ERR_MEMORY, -1));
} else if(!strcmp(key, "size")) {
/* size in the raw package is uncompressed (installed) size */
info->isize = atol(ptr);
} else if(!strcmp(key, "depend")) {
- pmdepend_t *dep = alpm_splitdep(ptr);
+ pmdepend_t *dep = _alpm_splitdep(ptr);
info->depends = alpm_list_add(info->depends, dep);
} else if(!strcmp(key, "optdepend")) {
info->optdepends = alpm_list_add(info->optdepends, strdup(ptr));
@@ -947,13 +961,11 @@ static int parse_descfile(const char *descfile, pmpkg_t *info)
info->backup = alpm_list_add(info->backup, strdup(ptr));
} else {
_alpm_log(PM_LOG_DEBUG, "%s: syntax error in description file line %d\n",
- info->name[0] != '\0' ? info->name : "error", linenum);
+ info->name ? info->name : "error", linenum);
}
}
line[0] = '\0';
}
- fclose(fp);
- unlink(descfile);
return(0);
}
@@ -973,8 +985,6 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
struct archive *archive;
struct archive_entry *entry;
pmpkg_t *info = NULL;
- char *descfile = NULL;
- int fd = -1;
struct stat st;
ALPM_LOG_FUNC;
@@ -984,7 +994,7 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
}
if((archive = archive_read_new()) == NULL) {
- RET_ERR(PM_ERR_LIBARCHIVE_ERROR, NULL);
+ RET_ERR(PM_ERR_LIBARCHIVE, NULL);
}
archive_read_support_compression_all(archive);
@@ -1005,48 +1015,28 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
info->size = st.st_size;
}
- /* TODO there is no reason to make temp files to read
- * from a libarchive archive, it can be done by reading
- * directly from the archive
- * See: archive_read_data_into_buffer
- * requires changes 'parse_descfile' as well
- * */
-
/* If full is false, only read through the archive until we find our needed
* metadata. If it is true, read through the entire archive, which serves
* as a verfication of integrity and allows us to create the filelist. */
while((ret = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) {
const char *entry_name = archive_entry_pathname(entry);
- /* NOTE: we used to look for .FILELIST, but it is easier (and safer) for
- * us to just generate this on our own. */
if(strcmp(entry_name, ".PKGINFO") == 0) {
- /* extract this file into /tmp. it has info for us */
- descfile = strdup("/tmp/alpm_XXXXXX");
- fd = mkstemp(descfile);
- if(archive_read_data_into_fd(archive, fd) != ARCHIVE_OK) {
- _alpm_log(PM_LOG_ERROR, _("error extracting package description file to %s\n"),
- descfile);
- goto pkg_invalid;
- }
/* parse the info file */
- if(parse_descfile(descfile, info) == -1) {
+ if(parse_descfile(archive, info) != 0) {
_alpm_log(PM_LOG_ERROR, _("could not parse package description file in %s\n"),
pkgfile);
goto pkg_invalid;
}
- if(!strlen(info->name)) {
+ if(info->name == NULL || strlen(info->name) == 0) {
_alpm_log(PM_LOG_ERROR, _("missing package name in %s\n"), pkgfile);
goto pkg_invalid;
}
- if(!strlen(info->version)) {
+ if(info->version == NULL || strlen(info->version) == 0) {
_alpm_log(PM_LOG_ERROR, _("missing package version in %s\n"), pkgfile);
goto pkg_invalid;
}
config = 1;
- unlink(descfile);
- FREE(descfile);
- close(fd);
continue;
} else if(strcmp(entry_name, ".INSTALL") == 0) {
info->scriptlet = 1;
@@ -1061,7 +1051,7 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
if(archive_read_data_skip(archive)) {
_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"),
pkgfile, archive_error_string(archive));
- pm_errno = PM_ERR_LIBARCHIVE_ERROR;
+ pm_errno = PM_ERR_LIBARCHIVE;
goto error;
}
@@ -1074,7 +1064,7 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
if(ret != ARCHIVE_EOF && ret != ARCHIVE_OK) { /* An error occured */
_alpm_log(PM_LOG_ERROR, _("error while reading package %s: %s\n"),
pkgfile, archive_error_string(archive));
- pm_errno = PM_ERR_LIBARCHIVE_ERROR;
+ pm_errno = PM_ERR_LIBARCHIVE;
goto error;
}
@@ -1090,13 +1080,13 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
info->origin_data.file = strdup(pkgfile);
if(full) {
- /* "checking for conflicts" requires a sorted list, so we ensure that here */
+ /* "checking for conflicts" requires a sorted list, ensure that here */
_alpm_log(PM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile);
info->files = alpm_list_msort(info->files, alpm_list_count(info->files),
_alpm_str_cmp);
info->infolevel = INFRQ_ALL;
} else {
- /* get rid of any partial filelist we may have collected, as it is invalid */
+ /* get rid of any partial filelist we may have collected, it is invalid */
FREELIST(info->files);
info->infolevel = INFRQ_BASE | INFRQ_DESC | INFRQ_DEPENDS;
}
@@ -1105,13 +1095,6 @@ pmpkg_t *_alpm_pkg_load(const char *pkgfile, unsigned short full)
pkg_invalid:
pm_errno = PM_ERR_PKG_INVALID;
- if(descfile) {
- unlink(descfile);
- FREE(descfile);
- }
- if(fd != -1) {
- close(fd);
- }
error:
_alpm_pkg_free(info);
archive_read_finish(archive);