diff options
Diffstat (limited to 'lib/libalpm/package.c')
-rw-r--r-- | lib/libalpm/package.c | 201 |
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); |