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.
|
||||
* gpgdir: Directory where GnuPG files are stored.
|
||||
* arch: Allowed package architecture.
|
||||
* deltaratio: Download deltas if possible; a ratio value.
|
||||
* checkspace: Check disk space before installing.
|
||||
* default_siglevel: Default signature verification level.
|
||||
* local_file_siglevel: Signature verification level for local file upgrades.
|
||||
|
|
|
@ -34,7 +34,6 @@ libalpm_la_SOURCES = \
|
|||
be_sync.c \
|
||||
conflict.h conflict.c \
|
||||
db.h db.c \
|
||||
delta.h delta.c \
|
||||
deps.h deps.c \
|
||||
diskspace.h diskspace.c \
|
||||
dload.h dload.c \
|
||||
|
|
|
@ -104,9 +104,6 @@ typedef enum _alpm_errno_t {
|
|||
/* Signatures */
|
||||
ALPM_ERR_SIG_MISSING,
|
||||
ALPM_ERR_SIG_INVALID,
|
||||
/* Deltas */
|
||||
ALPM_ERR_DLT_INVALID,
|
||||
ALPM_ERR_DLT_PATCHFAILED,
|
||||
/* Dependencies */
|
||||
ALPM_ERR_UNSATISFIED_DEPS,
|
||||
ALPM_ERR_CONFLICTING_DEPS,
|
||||
|
@ -273,22 +270,6 @@ typedef struct _alpm_group_t {
|
|||
alpm_list_t *packages;
|
||||
} 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 */
|
||||
typedef struct _alpm_file_t {
|
||||
char *name;
|
||||
|
@ -405,21 +386,6 @@ typedef enum _alpm_event_type_t {
|
|||
ALPM_EVENT_LOAD_START,
|
||||
/** Target package is finished loading. */
|
||||
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
|
||||
* arguments. */
|
||||
ALPM_EVENT_SCRIPTLET_INFO,
|
||||
|
@ -509,13 +475,6 @@ typedef struct _alpm_event_optdep_removal_t {
|
|||
alpm_depend_t *optdep;
|
||||
} 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 {
|
||||
/** Type of event. */
|
||||
alpm_event_type_t type;
|
||||
|
@ -589,7 +548,6 @@ typedef union _alpm_event_t {
|
|||
alpm_event_any_t any;
|
||||
alpm_event_package_operation_t package_operation;
|
||||
alpm_event_optdep_removal_t optdep_removal;
|
||||
alpm_event_delta_patch_t delta_patch;
|
||||
alpm_event_scriptlet_info_t scriptlet_info;
|
||||
alpm_event_database_missing_t database_missing;
|
||||
alpm_event_pkgdownload_t pkgdownload;
|
||||
|
@ -915,9 +873,6 @@ const char *alpm_option_get_arch(alpm_handle_t *handle);
|
|||
/** Sets the targeted architecture. */
|
||||
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_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);
|
||||
|
||||
/** 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.
|
||||
* @param pkg a pointer to package
|
||||
* @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);
|
||||
|
||||
alpm_list_t *alpm_pkg_unused_deltas(alpm_pkg_t *pkg);
|
||||
|
||||
/** Set install reason for a package in the local database.
|
||||
* The provided package object must be from the local database or this method
|
||||
* will fail. The write to the local database is performed immediately.
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "alpm_list.h"
|
||||
#include "package.h"
|
||||
#include "handle.h"
|
||||
#include "delta.h"
|
||||
#include "deps.h"
|
||||
#include "dload.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
|
||||
* entries varies considerably. Adding signatures nearly doubles the size of a
|
||||
* single entry; deltas also can make for large variations in size. These
|
||||
* current values are heavily influenced by Arch Linux; databases with no
|
||||
* deltas and a single signature per package. */
|
||||
* single entry. These current values are heavily influenced by Arch Linux;
|
||||
* databases with a single signature per package. */
|
||||
static size_t estimate_package_count(struct stat *st, struct archive *archive)
|
||||
{
|
||||
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) {
|
||||
mode_t mode = archive_entry_mode(entry);
|
||||
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) {
|
||||
_alpm_log(db->handle, ALPM_LOG_ERROR,
|
||||
_("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
|
||||
|| strcmp(filename, "files") == 0
|
||||
|| (strcmp(filename, "deltas") == 0 && db->handle->deltaratio > 0.0) ) {
|
||||
|| strcmp(filename, "files") == 0) {
|
||||
int ret;
|
||||
while((ret = _alpm_archive_fgets(archive, &buf)) == ARCHIVE_OK) {
|
||||
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);
|
||||
} else if(strcmp(line, "%PROVIDES%") == 0) {
|
||||
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) {
|
||||
/* TODO: this could lazy load if there is future demand */
|
||||
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;
|
||||
}
|
||||
*likely_pkg = pkg;
|
||||
} else if(strcmp(filename, "deltas") == 0) {
|
||||
/* skip reading delta files if UseDelta is unset */
|
||||
} else {
|
||||
/* unknown database file */
|
||||
_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");
|
||||
case ALPM_ERR_SIG_INVALID:
|
||||
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 */
|
||||
case ALPM_ERR_UNSATISFIED_DEPS:
|
||||
return _("could not satisfy dependencies");
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "alpm_list.h"
|
||||
#include "util.h"
|
||||
#include "log.h"
|
||||
#include "delta.h"
|
||||
#include "trans.h"
|
||||
#include "alpm.h"
|
||||
#include "deps.h"
|
||||
|
@ -44,7 +43,6 @@ alpm_handle_t *_alpm_handle_new(void)
|
|||
alpm_handle_t *handle;
|
||||
|
||||
CALLOC(handle, 1, sizeof(alpm_handle_t), return NULL);
|
||||
handle->deltaratio = 0.0;
|
||||
handle->lockfd = -1;
|
||||
|
||||
return handle;
|
||||
|
@ -75,8 +73,6 @@ void _alpm_handle_free(alpm_handle_t *handle)
|
|||
FREELIST(handle->known_keys);
|
||||
#endif
|
||||
|
||||
regfree(&handle->delta_regex);
|
||||
|
||||
/* free memory */
|
||||
_alpm_trans_free(handle->trans);
|
||||
FREE(handle->root);
|
||||
|
@ -303,12 +299,6 @@ const char SYMEXPORT *alpm_option_get_arch(alpm_handle_t *handle)
|
|||
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)
|
||||
{
|
||||
CHECK_HANDLE(handle, return -1);
|
||||
|
@ -755,16 +745,6 @@ int SYMEXPORT alpm_option_set_arch(alpm_handle_t *handle, const char *arch)
|
|||
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)
|
||||
{
|
||||
CHECK_HANDLE(handle, return NULL);
|
||||
|
|
|
@ -95,7 +95,6 @@ struct __alpm_handle_t {
|
|||
|
||||
/* options */
|
||||
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 checkspace; /* Check disk space before installing */
|
||||
char *dbext; /* Sync DB extension */
|
||||
|
@ -110,10 +109,6 @@ struct __alpm_handle_t {
|
|||
|
||||
/* lock file descriptor */
|
||||
int lockfd;
|
||||
|
||||
/* for delta parsing efficiency */
|
||||
int delta_regex_compiled;
|
||||
regex_t delta_regex;
|
||||
};
|
||||
|
||||
alpm_handle_t *_alpm_handle_new(void);
|
||||
|
|
|
@ -9,7 +9,6 @@ libalpm_sources = files('''
|
|||
be_sync.c
|
||||
conflict.h conflict.c
|
||||
db.h db.c
|
||||
delta.h delta.c
|
||||
deps.h deps.c
|
||||
diskspace.h diskspace.c
|
||||
dload.h dload.c
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include "db.h"
|
||||
#include "delta.h"
|
||||
#include "handle.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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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->conflicts = list_depdup(pkg->conflicts);
|
||||
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) {
|
||||
size_t filenum;
|
||||
|
@ -696,9 +685,6 @@ void _alpm_pkg_free(alpm_pkg_t *pkg)
|
|||
free_deplist(pkg->optdepends);
|
||||
free_deplist(pkg->conflicts);
|
||||
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_pkg_free(pkg->oldpkg);
|
||||
|
||||
|
|
|
@ -118,8 +118,6 @@ struct __alpm_pkg_t {
|
|||
alpm_list_t *makedepends;
|
||||
alpm_list_t *conflicts;
|
||||
alpm_list_t *provides;
|
||||
alpm_list_t *deltas;
|
||||
alpm_list_t *delta_path;
|
||||
alpm_list_t *removes; /* 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/conflict.c
|
||||
lib/libalpm/db.c
|
||||
lib/libalpm/delta.c
|
||||
lib/libalpm/deps.c
|
||||
lib/libalpm/diskspace.c
|
||||
lib/libalpm/dload.c
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "handle.h"
|
||||
#include "alpm.h"
|
||||
#include "dload.h"
|
||||
#include "delta.h"
|
||||
#include "remove.h"
|
||||
#include "diskspace.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 */
|
||||
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 {
|
||||
size = newpkg->size;
|
||||
}
|
||||
|
@ -696,118 +680,6 @@ off_t SYMEXPORT alpm_pkg_download_size(alpm_pkg_t *newpkg)
|
|||
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.
|
||||
* @param handle the context handle
|
||||
|
@ -832,44 +704,6 @@ static int prompt_to_delete(alpm_handle_t *handle, const char *filepath,
|
|||
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,
|
||||
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;
|
||||
}
|
||||
|
||||
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_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;
|
||||
|
||||
if(spkg->origin != ALPM_PKG_FROM_FILE && repo == spkg->origin_data.db) {
|
||||
alpm_list_t *delta_path = spkg->delta_path;
|
||||
|
||||
if(!repo->servers) {
|
||||
handle->pm_errno = ALPM_ERR_SERVER_NONE;
|
||||
_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;
|
||||
}
|
||||
|
||||
if(delta_path) {
|
||||
/* 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) {
|
||||
if(spkg->download_size != 0) {
|
||||
struct dload_payload *payload;
|
||||
ASSERT(spkg->filename != NULL, RET_ERR(handle, ALPM_ERR_PKG_INVALID_NAME, -1));
|
||||
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;
|
||||
}
|
||||
|
||||
static int download_files(alpm_handle_t *handle, alpm_list_t **deltas)
|
||||
static int download_files(alpm_handle_t *handle)
|
||||
{
|
||||
const char *cachedir;
|
||||
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) {
|
||||
errors += find_dl_candidates(i->data, &files, deltas);
|
||||
errors += find_dl_candidates(i->data, &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)
|
||||
{
|
||||
alpm_list_t *i, *deltas = NULL;
|
||||
alpm_list_t *i;
|
||||
size_t total = 0;
|
||||
uint64_t total_bytes = 0;
|
||||
alpm_trans_t *trans = handle->trans;
|
||||
|
||||
if(download_files(handle, &deltas)) {
|
||||
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)) {
|
||||
if(download_files(handle)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -347,14 +347,6 @@ void cb_event(alpm_event_t *event)
|
|||
case ALPM_EVENT_PKGDOWNLOAD_START:
|
||||
case ALPM_EVENT_PKGDOWNLOAD_DONE:
|
||||
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 */
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue