Remove support for deltas from libalpm
Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
parent
e7bb0f8824
commit
c0e9be7973
15 changed files with 10 additions and 723 deletions
1
README
1
README
|
@ -58,7 +58,6 @@ library is initialized.
|
||||||
* progresscb: Callback to handle display of transaction progress.
|
* progresscb: Callback to handle display of transaction progress.
|
||||||
* gpgdir: Directory where GnuPG files are stored.
|
* gpgdir: Directory where GnuPG files are stored.
|
||||||
* arch: Allowed package architecture.
|
* arch: Allowed package architecture.
|
||||||
* deltaratio: Download deltas if possible; a ratio value.
|
|
||||||
* checkspace: Check disk space before installing.
|
* checkspace: Check disk space before installing.
|
||||||
* default_siglevel: Default signature verification level.
|
* default_siglevel: Default signature verification level.
|
||||||
* local_file_siglevel: Signature verification level for local file upgrades.
|
* local_file_siglevel: Signature verification level for local file upgrades.
|
||||||
|
|
|
@ -34,7 +34,6 @@ libalpm_la_SOURCES = \
|
||||||
be_sync.c \
|
be_sync.c \
|
||||||
conflict.h conflict.c \
|
conflict.h conflict.c \
|
||||||
db.h db.c \
|
db.h db.c \
|
||||||
delta.h delta.c \
|
|
||||||
deps.h deps.c \
|
deps.h deps.c \
|
||||||
diskspace.h diskspace.c \
|
diskspace.h diskspace.c \
|
||||||
dload.h dload.c \
|
dload.h dload.c \
|
||||||
|
|
|
@ -104,9 +104,6 @@ typedef enum _alpm_errno_t {
|
||||||
/* Signatures */
|
/* Signatures */
|
||||||
ALPM_ERR_SIG_MISSING,
|
ALPM_ERR_SIG_MISSING,
|
||||||
ALPM_ERR_SIG_INVALID,
|
ALPM_ERR_SIG_INVALID,
|
||||||
/* Deltas */
|
|
||||||
ALPM_ERR_DLT_INVALID,
|
|
||||||
ALPM_ERR_DLT_PATCHFAILED,
|
|
||||||
/* Dependencies */
|
/* Dependencies */
|
||||||
ALPM_ERR_UNSATISFIED_DEPS,
|
ALPM_ERR_UNSATISFIED_DEPS,
|
||||||
ALPM_ERR_CONFLICTING_DEPS,
|
ALPM_ERR_CONFLICTING_DEPS,
|
||||||
|
@ -273,22 +270,6 @@ typedef struct _alpm_group_t {
|
||||||
alpm_list_t *packages;
|
alpm_list_t *packages;
|
||||||
} alpm_group_t;
|
} alpm_group_t;
|
||||||
|
|
||||||
/** Package upgrade delta */
|
|
||||||
typedef struct _alpm_delta_t {
|
|
||||||
/** filename of the delta patch */
|
|
||||||
char *delta;
|
|
||||||
/** md5sum of the delta file */
|
|
||||||
char *delta_md5;
|
|
||||||
/** filename of the 'before' file */
|
|
||||||
char *from;
|
|
||||||
/** filename of the 'after' file */
|
|
||||||
char *to;
|
|
||||||
/** filesize of the delta file */
|
|
||||||
off_t delta_size;
|
|
||||||
/** download filesize of the delta file */
|
|
||||||
off_t download_size;
|
|
||||||
} alpm_delta_t;
|
|
||||||
|
|
||||||
/** File in a package */
|
/** File in a package */
|
||||||
typedef struct _alpm_file_t {
|
typedef struct _alpm_file_t {
|
||||||
char *name;
|
char *name;
|
||||||
|
@ -405,21 +386,6 @@ typedef enum _alpm_event_type_t {
|
||||||
ALPM_EVENT_LOAD_START,
|
ALPM_EVENT_LOAD_START,
|
||||||
/** Target package is finished loading. */
|
/** Target package is finished loading. */
|
||||||
ALPM_EVENT_LOAD_DONE,
|
ALPM_EVENT_LOAD_DONE,
|
||||||
/** Target delta's integrity will be checked. */
|
|
||||||
ALPM_EVENT_DELTA_INTEGRITY_START,
|
|
||||||
/** Target delta's integrity was checked. */
|
|
||||||
ALPM_EVENT_DELTA_INTEGRITY_DONE,
|
|
||||||
/** Deltas will be applied to packages. */
|
|
||||||
ALPM_EVENT_DELTA_PATCHES_START,
|
|
||||||
/** Deltas were applied to packages. */
|
|
||||||
ALPM_EVENT_DELTA_PATCHES_DONE,
|
|
||||||
/** Delta patch will be applied to target package; See
|
|
||||||
* alpm_event_delta_patch_t for arguments.. */
|
|
||||||
ALPM_EVENT_DELTA_PATCH_START,
|
|
||||||
/** Delta patch was applied to target package. */
|
|
||||||
ALPM_EVENT_DELTA_PATCH_DONE,
|
|
||||||
/** Delta patch failed to apply to target package. */
|
|
||||||
ALPM_EVENT_DELTA_PATCH_FAILED,
|
|
||||||
/** Scriptlet has printed information; See alpm_event_scriptlet_info_t for
|
/** Scriptlet has printed information; See alpm_event_scriptlet_info_t for
|
||||||
* arguments. */
|
* arguments. */
|
||||||
ALPM_EVENT_SCRIPTLET_INFO,
|
ALPM_EVENT_SCRIPTLET_INFO,
|
||||||
|
@ -509,13 +475,6 @@ typedef struct _alpm_event_optdep_removal_t {
|
||||||
alpm_depend_t *optdep;
|
alpm_depend_t *optdep;
|
||||||
} alpm_event_optdep_removal_t;
|
} alpm_event_optdep_removal_t;
|
||||||
|
|
||||||
typedef struct _alpm_event_delta_patch_t {
|
|
||||||
/** Type of event. */
|
|
||||||
alpm_event_type_t type;
|
|
||||||
/** Delta info */
|
|
||||||
alpm_delta_t *delta;
|
|
||||||
} alpm_event_delta_patch_t;
|
|
||||||
|
|
||||||
typedef struct _alpm_event_scriptlet_info_t {
|
typedef struct _alpm_event_scriptlet_info_t {
|
||||||
/** Type of event. */
|
/** Type of event. */
|
||||||
alpm_event_type_t type;
|
alpm_event_type_t type;
|
||||||
|
@ -589,7 +548,6 @@ typedef union _alpm_event_t {
|
||||||
alpm_event_any_t any;
|
alpm_event_any_t any;
|
||||||
alpm_event_package_operation_t package_operation;
|
alpm_event_package_operation_t package_operation;
|
||||||
alpm_event_optdep_removal_t optdep_removal;
|
alpm_event_optdep_removal_t optdep_removal;
|
||||||
alpm_event_delta_patch_t delta_patch;
|
|
||||||
alpm_event_scriptlet_info_t scriptlet_info;
|
alpm_event_scriptlet_info_t scriptlet_info;
|
||||||
alpm_event_database_missing_t database_missing;
|
alpm_event_database_missing_t database_missing;
|
||||||
alpm_event_pkgdownload_t pkgdownload;
|
alpm_event_pkgdownload_t pkgdownload;
|
||||||
|
@ -915,9 +873,6 @@ const char *alpm_option_get_arch(alpm_handle_t *handle);
|
||||||
/** Sets the targeted architecture. */
|
/** Sets the targeted architecture. */
|
||||||
int alpm_option_set_arch(alpm_handle_t *handle, const char *arch);
|
int alpm_option_set_arch(alpm_handle_t *handle, const char *arch);
|
||||||
|
|
||||||
double alpm_option_get_deltaratio(alpm_handle_t *handle);
|
|
||||||
int alpm_option_set_deltaratio(alpm_handle_t *handle, double ratio);
|
|
||||||
|
|
||||||
int alpm_option_get_checkspace(alpm_handle_t *handle);
|
int alpm_option_get_checkspace(alpm_handle_t *handle);
|
||||||
int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace);
|
int alpm_option_set_checkspace(alpm_handle_t *handle, int checkspace);
|
||||||
|
|
||||||
|
@ -1294,12 +1249,6 @@ alpm_list_t *alpm_pkg_get_conflicts(alpm_pkg_t *pkg);
|
||||||
*/
|
*/
|
||||||
alpm_list_t *alpm_pkg_get_provides(alpm_pkg_t *pkg);
|
alpm_list_t *alpm_pkg_get_provides(alpm_pkg_t *pkg);
|
||||||
|
|
||||||
/** Returns the list of available deltas for pkg.
|
|
||||||
* @param pkg a pointer to package
|
|
||||||
* @return a reference to an internal list of strings.
|
|
||||||
*/
|
|
||||||
alpm_list_t *alpm_pkg_get_deltas(alpm_pkg_t *pkg);
|
|
||||||
|
|
||||||
/** Returns the list of packages to be replaced by pkg.
|
/** Returns the list of packages to be replaced by pkg.
|
||||||
* @param pkg a pointer to package
|
* @param pkg a pointer to package
|
||||||
* @return a reference to an internal list of alpm_depend_t structures.
|
* @return a reference to an internal list of alpm_depend_t structures.
|
||||||
|
@ -1397,8 +1346,6 @@ int alpm_pkg_has_scriptlet(alpm_pkg_t *pkg);
|
||||||
*/
|
*/
|
||||||
off_t alpm_pkg_download_size(alpm_pkg_t *newpkg);
|
off_t alpm_pkg_download_size(alpm_pkg_t *newpkg);
|
||||||
|
|
||||||
alpm_list_t *alpm_pkg_unused_deltas(alpm_pkg_t *pkg);
|
|
||||||
|
|
||||||
/** Set install reason for a package in the local database.
|
/** Set install reason for a package in the local database.
|
||||||
* The provided package object must be from the local database or this method
|
* The provided package object must be from the local database or this method
|
||||||
* will fail. The write to the local database is performed immediately.
|
* will fail. The write to the local database is performed immediately.
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
#include "alpm_list.h"
|
#include "alpm_list.h"
|
||||||
#include "package.h"
|
#include "package.h"
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
#include "delta.h"
|
|
||||||
#include "deps.h"
|
#include "deps.h"
|
||||||
#include "dload.h"
|
#include "dload.h"
|
||||||
#include "filelist.h"
|
#include "filelist.h"
|
||||||
|
@ -427,9 +426,8 @@ static alpm_pkg_t *load_pkg_for_entry(alpm_db_t *db, const char *entryname,
|
||||||
|
|
||||||
/* This function doesn't work as well as one might think, as size of database
|
/* This function doesn't work as well as one might think, as size of database
|
||||||
* entries varies considerably. Adding signatures nearly doubles the size of a
|
* entries varies considerably. Adding signatures nearly doubles the size of a
|
||||||
* single entry; deltas also can make for large variations in size. These
|
* single entry. These current values are heavily influenced by Arch Linux;
|
||||||
* current values are heavily influenced by Arch Linux; databases with no
|
* databases with a single signature per package. */
|
||||||
* deltas and a single signature per package. */
|
|
||||||
static size_t estimate_package_count(struct stat *st, struct archive *archive)
|
static size_t estimate_package_count(struct stat *st, struct archive *archive)
|
||||||
{
|
{
|
||||||
int per_package;
|
int per_package;
|
||||||
|
@ -511,7 +509,7 @@ static int sync_db_populate(alpm_db_t *db)
|
||||||
while((archive_ret = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) {
|
while((archive_ret = archive_read_next_header(archive, &entry)) == ARCHIVE_OK) {
|
||||||
mode_t mode = archive_entry_mode(entry);
|
mode_t mode = archive_entry_mode(entry);
|
||||||
if(!S_ISDIR(mode)) {
|
if(!S_ISDIR(mode)) {
|
||||||
/* we have desc, depends or deltas - parse it */
|
/* we have desc or depends - parse it */
|
||||||
if(sync_db_read(db, archive, entry, &pkg) != 0) {
|
if(sync_db_read(db, archive, entry, &pkg) != 0) {
|
||||||
_alpm_log(db->handle, ALPM_LOG_ERROR,
|
_alpm_log(db->handle, ALPM_LOG_ERROR,
|
||||||
_("could not parse package description file '%s' from db '%s'\n"),
|
_("could not parse package description file '%s' from db '%s'\n"),
|
||||||
|
@ -637,8 +635,7 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
|
if(strcmp(filename, "desc") == 0 || strcmp(filename, "depends") == 0
|
||||||
|| strcmp(filename, "files") == 0
|
|| strcmp(filename, "files") == 0) {
|
||||||
|| (strcmp(filename, "deltas") == 0 && db->handle->deltaratio > 0.0) ) {
|
|
||||||
int ret;
|
int ret;
|
||||||
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
|
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
|
||||||
char *line = buf.line;
|
char *line = buf.line;
|
||||||
|
@ -707,14 +704,6 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||||
READ_AND_SPLITDEP(pkg->conflicts);
|
READ_AND_SPLITDEP(pkg->conflicts);
|
||||||
} else if(strcmp(line, "%PROVIDES%") == 0) {
|
} else if(strcmp(line, "%PROVIDES%") == 0) {
|
||||||
READ_AND_SPLITDEP(pkg->provides);
|
READ_AND_SPLITDEP(pkg->provides);
|
||||||
} else if(strcmp(line, "%DELTAS%") == 0) {
|
|
||||||
/* Different than the rest because of the _alpm_delta_parse call. */
|
|
||||||
while(1) {
|
|
||||||
READ_NEXT();
|
|
||||||
if(strlen(line) == 0) break;
|
|
||||||
pkg->deltas = alpm_list_add(pkg->deltas,
|
|
||||||
_alpm_delta_parse(db->handle, line));
|
|
||||||
}
|
|
||||||
} else if(strcmp(line, "%FILES%") == 0) {
|
} else if(strcmp(line, "%FILES%") == 0) {
|
||||||
/* TODO: this could lazy load if there is future demand */
|
/* TODO: this could lazy load if there is future demand */
|
||||||
size_t files_count = 0, files_size = 0;
|
size_t files_count = 0, files_size = 0;
|
||||||
|
@ -751,8 +740,6 @@ static int sync_db_read(alpm_db_t *db, struct archive *archive,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
*likely_pkg = pkg;
|
*likely_pkg = pkg;
|
||||||
} else if(strcmp(filename, "deltas") == 0) {
|
|
||||||
/* skip reading delta files if UseDelta is unset */
|
|
||||||
} else {
|
} else {
|
||||||
/* unknown database file */
|
/* unknown database file */
|
||||||
_alpm_log(db->handle, ALPM_LOG_DEBUG, "unknown database file: %s\n", filename);
|
_alpm_log(db->handle, ALPM_LOG_DEBUG, "unknown database file: %s\n", filename);
|
||||||
|
|
|
@ -1,361 +0,0 @@
|
||||||
/*
|
|
||||||
* delta.c
|
|
||||||
*
|
|
||||||
* Copyright (c) 2006-2018 Pacman Development Team <pacman-dev@archlinux.org>
|
|
||||||
* Copyright (c) 2007-2006 by Judd Vinet <jvinet@zeroflux.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h> /* intmax_t */
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <regex.h>
|
|
||||||
|
|
||||||
/* libalpm */
|
|
||||||
#include "delta.h"
|
|
||||||
#include "alpm_list.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "graph.h"
|
|
||||||
|
|
||||||
static alpm_list_t *graph_init(alpm_list_t *deltas, int reverse)
|
|
||||||
{
|
|
||||||
alpm_list_t *i, *j;
|
|
||||||
alpm_list_t *vertices = NULL;
|
|
||||||
/* create the vertices */
|
|
||||||
for(i = deltas; i; i = i->next) {
|
|
||||||
alpm_graph_t *v = _alpm_graph_new();
|
|
||||||
if(!v) {
|
|
||||||
alpm_list_free(vertices);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
alpm_delta_t *vdelta = i->data;
|
|
||||||
vdelta->download_size = vdelta->delta_size;
|
|
||||||
v->weight = LONG_MAX;
|
|
||||||
v->data = vdelta;
|
|
||||||
vertices = alpm_list_add(vertices, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* compute the edges */
|
|
||||||
for(i = vertices; i; i = i->next) {
|
|
||||||
alpm_graph_t *v_i = i->data;
|
|
||||||
alpm_delta_t *d_i = v_i->data;
|
|
||||||
/* loop a second time so we make all possible comparisons */
|
|
||||||
for(j = vertices; j; j = j->next) {
|
|
||||||
alpm_graph_t *v_j = j->data;
|
|
||||||
alpm_delta_t *d_j = v_j->data;
|
|
||||||
/* We want to create a delta tree like the following:
|
|
||||||
* 1_to_2
|
|
||||||
* |
|
|
||||||
* 1_to_3 2_to_3
|
|
||||||
* \ /
|
|
||||||
* 3_to_4
|
|
||||||
* If J 'from' is equal to I 'to', then J is a child of I.
|
|
||||||
* */
|
|
||||||
if((!reverse && strcmp(d_j->from, d_i->to) == 0) ||
|
|
||||||
(reverse && strcmp(d_j->to, d_i->from) == 0)) {
|
|
||||||
v_i->children = alpm_list_add(v_i->children, v_j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
v_i->iterator = v_i->children;
|
|
||||||
}
|
|
||||||
return vertices;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void graph_init_size(alpm_handle_t *handle, alpm_list_t *vertices)
|
|
||||||
{
|
|
||||||
alpm_list_t *i;
|
|
||||||
|
|
||||||
for(i = vertices; i; i = i->next) {
|
|
||||||
char *fpath, *md5sum;
|
|
||||||
alpm_graph_t *v = i->data;
|
|
||||||
alpm_delta_t *vdelta = v->data;
|
|
||||||
|
|
||||||
/* determine whether the delta file already exists */
|
|
||||||
fpath = _alpm_filecache_find(handle, vdelta->delta);
|
|
||||||
if(fpath) {
|
|
||||||
md5sum = alpm_compute_md5sum(fpath);
|
|
||||||
if(md5sum && strcmp(md5sum, vdelta->delta_md5) == 0) {
|
|
||||||
vdelta->download_size = 0;
|
|
||||||
}
|
|
||||||
FREE(md5sum);
|
|
||||||
FREE(fpath);
|
|
||||||
} else {
|
|
||||||
char *fnamepart;
|
|
||||||
CALLOC(fnamepart, strlen(vdelta->delta) + 6, sizeof(char), return);
|
|
||||||
sprintf(fnamepart, "%s.part", vdelta->delta);
|
|
||||||
fpath = _alpm_filecache_find(handle, fnamepart);
|
|
||||||
if(fpath) {
|
|
||||||
struct stat st;
|
|
||||||
if(stat(fpath, &st) == 0) {
|
|
||||||
vdelta->download_size = vdelta->delta_size - st.st_size;
|
|
||||||
vdelta->download_size = vdelta->download_size < 0 ? 0 : vdelta->download_size;
|
|
||||||
}
|
|
||||||
FREE(fpath);
|
|
||||||
}
|
|
||||||
FREE(fnamepart);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* determine whether a base 'from' file exists */
|
|
||||||
fpath = _alpm_filecache_find(handle, vdelta->from);
|
|
||||||
if(fpath) {
|
|
||||||
v->weight = vdelta->download_size;
|
|
||||||
}
|
|
||||||
FREE(fpath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void dijkstra(alpm_list_t *vertices)
|
|
||||||
{
|
|
||||||
alpm_list_t *i;
|
|
||||||
alpm_graph_t *v;
|
|
||||||
while(1) {
|
|
||||||
v = NULL;
|
|
||||||
/* find the smallest vertice not visited yet */
|
|
||||||
for(i = vertices; i; i = i->next) {
|
|
||||||
alpm_graph_t *v_i = i->data;
|
|
||||||
|
|
||||||
if(v_i->state == ALPM_GRAPH_STATE_PROCESSING) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(v == NULL || v_i->weight < v->weight) {
|
|
||||||
v = v_i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(v == NULL || v->weight == LONG_MAX) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
v->state = ALPM_GRAPH_STATE_PROCESSING;
|
|
||||||
|
|
||||||
v->iterator = v->children;
|
|
||||||
while(v->iterator) {
|
|
||||||
alpm_graph_t *v_c = v->iterator->data;
|
|
||||||
alpm_delta_t *d_c = v_c->data;
|
|
||||||
if(v_c->weight > v->weight + d_c->download_size) {
|
|
||||||
v_c->weight = v->weight + d_c->download_size;
|
|
||||||
v_c->parent = v;
|
|
||||||
}
|
|
||||||
|
|
||||||
v->iterator = (v->iterator)->next;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static off_t shortest_path(alpm_list_t *vertices, const char *to, alpm_list_t **path)
|
|
||||||
{
|
|
||||||
alpm_list_t *i;
|
|
||||||
alpm_graph_t *v = NULL;
|
|
||||||
off_t bestsize = 0;
|
|
||||||
alpm_list_t *rpath = NULL;
|
|
||||||
|
|
||||||
for(i = vertices; i; i = i->next) {
|
|
||||||
alpm_graph_t *v_i = i->data;
|
|
||||||
alpm_delta_t *d_i = v_i->data;
|
|
||||||
|
|
||||||
if(strcmp(d_i->to, to) == 0) {
|
|
||||||
if(v == NULL || v_i->weight < v->weight) {
|
|
||||||
v = v_i;
|
|
||||||
bestsize = v->weight;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while(v != NULL) {
|
|
||||||
alpm_delta_t *vdelta = v->data;
|
|
||||||
rpath = alpm_list_add(rpath, vdelta);
|
|
||||||
v = v->parent;
|
|
||||||
}
|
|
||||||
*path = alpm_list_reverse(rpath);
|
|
||||||
alpm_list_free(rpath);
|
|
||||||
|
|
||||||
return bestsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Calculates the shortest path from one version to another.
|
|
||||||
* The shortest path is defined as the path with the smallest combined
|
|
||||||
* size, not the length of the path.
|
|
||||||
* @param handle the context handle
|
|
||||||
* @param deltas the list of alpm_delta_t * objects that a file has
|
|
||||||
* @param to the file to start the search at
|
|
||||||
* @param path the pointer to a list location where alpm_delta_t * objects that
|
|
||||||
* have the smallest size are placed. NULL is set if there is no path
|
|
||||||
* possible with the files available.
|
|
||||||
* @return the size of the path stored, or LONG_MAX if path is unfindable
|
|
||||||
*/
|
|
||||||
off_t _alpm_shortest_delta_path(alpm_handle_t *handle, alpm_list_t *deltas,
|
|
||||||
const char *to, alpm_list_t **path)
|
|
||||||
{
|
|
||||||
alpm_list_t *bestpath = NULL;
|
|
||||||
alpm_list_t *vertices;
|
|
||||||
off_t bestsize = LONG_MAX;
|
|
||||||
|
|
||||||
if(deltas == NULL) {
|
|
||||||
*path = NULL;
|
|
||||||
return bestsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
_alpm_log(handle, ALPM_LOG_DEBUG, "started delta shortest-path search for '%s'\n", to);
|
|
||||||
|
|
||||||
vertices = graph_init(deltas, 0);
|
|
||||||
graph_init_size(handle, vertices);
|
|
||||||
dijkstra(vertices);
|
|
||||||
bestsize = shortest_path(vertices, to, &bestpath);
|
|
||||||
|
|
||||||
_alpm_log(handle, ALPM_LOG_DEBUG, "delta shortest-path search complete : '%jd'\n", (intmax_t)bestsize);
|
|
||||||
|
|
||||||
alpm_list_free_inner(vertices, _alpm_graph_free);
|
|
||||||
alpm_list_free(vertices);
|
|
||||||
|
|
||||||
*path = bestpath;
|
|
||||||
return bestsize;
|
|
||||||
}
|
|
||||||
|
|
||||||
static alpm_list_t *find_unused(alpm_list_t *deltas, const char *to, off_t quota)
|
|
||||||
{
|
|
||||||
alpm_list_t *unused = NULL;
|
|
||||||
alpm_list_t *vertices;
|
|
||||||
alpm_list_t *i;
|
|
||||||
vertices = graph_init(deltas, 1);
|
|
||||||
|
|
||||||
for(i = vertices; i; i = i->next) {
|
|
||||||
alpm_graph_t *v = i->data;
|
|
||||||
alpm_delta_t *vdelta = v->data;
|
|
||||||
if(strcmp(vdelta->to, to) == 0) {
|
|
||||||
v->weight = vdelta->download_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dijkstra(vertices);
|
|
||||||
for(i = vertices; i; i = i->next) {
|
|
||||||
alpm_graph_t *v = i->data;
|
|
||||||
alpm_delta_t *vdelta = v->data;
|
|
||||||
if(v->weight > quota) {
|
|
||||||
unused = alpm_list_add(unused, vdelta->delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
alpm_list_free_inner(vertices, _alpm_graph_free);
|
|
||||||
alpm_list_free(vertices);
|
|
||||||
return unused;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** \addtogroup alpm_deltas Delta Functions
|
|
||||||
* @brief Functions to manipulate libalpm deltas
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_unused_deltas(alpm_pkg_t *pkg)
|
|
||||||
{
|
|
||||||
ASSERT(pkg != NULL, return NULL);
|
|
||||||
return find_unused(pkg->deltas, pkg->filename,
|
|
||||||
pkg->size * pkg->handle->deltaratio);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
#define NUM_MATCHES 6
|
|
||||||
|
|
||||||
/** Parses the string representation of a alpm_delta_t object.
|
|
||||||
* This function assumes that the string is in the correct format.
|
|
||||||
* This format is as follows:
|
|
||||||
* $deltafile $deltamd5 $deltasize $oldfile $newfile
|
|
||||||
* @param handle the context handle
|
|
||||||
* @param line the string to parse
|
|
||||||
* @return A pointer to the new alpm_delta_t object
|
|
||||||
*/
|
|
||||||
alpm_delta_t *_alpm_delta_parse(alpm_handle_t *handle, const char *line)
|
|
||||||
{
|
|
||||||
alpm_delta_t *delta;
|
|
||||||
size_t len;
|
|
||||||
regmatch_t pmatch[NUM_MATCHES];
|
|
||||||
char filesize[32];
|
|
||||||
|
|
||||||
/* this is so we only have to compile the pattern once */
|
|
||||||
if(!handle->delta_regex_compiled) {
|
|
||||||
/* $deltafile $deltamd5 $deltasize $oldfile $newfile*/
|
|
||||||
regcomp(&handle->delta_regex,
|
|
||||||
"^([^[:space:]]+) ([[:xdigit:]]{32}) ([[:digit:]]+)"
|
|
||||||
" ([^[:space:]]+) ([^[:space:]]+)$",
|
|
||||||
REG_EXTENDED | REG_NEWLINE);
|
|
||||||
handle->delta_regex_compiled = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(regexec(&handle->delta_regex, line, NUM_MATCHES, pmatch, 0) != 0) {
|
|
||||||
/* delta line is invalid, return NULL */
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CALLOC(delta, 1, sizeof(alpm_delta_t), return NULL);
|
|
||||||
|
|
||||||
/* start at index 1 -- match 0 is the entire match */
|
|
||||||
len = pmatch[1].rm_eo - pmatch[1].rm_so;
|
|
||||||
STRNDUP(delta->delta, &line[pmatch[1].rm_so], len, goto error);
|
|
||||||
|
|
||||||
len = pmatch[2].rm_eo - pmatch[2].rm_so;
|
|
||||||
STRNDUP(delta->delta_md5, &line[pmatch[2].rm_so], len, goto error);
|
|
||||||
|
|
||||||
len = pmatch[3].rm_eo - pmatch[3].rm_so;
|
|
||||||
if(len < sizeof(filesize)) {
|
|
||||||
strncpy(filesize, &line[pmatch[3].rm_so], len);
|
|
||||||
filesize[len] = '\0';
|
|
||||||
delta->delta_size = _alpm_strtoofft(filesize);
|
|
||||||
}
|
|
||||||
|
|
||||||
len = pmatch[4].rm_eo - pmatch[4].rm_so;
|
|
||||||
STRNDUP(delta->from, &line[pmatch[4].rm_so], len, goto error);
|
|
||||||
|
|
||||||
len = pmatch[5].rm_eo - pmatch[5].rm_so;
|
|
||||||
STRNDUP(delta->to, &line[pmatch[5].rm_so], len, goto error);
|
|
||||||
|
|
||||||
return delta;
|
|
||||||
|
|
||||||
error:
|
|
||||||
_alpm_delta_free(delta);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef NUM_MATCHES
|
|
||||||
|
|
||||||
void _alpm_delta_free(alpm_delta_t *delta)
|
|
||||||
{
|
|
||||||
ASSERT(delta != NULL, return);
|
|
||||||
FREE(delta->delta);
|
|
||||||
FREE(delta->delta_md5);
|
|
||||||
FREE(delta->from);
|
|
||||||
FREE(delta->to);
|
|
||||||
FREE(delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_delta_t *_alpm_delta_dup(const alpm_delta_t *delta)
|
|
||||||
{
|
|
||||||
alpm_delta_t *newdelta;
|
|
||||||
CALLOC(newdelta, 1, sizeof(alpm_delta_t), return NULL);
|
|
||||||
STRDUP(newdelta->delta, delta->delta, goto error);
|
|
||||||
STRDUP(newdelta->delta_md5, delta->delta_md5, goto error);
|
|
||||||
STRDUP(newdelta->from, delta->from, goto error);
|
|
||||||
STRDUP(newdelta->to, delta->to, goto error);
|
|
||||||
newdelta->delta_size = delta->delta_size;
|
|
||||||
newdelta->download_size = delta->download_size;
|
|
||||||
|
|
||||||
return newdelta;
|
|
||||||
|
|
||||||
error:
|
|
||||||
_alpm_delta_free(newdelta);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
* delta.h
|
|
||||||
*
|
|
||||||
* Copyright (c) 2006-2018 Pacman Development Team <pacman-dev@archlinux.org>
|
|
||||||
* Copyright (c) 2007-2006 by Judd Vinet <jvinet@zeroflux.org>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
#ifndef ALPM_DELTA_H
|
|
||||||
#define ALPM_DELTA_H
|
|
||||||
|
|
||||||
#include <sys/types.h> /* off_t */
|
|
||||||
|
|
||||||
#include "alpm.h"
|
|
||||||
|
|
||||||
alpm_delta_t *_alpm_delta_parse(alpm_handle_t *handle, const char *line);
|
|
||||||
void _alpm_delta_free(alpm_delta_t *delta);
|
|
||||||
alpm_delta_t *_alpm_delta_dup(const alpm_delta_t *delta);
|
|
||||||
off_t _alpm_shortest_delta_path(alpm_handle_t *handle, alpm_list_t *deltas,
|
|
||||||
const char *to, alpm_list_t **path);
|
|
||||||
|
|
||||||
#endif /* ALPM_DELTA_H */
|
|
|
@ -130,11 +130,6 @@ const char SYMEXPORT *alpm_strerror(alpm_errno_t err)
|
||||||
return _("missing PGP signature");
|
return _("missing PGP signature");
|
||||||
case ALPM_ERR_SIG_INVALID:
|
case ALPM_ERR_SIG_INVALID:
|
||||||
return _("invalid PGP signature");
|
return _("invalid PGP signature");
|
||||||
/* Deltas */
|
|
||||||
case ALPM_ERR_DLT_INVALID:
|
|
||||||
return _("invalid or corrupted delta");
|
|
||||||
case ALPM_ERR_DLT_PATCHFAILED:
|
|
||||||
return _("delta patch failed");
|
|
||||||
/* Dependencies */
|
/* Dependencies */
|
||||||
case ALPM_ERR_UNSATISFIED_DEPS:
|
case ALPM_ERR_UNSATISFIED_DEPS:
|
||||||
return _("could not satisfy dependencies");
|
return _("could not satisfy dependencies");
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "alpm_list.h"
|
#include "alpm_list.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "delta.h"
|
|
||||||
#include "trans.h"
|
#include "trans.h"
|
||||||
#include "alpm.h"
|
#include "alpm.h"
|
||||||
#include "deps.h"
|
#include "deps.h"
|
||||||
|
@ -44,7 +43,6 @@ alpm_handle_t *_alpm_handle_new(void)
|
||||||
alpm_handle_t *handle;
|
alpm_handle_t *handle;
|
||||||
|
|
||||||
CALLOC(handle, 1, sizeof(alpm_handle_t), return NULL);
|
CALLOC(handle, 1, sizeof(alpm_handle_t), return NULL);
|
||||||
handle->deltaratio = 0.0;
|
|
||||||
handle->lockfd = -1;
|
handle->lockfd = -1;
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
|
@ -75,8 +73,6 @@ void _alpm_handle_free(alpm_handle_t *handle)
|
||||||
FREELIST(handle->known_keys);
|
FREELIST(handle->known_keys);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
regfree(&handle->delta_regex);
|
|
||||||
|
|
||||||
/* free memory */
|
/* free memory */
|
||||||
_alpm_trans_free(handle->trans);
|
_alpm_trans_free(handle->trans);
|
||||||
FREE(handle->root);
|
FREE(handle->root);
|
||||||
|
@ -303,12 +299,6 @@ const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle)
|
||||||
return handle->arch;
|
return handle->arch;
|
||||||
}
|
}
|
||||||
|
|
||||||
double SYMEXPORT alpm_option_get_deltaratio(alpm_handle_t *handle)
|
|
||||||
{
|
|
||||||
CHECK_HANDLE(handle, return -1);
|
|
||||||
return handle->deltaratio;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SYMEXPORT alpm_option_get_checkspace(alpm_handle_t *handle)
|
int SYMEXPORT alpm_option_get_checkspace(alpm_handle_t *handle)
|
||||||
{
|
{
|
||||||
CHECK_HANDLE(handle, return -1);
|
CHECK_HANDLE(handle, return -1);
|
||||||
|
@ -755,16 +745,6 @@ int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SYMEXPORT alpm_option_set_deltaratio(alpm_handle_t *handle, double ratio)
|
|
||||||
{
|
|
||||||
CHECK_HANDLE(handle, return -1);
|
|
||||||
if(ratio < 0.0 || ratio > 2.0) {
|
|
||||||
RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1);
|
|
||||||
}
|
|
||||||
handle->deltaratio = ratio;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_db_t SYMEXPORT *alpm_get_localdb(alpm_handle_t *handle)
|
alpm_db_t SYMEXPORT *alpm_get_localdb(alpm_handle_t *handle)
|
||||||
{
|
{
|
||||||
CHECK_HANDLE(handle, return NULL);
|
CHECK_HANDLE(handle, return NULL);
|
||||||
|
|
|
@ -95,7 +95,6 @@ struct __alpm_handle_t {
|
||||||
|
|
||||||
/* options */
|
/* options */
|
||||||
char *arch; /* Architecture of packages we should allow */
|
char *arch; /* Architecture of packages we should allow */
|
||||||
double deltaratio; /* Download deltas if possible; a ratio value */
|
|
||||||
int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */
|
int usesyslog; /* Use syslog instead of logfile? */ /* TODO move to frontend */
|
||||||
int checkspace; /* Check disk space before installing */
|
int checkspace; /* Check disk space before installing */
|
||||||
char *dbext; /* Sync DB extension */
|
char *dbext; /* Sync DB extension */
|
||||||
|
@ -110,10 +109,6 @@ struct __alpm_handle_t {
|
||||||
|
|
||||||
/* lock file descriptor */
|
/* lock file descriptor */
|
||||||
int lockfd;
|
int lockfd;
|
||||||
|
|
||||||
/* for delta parsing efficiency */
|
|
||||||
int delta_regex_compiled;
|
|
||||||
regex_t delta_regex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
alpm_handle_t *_alpm_handle_new(void);
|
alpm_handle_t *_alpm_handle_new(void);
|
||||||
|
|
|
@ -9,7 +9,6 @@ libalpm_sources = files('''
|
||||||
be_sync.c
|
be_sync.c
|
||||||
conflict.h conflict.c
|
conflict.h conflict.c
|
||||||
db.h db.c
|
db.h db.c
|
||||||
delta.h delta.c
|
|
||||||
deps.h deps.c
|
deps.h deps.c
|
||||||
diskspace.h diskspace.c
|
diskspace.h diskspace.c
|
||||||
dload.h dload.c
|
dload.h dload.c
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "delta.h"
|
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
#include "deps.h"
|
#include "deps.h"
|
||||||
|
|
||||||
|
@ -374,13 +373,6 @@ alpm_list_t SYMEXPORT *alpm_pkg_get_replaces(alpm_pkg_t *pkg)
|
||||||
return pkg->ops->get_replaces(pkg);
|
return pkg->ops->get_replaces(pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
alpm_list_t SYMEXPORT *alpm_pkg_get_deltas(alpm_pkg_t *pkg)
|
|
||||||
{
|
|
||||||
ASSERT(pkg != NULL, return NULL);
|
|
||||||
pkg->handle->pm_errno = ALPM_ERR_OK;
|
|
||||||
return pkg->deltas;
|
|
||||||
}
|
|
||||||
|
|
||||||
alpm_filelist_t SYMEXPORT *alpm_pkg_get_files(alpm_pkg_t *pkg)
|
alpm_filelist_t SYMEXPORT *alpm_pkg_get_files(alpm_pkg_t *pkg)
|
||||||
{
|
{
|
||||||
ASSERT(pkg != NULL, return NULL);
|
ASSERT(pkg != NULL, return NULL);
|
||||||
|
@ -620,9 +612,6 @@ int _alpm_pkg_dup(alpm_pkg_t *pkg, alpm_pkg_t **new_ptr)
|
||||||
newpkg->optdepends = list_depdup(pkg->optdepends);
|
newpkg->optdepends = list_depdup(pkg->optdepends);
|
||||||
newpkg->conflicts = list_depdup(pkg->conflicts);
|
newpkg->conflicts = list_depdup(pkg->conflicts);
|
||||||
newpkg->provides = list_depdup(pkg->provides);
|
newpkg->provides = list_depdup(pkg->provides);
|
||||||
for(i = pkg->deltas; i; i = i->next) {
|
|
||||||
newpkg->deltas = alpm_list_add(newpkg->deltas, _alpm_delta_dup(i->data));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pkg->files.count) {
|
if(pkg->files.count) {
|
||||||
size_t filenum;
|
size_t filenum;
|
||||||
|
@ -696,9 +685,6 @@ void _alpm_pkg_free(alpm_pkg_t *pkg)
|
||||||
free_deplist(pkg->optdepends);
|
free_deplist(pkg->optdepends);
|
||||||
free_deplist(pkg->conflicts);
|
free_deplist(pkg->conflicts);
|
||||||
free_deplist(pkg->provides);
|
free_deplist(pkg->provides);
|
||||||
alpm_list_free_inner(pkg->deltas, (alpm_list_fn_free)_alpm_delta_free);
|
|
||||||
alpm_list_free(pkg->deltas);
|
|
||||||
alpm_list_free(pkg->delta_path);
|
|
||||||
alpm_list_free(pkg->removes);
|
alpm_list_free(pkg->removes);
|
||||||
_alpm_pkg_free(pkg->oldpkg);
|
_alpm_pkg_free(pkg->oldpkg);
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,6 @@ struct __alpm_pkg_t {
|
||||||
alpm_list_t *makedepends;
|
alpm_list_t *makedepends;
|
||||||
alpm_list_t *conflicts;
|
alpm_list_t *conflicts;
|
||||||
alpm_list_t *provides;
|
alpm_list_t *provides;
|
||||||
alpm_list_t *deltas;
|
|
||||||
alpm_list_t *delta_path;
|
|
||||||
alpm_list_t *removes; /* in transaction targets only */
|
alpm_list_t *removes; /* in transaction targets only */
|
||||||
alpm_pkg_t *oldpkg; /* in transaction targets only */
|
alpm_pkg_t *oldpkg; /* in transaction targets only */
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@ lib/libalpm/be_package.c
|
||||||
lib/libalpm/be_sync.c
|
lib/libalpm/be_sync.c
|
||||||
lib/libalpm/conflict.c
|
lib/libalpm/conflict.c
|
||||||
lib/libalpm/db.c
|
lib/libalpm/db.c
|
||||||
lib/libalpm/delta.c
|
|
||||||
lib/libalpm/deps.c
|
lib/libalpm/deps.c
|
||||||
lib/libalpm/diskspace.c
|
lib/libalpm/diskspace.c
|
||||||
lib/libalpm/dload.c
|
lib/libalpm/dload.c
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
#include "alpm.h"
|
#include "alpm.h"
|
||||||
#include "dload.h"
|
#include "dload.h"
|
||||||
#include "delta.h"
|
|
||||||
#include "remove.h"
|
#include "remove.h"
|
||||||
#include "diskspace.h"
|
#include "diskspace.h"
|
||||||
#include "signing.h"
|
#include "signing.h"
|
||||||
|
@ -351,21 +350,6 @@ static int compute_download_size(alpm_pkg_t *newpkg)
|
||||||
|
|
||||||
/* tell the caller that we have a partial */
|
/* tell the caller that we have a partial */
|
||||||
ret = 1;
|
ret = 1;
|
||||||
} else if(handle->deltaratio > 0.0) {
|
|
||||||
off_t dltsize;
|
|
||||||
|
|
||||||
dltsize = _alpm_shortest_delta_path(handle, newpkg->deltas,
|
|
||||||
newpkg->filename, &newpkg->delta_path);
|
|
||||||
|
|
||||||
if(newpkg->delta_path && (dltsize < newpkg->size * handle->deltaratio)) {
|
|
||||||
_alpm_log(handle, ALPM_LOG_DEBUG, "using delta size\n");
|
|
||||||
size = dltsize;
|
|
||||||
} else {
|
|
||||||
_alpm_log(handle, ALPM_LOG_DEBUG, "using package size\n");
|
|
||||||
size = newpkg->size;
|
|
||||||
alpm_list_free(newpkg->delta_path);
|
|
||||||
newpkg->delta_path = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
size = newpkg->size;
|
size = newpkg->size;
|
||||||
}
|
}
|
||||||
|
@ -696,118 +680,6 @@ off_t SYMEXPORT alpm_pkg_download_size(alpm_pkg_t *newpkg)
|
||||||
return newpkg->download_size;
|
return newpkg->download_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int endswith(const char *filename, const char *extension)
|
|
||||||
{
|
|
||||||
const char *s = filename + strlen(filename) - strlen(extension);
|
|
||||||
return strcmp(s, extension) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Applies delta files to create an upgraded package file.
|
|
||||||
*
|
|
||||||
* All intermediate files are deleted, leaving only the starting and
|
|
||||||
* ending package files.
|
|
||||||
*
|
|
||||||
* @param handle the context handle
|
|
||||||
*
|
|
||||||
* @return 0 if all delta files were able to be applied, 1 otherwise.
|
|
||||||
*/
|
|
||||||
static int apply_deltas(alpm_handle_t *handle)
|
|
||||||
{
|
|
||||||
alpm_list_t *i;
|
|
||||||
size_t deltas_found = 0;
|
|
||||||
int ret = 0;
|
|
||||||
const char *cachedir = _alpm_filecache_setup(handle);
|
|
||||||
alpm_trans_t *trans = handle->trans;
|
|
||||||
alpm_event_delta_patch_t event;
|
|
||||||
|
|
||||||
for(i = trans->add; i; i = i->next) {
|
|
||||||
alpm_pkg_t *spkg = i->data;
|
|
||||||
alpm_list_t *delta_path = spkg->delta_path;
|
|
||||||
alpm_list_t *dlts = NULL;
|
|
||||||
|
|
||||||
if(!delta_path) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!deltas_found) {
|
|
||||||
/* only show this if we actually have deltas to apply, and it is before
|
|
||||||
* the very first one */
|
|
||||||
event.type = ALPM_EVENT_DELTA_PATCHES_START;
|
|
||||||
EVENT(handle, &event);
|
|
||||||
deltas_found = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(dlts = delta_path; dlts; dlts = dlts->next) {
|
|
||||||
alpm_delta_t *d = dlts->data;
|
|
||||||
char *delta, *from, *to;
|
|
||||||
char command[PATH_MAX];
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
delta = _alpm_filecache_find(handle, d->delta);
|
|
||||||
/* the initial package might be in a different cachedir */
|
|
||||||
if(dlts == delta_path) {
|
|
||||||
from = _alpm_filecache_find(handle, d->from);
|
|
||||||
} else {
|
|
||||||
/* len = cachedir len + from len + '/' + null */
|
|
||||||
len = strlen(cachedir) + strlen(d->from) + 2;
|
|
||||||
MALLOC(from, len, free(delta); RET_ERR(handle, ALPM_ERR_MEMORY, 1));
|
|
||||||
snprintf(from, len, "%s/%s", cachedir, d->from);
|
|
||||||
}
|
|
||||||
len = strlen(cachedir) + strlen(d->to) + 2;
|
|
||||||
MALLOC(to, len, free(delta); free(from); RET_ERR(handle, ALPM_ERR_MEMORY, 1));
|
|
||||||
snprintf(to, len, "%s/%s", cachedir, d->to);
|
|
||||||
|
|
||||||
/* build the patch command */
|
|
||||||
if(endswith(to, ".gz")) {
|
|
||||||
/* special handling for gzip : we disable timestamp with -n option */
|
|
||||||
snprintf(command, PATH_MAX, "xdelta3 -d -q -R -c -s %s %s | gzip -n > %s", from, delta, to);
|
|
||||||
} else {
|
|
||||||
snprintf(command, PATH_MAX, "xdelta3 -d -q -s %s %s %s", from, delta, to);
|
|
||||||
}
|
|
||||||
|
|
||||||
_alpm_log(handle, ALPM_LOG_DEBUG, "command: %s\n", command);
|
|
||||||
|
|
||||||
event.type = ALPM_EVENT_DELTA_PATCH_START;
|
|
||||||
event.delta = d;
|
|
||||||
EVENT(handle, &event);
|
|
||||||
|
|
||||||
int retval = system(command);
|
|
||||||
if(retval == 0) {
|
|
||||||
event.type = ALPM_EVENT_DELTA_PATCH_DONE;
|
|
||||||
EVENT(handle, &event);
|
|
||||||
|
|
||||||
/* delete the delta file */
|
|
||||||
unlink(delta);
|
|
||||||
|
|
||||||
/* Delete the 'from' package but only if it is an intermediate
|
|
||||||
* package. The starting 'from' package should be kept, just
|
|
||||||
* as if deltas were not used. */
|
|
||||||
if(dlts != delta_path) {
|
|
||||||
unlink(from);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FREE(from);
|
|
||||||
FREE(to);
|
|
||||||
FREE(delta);
|
|
||||||
|
|
||||||
if(retval != 0) {
|
|
||||||
/* one delta failed for this package, cancel the remaining ones */
|
|
||||||
event.type = ALPM_EVENT_DELTA_PATCH_FAILED;
|
|
||||||
EVENT(handle, &event);
|
|
||||||
handle->pm_errno = ALPM_ERR_DLT_PATCHFAILED;
|
|
||||||
ret = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(deltas_found) {
|
|
||||||
event.type = ALPM_EVENT_DELTA_PATCHES_DONE;
|
|
||||||
EVENT(handle, &event);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prompts to delete the file now that we know it is invalid.
|
* Prompts to delete the file now that we know it is invalid.
|
||||||
* @param handle the context handle
|
* @param handle the context handle
|
||||||
|
@ -832,44 +704,6 @@ static int prompt_to_delete(alpm_handle_t *handle, const char *filepath,
|
||||||
return question.remove;
|
return question.remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int validate_deltas(alpm_handle_t *handle, alpm_list_t *deltas)
|
|
||||||
{
|
|
||||||
alpm_list_t *i, *errors = NULL;
|
|
||||||
alpm_event_t event;
|
|
||||||
|
|
||||||
if(!deltas) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check integrity of deltas */
|
|
||||||
event.type = ALPM_EVENT_DELTA_INTEGRITY_START;
|
|
||||||
EVENT(handle, &event);
|
|
||||||
for(i = deltas; i; i = i->next) {
|
|
||||||
alpm_delta_t *d = i->data;
|
|
||||||
char *filepath = _alpm_filecache_find(handle, d->delta);
|
|
||||||
|
|
||||||
if(_alpm_test_checksum(filepath, d->delta_md5, ALPM_PKG_VALIDATION_MD5SUM)) {
|
|
||||||
errors = alpm_list_add(errors, filepath);
|
|
||||||
} else {
|
|
||||||
FREE(filepath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
event.type = ALPM_EVENT_DELTA_INTEGRITY_DONE;
|
|
||||||
EVENT(handle, &event);
|
|
||||||
|
|
||||||
if(errors) {
|
|
||||||
for(i = errors; i; i = i->next) {
|
|
||||||
char *filepath = i->data;
|
|
||||||
prompt_to_delete(handle, filepath, ALPM_ERR_DLT_INVALID);
|
|
||||||
FREE(filepath);
|
|
||||||
}
|
|
||||||
alpm_list_free(errors);
|
|
||||||
handle->pm_errno = ALPM_ERR_DLT_INVALID;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct dload_payload *build_payload(alpm_handle_t *handle,
|
static struct dload_payload *build_payload(alpm_handle_t *handle,
|
||||||
const char *filename, size_t size, alpm_list_t *servers)
|
const char *filename, size_t size, alpm_list_t *servers)
|
||||||
{
|
{
|
||||||
|
@ -882,7 +716,7 @@ static struct dload_payload *build_payload(alpm_handle_t *handle,
|
||||||
return payload;
|
return payload;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int find_dl_candidates(alpm_db_t *repo, alpm_list_t **files, alpm_list_t **deltas)
|
static int find_dl_candidates(alpm_db_t *repo, alpm_list_t **files)
|
||||||
{
|
{
|
||||||
alpm_list_t *i;
|
alpm_list_t *i;
|
||||||
alpm_handle_t *handle = repo->handle;
|
alpm_handle_t *handle = repo->handle;
|
||||||
|
@ -891,8 +725,6 @@ static int find_dl_candidates(alpm_db_t *repo, alpm_list_t **files, alpm_list_t
|
||||||
alpm_pkg_t *spkg = i->data;
|
alpm_pkg_t *spkg = i->data;
|
||||||
|
|
||||||
if(spkg->origin != ALPM_PKG_FROM_FILE && repo == spkg->origin_data.db) {
|
if(spkg->origin != ALPM_PKG_FROM_FILE && repo == spkg->origin_data.db) {
|
||||||
alpm_list_t *delta_path = spkg->delta_path;
|
|
||||||
|
|
||||||
if(!repo->servers) {
|
if(!repo->servers) {
|
||||||
handle->pm_errno = ALPM_ERR_SERVER_NONE;
|
handle->pm_errno = ALPM_ERR_SERVER_NONE;
|
||||||
_alpm_log(handle, ALPM_LOG_ERROR, "%s: %s\n",
|
_alpm_log(handle, ALPM_LOG_ERROR, "%s: %s\n",
|
||||||
|
@ -900,22 +732,7 @@ static int find_dl_candidates(alpm_db_t *repo, alpm_list_t **files, alpm_list_t
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(delta_path) {
|
if(spkg->download_size != 0) {
|
||||||
/* using deltas */
|
|
||||||
alpm_list_t *dlts;
|
|
||||||
for(dlts = delta_path; dlts; dlts = dlts->next) {
|
|
||||||
alpm_delta_t *delta = dlts->data;
|
|
||||||
if(delta->download_size != 0) {
|
|
||||||
struct dload_payload *payload = build_payload(
|
|
||||||
handle, delta->delta, delta->delta_size, repo->servers);
|
|
||||||
ASSERT(payload, return -1);
|
|
||||||
*files = alpm_list_add(*files, payload);
|
|
||||||
}
|
|
||||||
/* keep a list of all the delta files for md5sums */
|
|
||||||
*deltas = alpm_list_add(*deltas, delta);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(spkg->download_size != 0) {
|
|
||||||
struct dload_payload *payload;
|
struct dload_payload *payload;
|
||||||
ASSERT(spkg->filename != NULL, RET_ERR(handle, ALPM_ERR_PKG_INVALID_NAME, -1));
|
ASSERT(spkg->filename != NULL, RET_ERR(handle, ALPM_ERR_PKG_INVALID_NAME, -1));
|
||||||
payload = build_payload(handle, spkg->filename, spkg->size, repo->servers);
|
payload = build_payload(handle, spkg->filename, spkg->size, repo->servers);
|
||||||
|
@ -963,7 +780,7 @@ static int download_single_file(alpm_handle_t *handle, struct dload_payload *pay
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int download_files(alpm_handle_t *handle, alpm_list_t **deltas)
|
static int download_files(alpm_handle_t *handle)
|
||||||
{
|
{
|
||||||
const char *cachedir;
|
const char *cachedir;
|
||||||
alpm_list_t *i, *files = NULL;
|
alpm_list_t *i, *files = NULL;
|
||||||
|
@ -987,7 +804,7 @@ static int download_files(alpm_handle_t *handle, alpm_list_t **deltas)
|
||||||
}
|
}
|
||||||
|
|
||||||
for(i = handle->dbs_sync; i; i = i->next) {
|
for(i = handle->dbs_sync; i; i = i->next) {
|
||||||
errors += find_dl_candidates(i->data, &files, deltas);
|
errors += find_dl_candidates(i->data, &files);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(files) {
|
if(files) {
|
||||||
|
@ -1309,24 +1126,12 @@ static int load_packages(alpm_handle_t *handle, alpm_list_t **data,
|
||||||
|
|
||||||
int _alpm_sync_load(alpm_handle_t *handle, alpm_list_t **data)
|
int _alpm_sync_load(alpm_handle_t *handle, alpm_list_t **data)
|
||||||
{
|
{
|
||||||
alpm_list_t *i, *deltas = NULL;
|
alpm_list_t *i;
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
uint64_t total_bytes = 0;
|
uint64_t total_bytes = 0;
|
||||||
alpm_trans_t *trans = handle->trans;
|
alpm_trans_t *trans = handle->trans;
|
||||||
|
|
||||||
if(download_files(handle, &deltas)) {
|
if(download_files(handle)) {
|
||||||
alpm_list_free(deltas);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(validate_deltas(handle, deltas)) {
|
|
||||||
alpm_list_free(deltas);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
alpm_list_free(deltas);
|
|
||||||
|
|
||||||
/* Use the deltas to generate the packages */
|
|
||||||
if(apply_deltas(handle)) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -347,14 +347,6 @@ void cb_event(alpm_event_t *event)
|
||||||
case ALPM_EVENT_PKGDOWNLOAD_START:
|
case ALPM_EVENT_PKGDOWNLOAD_START:
|
||||||
case ALPM_EVENT_PKGDOWNLOAD_DONE:
|
case ALPM_EVENT_PKGDOWNLOAD_DONE:
|
||||||
case ALPM_EVENT_PKGDOWNLOAD_FAILED:
|
case ALPM_EVENT_PKGDOWNLOAD_FAILED:
|
||||||
/* temporary until removed from libalpm */
|
|
||||||
case ALPM_EVENT_DELTA_INTEGRITY_START:
|
|
||||||
case ALPM_EVENT_DELTA_INTEGRITY_DONE:
|
|
||||||
case ALPM_EVENT_DELTA_PATCHES_START:
|
|
||||||
case ALPM_EVENT_DELTA_PATCHES_DONE:
|
|
||||||
case ALPM_EVENT_DELTA_PATCH_START:
|
|
||||||
case ALPM_EVENT_DELTA_PATCH_DONE:
|
|
||||||
case ALPM_EVENT_DELTA_PATCH_FAILED:
|
|
||||||
/* nothing */
|
/* nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue