summaryrefslogtreecommitdiffstats
path: root/lib/libalpm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm')
-rw-r--r--lib/libalpm/alpm.h7
-rw-r--r--lib/libalpm/alpm_list.c18
-rw-r--r--lib/libalpm/alpm_list.h1
-rw-r--r--lib/libalpm/be_local.c133
-rw-r--r--lib/libalpm/be_package.c14
-rw-r--r--lib/libalpm/be_sync.c24
-rw-r--r--lib/libalpm/conflict.c89
-rw-r--r--lib/libalpm/conflict.h3
-rw-r--r--lib/libalpm/deps.c6
-rw-r--r--lib/libalpm/diskspace.c55
-rw-r--r--lib/libalpm/dload.c2
-rw-r--r--lib/libalpm/package.c38
-rw-r--r--lib/libalpm/package.h4
-rw-r--r--lib/libalpm/remove.c41
14 files changed, 226 insertions, 209 deletions
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h
index 8d458c3e..e733eb2d 100644
--- a/lib/libalpm/alpm.h
+++ b/lib/libalpm/alpm.h
@@ -160,6 +160,13 @@ typedef struct _alpm_delta_t {
off_t download_size;
} alpm_delta_t;
+/** File in a package */
+typedef struct _alpm_file_t {
+ char *name;
+ off_t size;
+ mode_t mode;
+} alpm_file_t;
+
/** Local package or package file backup entry */
typedef struct _alpm_backup_t {
char *name;
diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c
index c2b30adc..1976e13d 100644
--- a/lib/libalpm/alpm_list.c
+++ b/lib/libalpm/alpm_list.c
@@ -556,6 +556,24 @@ inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node)
}
/**
+ * @brief Get the previous element of a list.
+ *
+ * @param list the list head
+ * @param node the list node
+ *
+ * @return the previous element, or NULL when no previous element exist
+ */
+inline alpm_list_t SYMEXPORT *alpm_list_previous(const alpm_list_t *list,
+ const alpm_list_t *node)
+{
+ if(node && node != list) {
+ return node->prev;
+ } else {
+ return NULL;
+ }
+}
+
+/**
* @brief Get the last item in the list.
*
* @param list the list
diff --git a/lib/libalpm/alpm_list.h b/lib/libalpm/alpm_list.h
index 1f6393a6..27a76d12 100644
--- a/lib/libalpm/alpm_list.h
+++ b/lib/libalpm/alpm_list.h
@@ -70,6 +70,7 @@ alpm_list_t *alpm_list_reverse(alpm_list_t *list);
alpm_list_t *alpm_list_first(const alpm_list_t *list);
alpm_list_t *alpm_list_nth(const alpm_list_t *list, size_t n);
alpm_list_t *alpm_list_next(const alpm_list_t *list);
+alpm_list_t *alpm_list_previous(const alpm_list_t *list, const alpm_list_t *node);
alpm_list_t *alpm_list_last(const alpm_list_t *list);
void *alpm_list_getdata(const alpm_list_t *entry);
diff --git a/lib/libalpm/be_local.c b/lib/libalpm/be_local.c
index 304a5a13..70f242d2 100644
--- a/lib/libalpm/be_local.c
+++ b/lib/libalpm/be_local.c
@@ -498,6 +498,23 @@ static char *get_pkgpath(alpm_db_t *db, alpm_pkg_t *info)
return pkgpath;
}
+#define READ_NEXT() do { \
+ if(fgets(line, sizeof(line), fp) == NULL && !feof(fp)) goto error; \
+ _alpm_strtrim(line); \
+} while(0)
+
+#define READ_AND_STORE(f) do { \
+ READ_NEXT(); \
+ STRDUP(f, line, goto error); \
+} while(0)
+
+#define READ_AND_STORE_ALL(f) do { \
+ char *linedup; \
+ READ_NEXT(); \
+ if(strlen(line) == 0) break; \
+ STRDUP(linedup, line, goto error); \
+ f = alpm_list_add(f, linedup); \
+} while(1) /* note the while(1) and not (0) */
static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
{
@@ -539,116 +556,65 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
goto error;
}
while(!feof(fp)) {
- if(fgets(line, sizeof(line), fp) == NULL) {
- break;
- }
- _alpm_strtrim(line);
+ READ_NEXT();
if(strcmp(line, "%NAME%") == 0) {
- if(fgets(line, sizeof(line), fp) == NULL) {
- goto error;
- }
- if(strcmp(_alpm_strtrim(line), info->name) != 0) {
+ READ_NEXT();
+ if(strcmp(line, info->name) != 0) {
_alpm_log(db->handle, ALPM_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, sizeof(line), fp) == NULL) {
- goto error;
- }
- if(strcmp(_alpm_strtrim(line), info->version) != 0) {
+ READ_NEXT();
+ if(strcmp(line, info->version) != 0) {
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: version "
"mismatch on package %s\n"), db->treename, info->name);
}
} else if(strcmp(line, "%DESC%") == 0) {
- if(fgets(line, sizeof(line), fp) == NULL) {
- goto error;
- }
- STRDUP(info->desc, _alpm_strtrim(line), goto error);
+ READ_AND_STORE(info->desc);
} else if(strcmp(line, "%GROUPS%") == 0) {
- while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
- char *linedup;
- STRDUP(linedup, line, goto error);
- info->groups = alpm_list_add(info->groups, linedup);
- }
+ READ_AND_STORE_ALL(info->groups);
} else if(strcmp(line, "%URL%") == 0) {
- if(fgets(line, sizeof(line), fp) == NULL) {
- goto error;
- }
- STRDUP(info->url, _alpm_strtrim(line), goto error);
+ READ_AND_STORE(info->url);
} else if(strcmp(line, "%LICENSE%") == 0) {
- while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
- char *linedup;
- STRDUP(linedup, line, goto error);
- info->licenses = alpm_list_add(info->licenses, linedup);
- }
+ READ_AND_STORE_ALL(info->licenses);
} else if(strcmp(line, "%ARCH%") == 0) {
- if(fgets(line, sizeof(line), fp) == NULL) {
- goto error;
- }
- STRDUP(info->arch, _alpm_strtrim(line), goto error);
+ READ_AND_STORE(info->arch);
} else if(strcmp(line, "%BUILDDATE%") == 0) {
- if(fgets(line, sizeof(line), fp) == NULL) {
- goto error;
- }
- _alpm_strtrim(line);
+ READ_NEXT();
info->builddate = _alpm_parsedate(line);
} else if(strcmp(line, "%INSTALLDATE%") == 0) {
- if(fgets(line, sizeof(line), fp) == NULL) {
- goto error;
- }
- _alpm_strtrim(line);
+ READ_NEXT();
info->installdate = _alpm_parsedate(line);
} else if(strcmp(line, "%PACKAGER%") == 0) {
- if(fgets(line, sizeof(line), fp) == NULL) {
- goto error;
- }
- STRDUP(info->packager, _alpm_strtrim(line), goto error);
+ READ_AND_STORE(info->packager);
} else if(strcmp(line, "%REASON%") == 0) {
- if(fgets(line, sizeof(line), fp) == NULL) {
- goto error;
- }
- info->reason = (alpm_pkgreason_t)atol(_alpm_strtrim(line));
+ READ_NEXT();
+ info->reason = (alpm_pkgreason_t)atol(line);
} else if(strcmp(line, "%SIZE%") == 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.
*/
- if(fgets(line, sizeof(line), fp) == NULL) {
- goto error;
- }
- info->size = atol(_alpm_strtrim(line));
+ READ_NEXT();
+ info->size = atol(line);
/* also store this value to isize */
info->isize = info->size;
} else if(strcmp(line, "%REPLACES%") == 0) {
- while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
- char *linedup;
- STRDUP(linedup, line, goto error);
- info->replaces = alpm_list_add(info->replaces, linedup);
- }
+ READ_AND_STORE_ALL(info->replaces);
} else if(strcmp(line, "%DEPENDS%") == 0) {
- while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
- alpm_depend_t *dep = _alpm_splitdep(line);
- info->depends = alpm_list_add(info->depends, dep);
+ /* Different than the rest because of the _alpm_splitdep call. */
+ while(1) {
+ READ_NEXT();
+ if(strlen(line) == 0) break;
+ info->depends = alpm_list_add(info->depends, _alpm_splitdep(line));
}
} else if(strcmp(line, "%OPTDEPENDS%") == 0) {
- while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
- char *linedup;
- STRDUP(linedup, line, goto error);
- info->optdepends = alpm_list_add(info->optdepends, linedup);
- }
+ READ_AND_STORE_ALL(info->optdepends);
} else if(strcmp(line, "%CONFLICTS%") == 0) {
- while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
- char *linedup;
- STRDUP(linedup, line, goto error);
- info->conflicts = alpm_list_add(info->conflicts, linedup);
- }
+ READ_AND_STORE_ALL(info->conflicts);
} else if(strcmp(line, "%PROVIDES%") == 0) {
- while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
- char *linedup;
- STRDUP(linedup, line, goto error);
- info->provides = alpm_list_add(info->provides, linedup);
- }
+ READ_AND_STORE_ALL(info->provides);
}
}
fclose(fp);
@@ -666,9 +632,11 @@ static int local_db_read(alpm_pkg_t *info, alpm_dbinfrq_t inforeq)
_alpm_strtrim(line);
if(strcmp(line, "%FILES%") == 0) {
while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
- char *linedup;
- STRDUP(linedup, line, goto error);
- info->files = alpm_list_add(info->files, linedup);
+ alpm_file_t *file;
+ CALLOC(file, 1, sizeof(alpm_file_t), goto error);
+ STRDUP(file->name, line, goto error);
+ /* TODO: lstat file, get mode/size */
+ info->files = alpm_list_add(info->files, file);
}
} else if(strcmp(line, "%BACKUP%") == 0) {
while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) {
@@ -869,14 +837,15 @@ int _alpm_local_db_write(alpm_db_t *db, alpm_pkg_t *info, alpm_dbinfrq_t inforeq
if(info->files) {
fprintf(fp, "%%FILES%%\n");
for(lp = info->files; lp; lp = lp->next) {
- fprintf(fp, "%s\n", (char *)lp->data);
+ const alpm_file_t *file = lp->data;
+ fprintf(fp, "%s\n", file->name);
}
fprintf(fp, "\n");
}
if(info->backup) {
fprintf(fp, "%%BACKUP%%\n");
for(lp = info->backup; lp; lp = lp->next) {
- alpm_backup_t *backup = lp->data;
+ const alpm_backup_t *backup = lp->data;
fprintf(fp, "%s\t%s\n", backup->name, backup->hash);
}
fprintf(fp, "\n");
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index 16132144..af213241 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -328,7 +328,12 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
* already been handled (for future possibilities) */
} else if(full) {
/* Keep track of all files for filelist generation */
- newpkg->files = alpm_list_add(newpkg->files, strdup(entry_name));
+ alpm_file_t *file;
+ CALLOC(file, 1, sizeof(alpm_file_t), goto error);
+ STRDUP(file->name, entry_name, goto error);
+ file->size = archive_entry_size(entry);
+ file->mode = archive_entry_mode(entry);
+ newpkg->files = alpm_list_add(newpkg->files, file);
files_count++;
}
@@ -368,11 +373,14 @@ alpm_pkg_t *_alpm_pkg_load_internal(alpm_handle_t *handle, const char *pkgfile,
if(full) {
/* "checking for conflicts" requires a sorted list, ensure that here */
_alpm_log(handle, ALPM_LOG_DEBUG, "sorting package filelist for %s\n", pkgfile);
- newpkg->files = alpm_list_msort(newpkg->files, files_count, _alpm_str_cmp);
+ newpkg->files = alpm_list_msort(newpkg->files, files_count,
+ _alpm_files_cmp);
newpkg->infolevel = INFRQ_ALL;
} else {
/* get rid of any partial filelist we may have collected, it is invalid */
- FREELIST(newpkg->files);
+ alpm_list_free_inner(newpkg->files, (alpm_list_fn_free)_alpm_files_free);
+ alpm_list_free(newpkg->files);
+ newpkg->files = NULL;
newpkg->infolevel = INFRQ_BASE | INFRQ_DESC;
}
diff --git a/lib/libalpm/be_sync.c b/lib/libalpm/be_sync.c
index cda1e097..368accea 100644
--- a/lib/libalpm/be_sync.c
+++ b/lib/libalpm/be_sync.c
@@ -433,19 +433,19 @@ static int sync_db_populate(alpm_db_t *db)
return count;
}
-#define READ_NEXT(s) do { \
+#define READ_NEXT() do { \
if(_alpm_archive_fgets(archive, &buf) != ARCHIVE_OK) goto error; \
- s = _alpm_strtrim(buf.line); \
+ line = _alpm_strtrim(buf.line); \
} while(0)
#define READ_AND_STORE(f) do { \
- READ_NEXT(line); \
+ READ_NEXT(); \
STRDUP(f, line, goto error); \
} while(0)
#define READ_AND_STORE_ALL(f) do { \
char *linedup; \
- READ_NEXT(line); \
+ READ_NEXT(); \
if(strlen(line) == 0) break; \
STRDUP(linedup, line, goto error); \
f = alpm_list_add(f, linedup); \
@@ -488,13 +488,13 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
char *line = _alpm_strtrim(buf.line);
if(strcmp(line, "%NAME%") == 0) {
- READ_NEXT(line);
+ READ_NEXT();
if(strcmp(line, pkg->name) != 0) {
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: name "
"mismatch on package %s\n"), db->treename, pkg->name);
}
} else if(strcmp(line, "%VERSION%") == 0) {
- READ_NEXT(line);
+ READ_NEXT();
if(strcmp(line, pkg->version) != 0) {
_alpm_log(db->handle, ALPM_LOG_ERROR, _("%s database is inconsistent: version "
"mismatch on package %s\n"), db->treename, pkg->name);
@@ -512,7 +512,7 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
} else if(strcmp(line, "%ARCH%") == 0) {
READ_AND_STORE(pkg->arch);
} else if(strcmp(line, "%BUILDDATE%") == 0) {
- READ_NEXT(line);
+ READ_NEXT();
pkg->builddate = _alpm_parsedate(line);
} else if(strcmp(line, "%PACKAGER%") == 0) {
READ_AND_STORE(pkg->packager);
@@ -521,20 +521,20 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
* 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.
*/
- READ_NEXT(line);
+ READ_NEXT();
pkg->size = atol(line);
/* also store this value to isize if isize is unset */
if(pkg->isize == 0) {
pkg->isize = pkg->size;
}
} else if(strcmp(line, "%ISIZE%") == 0) {
- READ_NEXT(line);
+ READ_NEXT();
pkg->isize = atol(line);
} else if(strcmp(line, "%MD5SUM%") == 0) {
READ_AND_STORE(pkg->md5sum);
} else if(strcmp(line, "%SHA256SUM%") == 0) {
/* we don't do anything with this value right now */
- READ_NEXT(line);
+ READ_NEXT();
} else if(strcmp(line, "%PGPSIG%") == 0) {
READ_AND_STORE(pkg->base64_sig);
} else if(strcmp(line, "%REPLACES%") == 0) {
@@ -542,7 +542,7 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
} else if(strcmp(line, "%DEPENDS%") == 0) {
/* Different than the rest because of the _alpm_splitdep call. */
while(1) {
- READ_NEXT(line);
+ READ_NEXT();
if(strlen(line) == 0) break;
pkg->depends = alpm_list_add(pkg->depends, _alpm_splitdep(line));
}
@@ -555,7 +555,7 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
} else if(strcmp(line, "%DELTAS%") == 0) {
/* Different than the rest because of the _alpm_delta_parse call. */
while(1) {
- READ_NEXT(line);
+ READ_NEXT();
if(strlen(line) == 0) break;
pkg->deltas = alpm_list_add(pkg->deltas, _alpm_delta_parse(line));
}
diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
index ad689dcf..8cf16191 100644
--- a/lib/libalpm/conflict.c
+++ b/lib/libalpm/conflict.c
@@ -34,6 +34,7 @@
/* libalpm */
#include "conflict.h"
#include "alpm_list.h"
+#include "alpm.h"
#include "handle.h"
#include "trans.h"
#include "util.h"
@@ -222,6 +223,7 @@ static const int DIFFERENCE = 0;
static const int INTERSECT = 1;
/* Returns a set operation on the provided two lists of files.
* Pre-condition: both lists are sorted!
+ * When done, free the list but NOT the contained data.
*
* Operations:
* DIFFERENCE - a difference operation is performed. filesA - filesB.
@@ -234,8 +236,10 @@ static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB,
alpm_list_t *pA = filesA, *pB = filesB;
while(pA && pB) {
- const char *strA = pA->data;
- const char *strB = pB->data;
+ alpm_file_t *fileA = pA->data;
+ alpm_file_t *fileB = pB->data;
+ const char *strA = fileA->name;
+ const char *strB = fileB->name;
/* skip directories, we don't care about them */
if(strA[strlen(strA)-1] == '/') {
pA = pA->next;
@@ -246,7 +250,7 @@ static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB,
if(cmp < 0) {
if(operation == DIFFERENCE) {
/* item only in filesA, qualifies as a difference */
- ret = alpm_list_add(ret, strdup(strA));
+ ret = alpm_list_add(ret, fileA);
}
pA = pA->next;
} else if(cmp > 0) {
@@ -254,7 +258,7 @@ static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB,
} else {
if(operation == INTERSECT) {
/* item in both, qualifies as an intersect */
- ret = alpm_list_add(ret, strdup(strA));
+ ret = alpm_list_add(ret, fileA);
}
pA = pA->next;
pB = pB->next;
@@ -264,10 +268,11 @@ static alpm_list_t *filelist_operation(alpm_list_t *filesA, alpm_list_t *filesB,
/* if doing a difference, ensure we have completely emptied pA */
while(operation == DIFFERENCE && pA) {
- const char *strA = pA->data;
+ alpm_file_t *fileA = pA->data;
+ const char *strA = fileA->name;
/* skip directories */
if(strA[strlen(strA)-1] != '/') {
- ret = alpm_list_add(ret, strdup(strA));
+ ret = alpm_list_add(ret, fileA);
}
pA = pA->next;
}
@@ -314,13 +319,27 @@ void _alpm_fileconflict_free(alpm_fileconflict_t *conflict)
FREE(conflict);
}
+const alpm_file_t *_alpm_filelist_contains(const alpm_list_t *haystack,
+ const char *needle)
+{
+ const alpm_list_t *lp = haystack;
+ while(lp) {
+ const alpm_file_t *file = lp->data;
+ if(strcmp(file->name, needle) == 0) {
+ return file;
+ }
+ lp = lp->next;
+ }
+ return NULL;
+}
+
static int dir_belongsto_pkg(const char *root, const char *dirpath,
alpm_pkg_t *pkg)
{
- struct dirent *ent = NULL;
struct stat sbuf;
char path[PATH_MAX];
char abspath[PATH_MAX];
+ struct dirent *ent = NULL;
DIR *dir;
snprintf(abspath, PATH_MAX, "%s%s", root, dirpath);
@@ -328,6 +347,7 @@ static int dir_belongsto_pkg(const char *root, const char *dirpath,
if(dir == NULL) {
return 1;
}
+
while((ent = readdir(dir)) != NULL) {
const char *name = ent->d_name;
@@ -347,7 +367,7 @@ static int dir_belongsto_pkg(const char *root, const char *dirpath,
return 0;
}
} else {
- if(alpm_list_find_str(alpm_pkg_get_files(pkg), path)) {
+ if(_alpm_filelist_contains(alpm_pkg_get_files(pkg), path)) {
continue;
} else {
closedir(dir);
@@ -365,7 +385,7 @@ static int dir_belongsto_pkg(const char *root, const char *dirpath,
alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
alpm_list_t *upgrade, alpm_list_t *remove)
{
- alpm_list_t *i, *j, *conflicts = NULL;
+ alpm_list_t *i, *conflicts = NULL;
size_t numtargs = alpm_list_count(upgrade);
size_t current;
alpm_trans_t *trans = handle->trans;
@@ -379,14 +399,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
* here as we do when we actually extract files in add.c with our 12
* different cases. */
for(current = 0, i = upgrade; i; i = i->next, current++) {
- alpm_list_t *k, *tmpfiles;
- alpm_pkg_t *p1, *p2, *dbpkg;
- char path[PATH_MAX];
-
- p1 = i->data;
- if(!p1) {
- continue;
- }
+ alpm_pkg_t *p1 = i->data;
+ alpm_list_t *j, *tmpfiles;
+ alpm_pkg_t *dbpkg;
int percent = (current * 100) / numtargs;
PROGRESS(trans, ALPM_TRANS_PROGRESS_CONFLICTS_START, "", percent,
@@ -396,14 +411,13 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
alpm_pkg_get_name(p1));
for(j = i->next; j; j = j->next) {
alpm_list_t *common_files;
- p2 = j->data;
- if(!p2) {
- continue;
- }
+ alpm_pkg_t *p2 = j->data;
common_files = filelist_operation(alpm_pkg_get_files(p1),
alpm_pkg_get_files(p2), INTERSECT);
if(common_files) {
+ alpm_list_t *k;
+ char path[PATH_MAX];
for(k = common_files; k; k = k->next) {
snprintf(path, PATH_MAX, "%s%s", handle->root, (char *)k->data);
conflicts = add_fileconflict(handle, conflicts,
@@ -415,7 +429,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
return NULL;
}
}
- FREELIST(common_files);
+ alpm_list_free(common_files);
}
}
@@ -439,10 +453,14 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
}
for(j = tmpfiles; j; j = j->next) {
- struct stat lsbuf;
- const char *filestr = j->data, *relative_path;
+ alpm_file_t *file = j->data;
+ const char *filestr = file->name;
+ const char *relative_path;
+ alpm_list_t *k;
/* have we acted on this conflict? */
int resolved_conflict = 0;
+ struct stat lsbuf;
+ char path[PATH_MAX];
snprintf(path, PATH_MAX, "%s%s", handle->root, filestr);
@@ -451,7 +469,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
continue;
}
- if(path[strlen(path) - 1] == '/') {
+ if(S_ISDIR(file->mode)) {
struct stat sbuf;
if(S_ISDIR(lsbuf.st_mode)) {
_alpm_log(handle, ALPM_LOG_DEBUG, "%s is a directory, not a conflict\n", path);
@@ -475,32 +493,31 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
/* Check remove list (will we remove the conflicting local file?) */
for(k = remove; k && !resolved_conflict; k = k->next) {
alpm_pkg_t *rempkg = k->data;
- if(alpm_list_find_str(alpm_pkg_get_files(rempkg), relative_path)) {
+ if(rempkg && _alpm_filelist_contains(alpm_pkg_get_files(rempkg),
+ relative_path)) {
_alpm_log(handle, ALPM_LOG_DEBUG,
- "local file will be removed, not a conflict: %s\n",
- relative_path);
+ "local file will be removed, not a conflict: %s\n", path);
resolved_conflict = 1;
}
}
/* Look at all the targets to see if file has changed hands */
for(k = upgrade; k && !resolved_conflict; k = k->next) {
- p2 = k->data;
+ alpm_pkg_t *p2 = k->data;
if(!p2 || strcmp(p1->name, p2->name) == 0) {
continue;
}
alpm_pkg_t *localp2 = _alpm_db_get_pkgfromcache(handle->db_local, p2->name);
/* localp2->files will be removed (target conflicts are handled by CHECK 1) */
- if(localp2 && alpm_list_find_str(alpm_pkg_get_files(localp2), filestr)) {
+ if(localp2 && _alpm_filelist_contains(alpm_pkg_get_files(localp2), filestr)) {
/* skip removal of file, but not add. this will prevent a second
* package from removing the file when it was already installed
* by its new owner (whether the file is in backup array or not */
handle->trans->skip_remove =
alpm_list_add(handle->trans->skip_remove, strdup(filestr));
_alpm_log(handle, ALPM_LOG_DEBUG,
- "file changed packages, adding to remove skiplist: %s\n",
- filestr);
+ "file changed packages, adding to remove skiplist: %s\n", path);
resolved_conflict = 1;
}
}
@@ -509,7 +526,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
if(!resolved_conflict && S_ISDIR(lsbuf.st_mode) && dbpkg) {
char *dir = malloc(strlen(filestr) + 2);
sprintf(dir, "%s/", filestr);
- if(alpm_list_find_str(alpm_pkg_get_files(dbpkg),dir)) {
+ if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), dir)) {
_alpm_log(handle, ALPM_LOG_DEBUG,
"check if all files in %s belongs to %s\n",
dir, dbpkg->name);
@@ -526,7 +543,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
continue;
}
relative_rpath = rpath + strlen(handle->root);
- if(alpm_list_find_str(alpm_pkg_get_files(dbpkg), relative_rpath)) {
+ if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), relative_rpath)) {
resolved_conflict = 1;
}
free(rpath);
@@ -539,7 +556,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
FREELIST(conflicts);
if(dbpkg) {
/* only freed if it was generated from filelist_operation() */
- FREELIST(tmpfiles);
+ alpm_list_free(tmpfiles);
}
return NULL;
}
@@ -547,7 +564,7 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
}
if(dbpkg) {
/* only freed if it was generated from filelist_operation() */
- FREELIST(tmpfiles);
+ alpm_list_free(tmpfiles);
}
}
PROGRESS(trans, ALPM_TRANS_PROGRESS_CONFLICTS_START, "", 100,
diff --git a/lib/libalpm/conflict.h b/lib/libalpm/conflict.h
index 6c13cb28..f2ab6258 100644
--- a/lib/libalpm/conflict.h
+++ b/lib/libalpm/conflict.h
@@ -33,6 +33,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
void _alpm_fileconflict_free(alpm_fileconflict_t *conflict);
+const alpm_file_t *_alpm_filelist_contains(const alpm_list_t *haystack,
+ const char *needle);
+
#endif /* _ALPM_CONFLICT_H */
/* vim: set ts=2 sw=2 noet: */
diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c
index 0319d291..c3681b34 100644
--- a/lib/libalpm/deps.c
+++ b/lib/libalpm/deps.c
@@ -269,22 +269,20 @@ alpm_list_t SYMEXPORT *alpm_checkdeps(alpm_handle_t *handle, alpm_list_t *pkglis
alpm_list_t *remove, alpm_list_t *upgrade, int reversedeps)
{
alpm_list_t *i, *j;
- alpm_list_t *targets, *dblist = NULL, *modified = NULL;
+ alpm_list_t *dblist = NULL, *modified = NULL;
alpm_list_t *baddeps = NULL;
int nodepversion;
CHECK_HANDLE(handle, return NULL);
- targets = alpm_list_join(alpm_list_copy(remove), alpm_list_copy(upgrade));
for(i = pkglist; i; i = i->next) {
alpm_pkg_t *pkg = i->data;
- if(_alpm_pkg_find(targets, pkg->name)) {
+ if(_alpm_pkg_find(remove, pkg->name) || _alpm_pkg_find(upgrade, pkg->name)) {
modified = alpm_list_add(modified, pkg);
} else {
dblist = alpm_list_add(dblist, pkg);
}
}
- alpm_list_free(targets);
nodepversion = no_dep_version(handle);
diff --git a/lib/libalpm/diskspace.c b/lib/libalpm/diskspace.c
index 52364a0e..3ab62a86 100644
--- a/lib/libalpm/diskspace.c
+++ b/lib/libalpm/diskspace.c
@@ -39,10 +39,6 @@
#include <sys/types.h>
#endif
-/* libarchive */
-#include <archive.h>
-#include <archive_entry.h>
-
/* libalpm */
#include "diskspace.h"
#include "alpm_list.h"
@@ -151,14 +147,15 @@ static alpm_mountpoint_t *match_mount_point(const alpm_list_t *mount_points,
static int calculate_removed_size(alpm_handle_t *handle,
const alpm_list_t *mount_points, alpm_pkg_t *pkg)
{
- alpm_list_t *file;
+ alpm_list_t *i;
alpm_list_t *files = alpm_pkg_get_files(pkg);
- for(file = files; file; file = file->next) {
+ for(i = files; i; i = i->next) {
alpm_mountpoint_t *mp;
struct stat st;
char path[PATH_MAX];
- const char *filename = file->data;
+ const alpm_file_t *file = i->data;
+ const char *filename = file->name;
snprintf(path, PATH_MAX, "%s%s", handle->root, filename);
_alpm_lstat(path, &st);
@@ -188,39 +185,19 @@ static int calculate_removed_size(alpm_handle_t *handle,
static int calculate_installed_size(alpm_handle_t *handle,
const alpm_list_t *mount_points, alpm_pkg_t *pkg)
{
- int ret=0;
- struct archive *archive;
- struct archive_entry *entry;
-
- if((archive = archive_read_new()) == NULL) {
- handle->pm_errno = ALPM_ERR_LIBARCHIVE;
- ret = -1;
- goto cleanup;
- }
-
- archive_read_support_compression_all(archive);
- archive_read_support_format_all(archive);
-
- if(archive_read_open_filename(archive, pkg->origin_data.file,
- ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
- handle->pm_errno = ALPM_ERR_PKG_OPEN;
- ret = -1;
- goto cleanup;
- }
+ alpm_list_t *i;
- while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
+ for(i = alpm_pkg_get_files(pkg); i; i = i->next) {
+ const alpm_file_t *file = i->data;
alpm_mountpoint_t *mp;
- const char *filename;
- mode_t mode;
char path[PATH_MAX];
- filename = archive_entry_pathname(entry);
- mode = archive_entry_mode(entry);
+ const char *filename = file->name;
/* libarchive reports these as zero size anyways */
/* NOTE: if we do start accounting for directory size, a dir matching a
* mountpoint needs to be attributed to the parent, not the mountpoint. */
- if(S_ISDIR(mode) || S_ISLNK(mode)) {
+ if(S_ISDIR(file->mode) || S_ISLNK(file->mode)) {
continue;
}
@@ -240,21 +217,11 @@ static int calculate_installed_size(alpm_handle_t *handle,
/* the addition of (divisor - 1) performs ceil() with integer division */
mp->blocks_needed +=
- (archive_entry_size(entry) + mp->fsp.f_bsize - 1l) / mp->fsp.f_bsize;
+ (file->size + mp->fsp.f_bsize - 1l) / mp->fsp.f_bsize;
mp->used |= USED_INSTALL;
-
- if(archive_read_data_skip(archive)) {
- _alpm_log(handle, ALPM_LOG_ERROR, _("error while reading package %s: %s\n"),
- pkg->name, archive_error_string(archive));
- handle->pm_errno = ALPM_ERR_LIBARCHIVE;
- break;
- }
}
- archive_read_finish(archive);
-
-cleanup:
- return ret;
+ return 0;
}
int _alpm_check_diskspace(alpm_handle_t *handle)
diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c
index dc8ee395..c7a1c2b2 100644
--- a/lib/libalpm/dload.c
+++ b/lib/libalpm/dload.c
@@ -211,7 +211,7 @@ static int curl_download_internal(alpm_handle_t *handle,
/* a previous partial download exists, resume from end of file. */
open_mode = "ab";
curl_easy_setopt(handle->curl, CURLOPT_RESUME_FROM, (long)st.st_size);
- _alpm_log(handle, ALPM_LOG_DEBUG, "tempfile found, attempting continuation");
+ _alpm_log(handle, ALPM_LOG_DEBUG, "tempfile found, attempting continuation\n");
dlfile.initial_size = (double)st.st_size;
}
diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c
index 28fa08cb..ae9b9a9d 100644
--- a/lib/libalpm/package.c
+++ b/lib/libalpm/package.c
@@ -427,6 +427,33 @@ alpm_list_t SYMEXPORT *alpm_pkg_compute_requiredby(alpm_pkg_t *pkg)
/** @} */
+void _alpm_files_free(alpm_file_t *file)
+{
+ free(file->name);
+ free(file);
+}
+
+alpm_file_t *_alpm_files_dup(const alpm_file_t *file)
+{
+ alpm_file_t *newfile;
+ CALLOC(newfile, 1, sizeof(alpm_file_t), return NULL);
+
+ STRDUP(newfile->name, file->name, return NULL);
+ newfile->size = file->size;
+ newfile->mode = file->mode;
+
+ return newfile;
+}
+
+/* Helper function for comparing files list entries
+ */
+int _alpm_files_cmp(const void *f1, const void *f2)
+{
+ const alpm_file_t *file1 = f1;
+ const alpm_file_t *file2 = f2;
+ return strcmp(file1->name, file2->name);
+}
+
alpm_pkg_t *_alpm_pkg_new(void)
{
alpm_pkg_t* pkg;
@@ -466,7 +493,9 @@ alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg)
newpkg->licenses = alpm_list_strdup(pkg->licenses);
newpkg->replaces = alpm_list_strdup(pkg->replaces);
newpkg->groups = alpm_list_strdup(pkg->groups);
- newpkg->files = alpm_list_strdup(pkg->files);
+ for(i = pkg->files; i; i = alpm_list_next(i)) {
+ newpkg->files = alpm_list_add(newpkg->files, _alpm_files_dup(i->data));
+ }
for(i = pkg->backup; i; i = alpm_list_next(i)) {
newpkg->backup = alpm_list_add(newpkg->backup, _alpm_backup_dup(i->data));
}
@@ -516,7 +545,8 @@ void _alpm_pkg_free(alpm_pkg_t *pkg)
FREELIST(pkg->licenses);
FREELIST(pkg->replaces);
FREELIST(pkg->groups);
- FREELIST(pkg->files);
+ alpm_list_free_inner(pkg->files, (alpm_list_fn_free)_alpm_files_free);
+ alpm_list_free(pkg->files);
alpm_list_free_inner(pkg->backup, (alpm_list_fn_free)_alpm_backup_free);
alpm_list_free(pkg->backup);
alpm_list_free_inner(pkg->depends, (alpm_list_fn_free)_alpm_dep_free);
@@ -566,8 +596,8 @@ int _alpm_pkg_compare_versions(alpm_pkg_t *spkg, alpm_pkg_t *localpkg)
*/
int _alpm_pkg_cmp(const void *p1, const void *p2)
{
- alpm_pkg_t *pkg1 = (alpm_pkg_t *)p1;
- alpm_pkg_t *pkg2 = (alpm_pkg_t *)p2;
+ const alpm_pkg_t *pkg1 = p1;
+ const alpm_pkg_t *pkg2 = p2;
return strcoll(pkg1->name, pkg2->name);
}
diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h
index 772c2f62..b6021939 100644
--- a/lib/libalpm/package.h
+++ b/lib/libalpm/package.h
@@ -139,6 +139,10 @@ struct __alpm_pkg_t {
struct pkg_operations *ops;
};
+void _alpm_files_free(alpm_file_t *file);
+alpm_file_t *_alpm_files_dup(const alpm_file_t *file);
+int _alpm_files_cmp(const void *f1, const void *f2);
+
alpm_pkg_t* _alpm_pkg_new(void);
alpm_pkg_t *_alpm_pkg_dup(alpm_pkg_t *pkg);
void _alpm_pkg_free(alpm_pkg_t *pkg);
diff --git a/lib/libalpm/remove.c b/lib/libalpm/remove.c
index 2d6fcf64..59374dcb 100644
--- a/lib/libalpm/remove.c
+++ b/lib/libalpm/remove.c
@@ -43,6 +43,7 @@
#include "db.h"
#include "deps.h"
#include "handle.h"
+#include "conflict.h"
int SYMEXPORT alpm_remove_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg)
{
@@ -191,25 +192,25 @@ int _alpm_remove_prepare(alpm_handle_t *handle, alpm_list_t **data)
return 0;
}
-static int can_remove_file(alpm_handle_t *handle, const char *path,
+static int can_remove_file(alpm_handle_t *handle, const alpm_file_t *file,
alpm_list_t *skip_remove)
{
- char file[PATH_MAX];
+ char filepath[PATH_MAX];
- snprintf(file, PATH_MAX, "%s%s", handle->root, path);
+ snprintf(filepath, PATH_MAX, "%s%s", handle->root, file->name);
- if(alpm_list_find_str(skip_remove, file)) {
+ if(alpm_list_find_str(skip_remove, filepath)) {
/* return success because we will never actually remove this file */
return 1;
}
/* If we fail write permissions due to a read-only filesystem, abort.
* Assume all other possible failures are covered somewhere else */
- if(access(file, W_OK) == -1) {
- if(errno != EACCES && errno != ETXTBSY && access(file, F_OK) == 0) {
+ if(access(filepath, W_OK) == -1) {
+ if(errno != EACCES && errno != ETXTBSY && access(filepath, F_OK) == 0) {
/* only return failure if the file ACTUALLY exists and we can't write to
* it - ignore "chmod -w" simple permission failures */
_alpm_log(handle, ALPM_LOG_ERROR, _("cannot remove file '%s': %s\n"),
- file, strerror(errno));
+ filepath, strerror(errno));
return 0;
}
}
@@ -219,18 +220,18 @@ static int can_remove_file(alpm_handle_t *handle, const char *path,
/* Helper function for iterating through a package's file and deleting them
* Used by _alpm_remove_commit. */
-static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, const char *filename,
- alpm_list_t *skip_remove, int nosave)
+static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info,
+ const alpm_file_t *fileobj, alpm_list_t *skip_remove, int nosave)
{
struct stat buf;
char file[PATH_MAX];
- snprintf(file, PATH_MAX, "%s%s", handle->root, filename);
+ snprintf(file, PATH_MAX, "%s%s", handle->root, fileobj->name);
/* check the remove skip list before removing the file.
* see the big comment block in db_find_fileconflicts() for an
* explanation. */
- if(alpm_list_find_str(skip_remove, filename)) {
+ if(alpm_list_find_str(skip_remove, fileobj->name)) {
_alpm_log(handle, ALPM_LOG_DEBUG, "%s is in skip_remove, skipping removal\n",
file);
return;
@@ -254,7 +255,7 @@ static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, const char *fil
}
} else {
/* if the file needs backup and has been modified, back it up to .pacsave */
- alpm_backup_t *backup = _alpm_needbackup(filename, alpm_pkg_get_backup(info));
+ alpm_backup_t *backup = _alpm_needbackup(fileobj->name, alpm_pkg_get_backup(info));
if(backup) {
if(nosave) {
_alpm_log(handle, ALPM_LOG_DEBUG, "transaction is set to NOSAVE, not backing up '%s'\n", file);
@@ -277,7 +278,7 @@ static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, const char *fil
if(unlink(file) == -1) {
_alpm_log(handle, ALPM_LOG_ERROR, _("cannot remove file '%s': %s\n"),
- filename, strerror(errno));
+ file, strerror(errno));
}
}
}
@@ -285,8 +286,7 @@ static void unlink_file(alpm_handle_t *handle, alpm_pkg_t *info, const char *fil
int _alpm_upgraderemove_package(alpm_handle_t *handle,
alpm_pkg_t *oldpkg, alpm_pkg_t *newpkg)
{
- alpm_list_t *skip_remove, *b;
- alpm_list_t *newfiles, *lp;
+ alpm_list_t *skip_remove, *b, *lp;
size_t filenum = 0;
alpm_list_t *files = alpm_pkg_get_files(oldpkg);
const char *pkgname = alpm_pkg_get_name(oldpkg);
@@ -309,7 +309,7 @@ int _alpm_upgraderemove_package(alpm_handle_t *handle,
for(b = alpm_pkg_get_backup(newpkg); b; b = b->next) {
const alpm_backup_t *backup = b->data;
/* safety check (fix the upgrade026 pactest) */
- if(!alpm_list_find_str(filelist, backup->name)) {
+ if(!_alpm_filelist_contains(filelist, backup->name)) {
continue;
}
_alpm_log(handle, ALPM_LOG_DEBUG, "adding %s to the skip_remove array\n",
@@ -329,11 +329,9 @@ int _alpm_upgraderemove_package(alpm_handle_t *handle,
_alpm_log(handle, ALPM_LOG_DEBUG, "removing %ld files\n", (unsigned long)filenum);
/* iterate through the list backwards, unlinking files */
- newfiles = alpm_list_reverse(files);
- for(lp = newfiles; lp; lp = alpm_list_next(lp)) {
+ for(lp = alpm_list_last(files); lp; lp = alpm_list_previous(files, lp)) {
unlink_file(handle, oldpkg, lp->data, skip_remove, 0);
}
- alpm_list_free(newfiles);
FREELIST(skip_remove);
db:
@@ -390,7 +388,6 @@ int _alpm_remove_packages(alpm_handle_t *handle)
if(!(trans->flags & ALPM_TRANS_FLAG_DBONLY)) {
alpm_list_t *files = alpm_pkg_get_files(info);
- alpm_list_t *newfiles;
size_t filenum = 0;
for(lp = files; lp; lp = lp->next) {
@@ -409,8 +406,7 @@ int _alpm_remove_packages(alpm_handle_t *handle)
pkg_count, (pkg_count - targcount + 1));
/* iterate through the list backwards, unlinking files */
- newfiles = alpm_list_reverse(files);
- for(lp = newfiles; lp; lp = alpm_list_next(lp)) {
+ for(lp = alpm_list_last(files); lp; lp = alpm_list_previous(files, lp)) {
int percent;
unlink_file(handle, info, lp->data, NULL, trans->flags & ALPM_TRANS_FLAG_NOSAVE);
@@ -420,7 +416,6 @@ int _alpm_remove_packages(alpm_handle_t *handle)
percent, pkg_count, (pkg_count - targcount + 1));
position++;
}
- alpm_list_free(newfiles);
}
/* set progress to 100% after we finish unlinking files */