Commit cc8738cd authored by Bernhard Link's avatar Bernhard Link

refactor indexfile parsing. (Needed for future changes, perhaps speeding some...

refactor indexfile parsing. (Needed for future changes, perhaps speeding some things up a tiny littly bit).
parent 72a91c1c
2008-07-25
* refactor indexfile parsing. (Needed for future changes,
perhaps speeding some things up a tiny littly bit).
2008-07-23
* Do not claim --noskipold makes a difference in the update output
for targets not having any upstream to pull from.
......
......@@ -18,12 +18,12 @@ AM_CPPFLAGS = -std=gnu99 -Wall $(ARCHIVECPP) $(DBCPPFLAGS)
reprepro_LDADD = $(ARCHIVELIBS) $(DBLIBS)
changestool_LDADD = $(ARCHIVELIBS)
reprepro_SOURCES = copypackages.c readcompressed.c sourceextraction.c checksums.c readtextfile.c filecntl.c sha1.c sha256.c configparser.c database.c freespace.c log.c changes.c incoming.c uploaderslist.c guesscomponent.c files.c md5.c dirs.c chunks.c reference.c binaries.c sources.c checks.c names.c dpkgversions.c release.c mprintf.c updates.c strlist.c signature.c distribution.c checkindeb.c checkindsc.c checkin.c upgradelist.c target.c aptmethod.c downloadcache.c main.c override.c terms.c ignore.c filterlist.c exports.c tracking.c optionsfile.c readrelease.c donefile.c pull.c contents.c filelist.c $(ARCHIVE_USED) $(ARCHIVE_CONTENTS)
reprepro_SOURCES = indexfile.c copypackages.c readcompressed.c sourceextraction.c checksums.c readtextfile.c filecntl.c sha1.c sha256.c configparser.c database.c freespace.c log.c changes.c incoming.c uploaderslist.c guesscomponent.c files.c md5.c dirs.c chunks.c reference.c binaries.c sources.c checks.c names.c dpkgversions.c release.c mprintf.c updates.c strlist.c signature.c distribution.c checkindeb.c checkindsc.c checkin.c upgradelist.c target.c aptmethod.c downloadcache.c main.c override.c terms.c ignore.c filterlist.c exports.c tracking.c optionsfile.c readrelease.c donefile.c pull.c contents.c filelist.c $(ARCHIVE_USED) $(ARCHIVE_CONTENTS)
EXTRA_reprepro_SOURCE = $(ARCHIVE_UNUSED)
changestool_SOURCES = readcompressed.c sourceextraction.c readtextfile.c filecntl.c tool.c chunkedit.c strlist.c checksums.c sha1.c sha256.c md5.c mprintf.c chunks.c signature.c dirs.c names.c $(ARCHIVE_USED)
noinst_HEADERS = copypackages.h readcompressed.h sourceextraction.h checksums.h readtextfile.h filecntl.h sha1.h sha256.h configparser.h database_p.h database.h freespace.h log.h changes.h incoming.h guesscomponent.h md5.h dirs.h files.h chunks.h reference.h binaries.h sources.h checks.h names.h release.h error.h mprintf.h updates.h strlist.h signature.h distribution.h debfile.h checkindeb.h checkindsc.h upgradelist.h target.h aptmethod.h downloadcache.h override.h terms.h ignore.h filterlist.h dpkgversions.h checkin.h exports.h globals.h tracking.h trackingt.h optionsfile.h readrelease.h donefile.h pull.h ar.h filelist.h contents.h chunkedit.h uploaderslist.h
noinst_HEADERS = copypackages.h readcompressed.h sourceextraction.h checksums.h readtextfile.h filecntl.h sha1.h sha256.h configparser.h database_p.h database.h freespace.h log.h changes.h incoming.h guesscomponent.h md5.h dirs.h files.h chunks.h reference.h binaries.h sources.h checks.h names.h release.h error.h mprintf.h updates.h strlist.h signature.h distribution.h debfile.h checkindeb.h checkindsc.h upgradelist.h target.h aptmethod.h downloadcache.h override.h terms.h ignore.h filterlist.h dpkgversions.h checkin.h exports.h globals.h tracking.h trackingt.h optionsfile.h readrelease.h donefile.h pull.h ar.h filelist.h contents.h chunkedit.h uploaderslist.h indexfile.h
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/configure $(srcdir)/stamp-h.in $(srcdir)/aclocal.m4 $(srcdir)/config.h.in
......
......@@ -174,18 +174,6 @@ static inline retvalue calcnewcontrol(const char *chunk,const char *sourcename,c
return RET_OK;
}
retvalue binaries_getname(const char *control, char **packagename){
retvalue r;
r = chunk_getvalue(control,"Package",packagename);
if( RET_WAS_ERROR(r) )
return r;
if( r == RET_NOTHING ) {
fprintf(stderr, "Missing 'Package' field in chunk:'%s'\n", control);
return RET_ERROR;
}
return r;
}
retvalue binaries_getversion(const char *control, char **version) {
retvalue r;
......
......@@ -14,7 +14,6 @@
/* Functions for the target.h-stuff: */
retvalue binaries_getname(const char *chunk,char **packagename);
retvalue binaries_getversion(const char *chunk,char **version);
retvalue binaries_getinstalldata(const struct target *t, const char *packagename, const char *version, const char *chunk, /*@out@*/char **control, /*@out@*/struct strlist *filekeys, /*@out@*/struct checksumsarray *origfiles, /*@null@*//*@out@*/enum filetype *);
retvalue binaries_getfilekeys(const char *chunk, /*@out@*/struct strlist *);
......
......@@ -21,7 +21,6 @@
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <zlib.h>
#include <assert.h>
#include "error.h"
#include "chunks.h"
......@@ -29,118 +28,6 @@
extern int verbose;
//TODO: this should now also be able to parse \r\n terminated lines instead
// of only \n terminated oned. Though this has still to be tested properly...
static retvalue chunk_read(gzFile f,char **chunk);
/* Call action for each chunk in <filename> */
retvalue chunk_foreach(const char *filename, chunkaction action, void *data, bool stopwhenok){
gzFile f;
retvalue result,ret;
char *chunk;
f = gzopen(filename,"r");
if( f == NULL ) {
fprintf(stderr, "Unable to open file %s: %s\n",
filename, strerror(errno));
return RET_ERRNO(errno);
}
result = RET_NOTHING;
while( (ret = chunk_read(f,&chunk)) == RET_OK ) {
if( interrupted() ) {
RET_UPDATE(result, RET_ERROR_INTERRUPTED);
free(chunk);
break;
}
ret = action(data,chunk);
free(chunk);
if( RET_WAS_ERROR(ret) ) {
if( verbose > 0 )
fprintf(stderr,"Stop reading further chunks from '%s' due to previous errors.\n",filename);
break;
}
RET_UPDATE(result,ret);
if( stopwhenok && RET_IS_OK(ret) )
break;
}
RET_UPDATE(result,ret);
//TODO: check result:
gzclose(f);
return result;
}
/* get the next chunk from file f ( return RET_NOTHING, if there are none )*/
retvalue chunk_read(gzFile f,char **chunk) {
char *buffer,*bhead;
size_t size,already,without,l;
bool afternewline = false;
size = 4096;
already = 0; without = 0;
bhead = buffer = (char*)malloc(size);
if( buffer == NULL )
return RET_ERROR_OOM;
while( gzgets(f,bhead,size-1-already) != NULL ) {
char *p;
p = bhead;
while( *p != '\0' ) {
if( *p != '\r' && *p != '\n' )
without = 1 + p - buffer;
p++;
}
if( without == 0 ) {
/* ignore leading newlines... */
bhead = buffer;
already = 0;
continue;
}
l = strlen(bhead);
/* if we are after a newline, and have a new newline,
* and only '\r' in between, then return the chunk: */
if( afternewline && without < already && l!=0 && bhead[l-1] == '\n' ) {
break;
}
already += l;
if( l != 0 ) // a bit of parania...
afternewline = bhead[l-1] == '\n';
if( size-already < 1024 ) {
char *n;
if( size >= 513*1024*1024 ) {
fprintf(stderr,"Will not process chunks larger than half a gigabyte!\n");
free(buffer);
return RET_ERROR;
}
size *= 2;
n = realloc(buffer,size);
if( n == NULL ) {
free(buffer);
return RET_ERROR_OOM;
}
buffer = n;
}
bhead = buffer + already;
}
if( without == 0 ) {
free(buffer);
return RET_NOTHING;
} else {
char *n;
/* we do not want to include the final newlines */
buffer[without] = '\0';
n = realloc(buffer,without+1);
if( n == NULL ) {
/* guess this will not happen, but... */
free(buffer);
return RET_ERROR_OOM;
}
buffer = n;
*chunk = buffer;
return RET_OK;
}
}
/* point to a specified field in a chunk */
static const char *chunk_getfield(const char *name,const char *chunk) {
size_t l;
......
......@@ -26,13 +26,6 @@ retvalue chunk_gettruth(const char *chunk,const char *name);
/* return RET_OK, if field is found, RET_NOTHING, if not */
retvalue chunk_checkfield(const char *chunk,const char *name);
typedef retvalue chunkaction(/*@temp@*/void *data,/*@temp@*/const char *chunk);
/* Call action for each chunk in <filename>,
* until error or until ok when <stopwhenok> */
retvalue chunk_foreach(const char *filename, chunkaction action, /*@null@*/ /*@temp@*/void *data, bool stopwhenok);
/* modifications of a chunk: */
struct fieldtoadd {
/*@null@*/struct fieldtoadd *next;
......
This diff is collapsed.
......@@ -28,7 +28,6 @@
#include <archive_entry.h>
#include "error.h"
#include "ar.h"
#include "chunks.h"
#include "filelist.h"
#include "debfile.h"
......
/* This file is part of "reprepro"
* Copyright (C) 2003,2004,2005,2007,2008 Bernhard R. Link
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include <config.h>
#include <errno.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <zlib.h>
#include <assert.h>
#include "error.h"
#include "chunks.h"
#include "names.h"
#include "indexfile.h"
/* the purpose of this code is to read index files, either from a snapshot
* previously generated or downloaded while updating. */
struct indexfile {
gzFile f;
char *filename;
int linenumber, startlinenumber;
retvalue status;
char *buffer;
size_t size;
};
extern int verbose;
retvalue indexfile_open(struct indexfile **file_p, const char *filename) {
struct indexfile *f = calloc(1, sizeof(struct indexfile));
if( FAILEDTOALLOC(f) )
return RET_ERROR_OOM;
f->filename = strdup(filename);
if( FAILEDTOALLOC(f->filename) ) {
free(f);
return RET_ERROR_OOM;
}
// TODO: gzopen and gzgets are slow like hell, improve !
f->f = gzopen(filename, "r");
if( f->f == NULL ) {
fprintf(stderr, "Unable to open file %s: %s\n",
filename, strerror(errno));
free(f->filename);
free(f);
return RET_ERRNO(errno);
}
f->linenumber = 0;
f->startlinenumber = 0;
f->status = RET_OK;
f->size = 4096;
f->buffer = malloc(f->size);
if( FAILEDTOALLOC(f->buffer) ) {
(void)gzclose(f->f);
free(f);
return RET_ERROR_OOM;
}
*file_p = f;
return RET_OK;
}
retvalue indexfile_close(struct indexfile *f) {
retvalue r;
//TODO: check result:
gzclose(f->f);
free(f->filename);
free(f->buffer);
r = f->status;
free(f);
return r;
}
//TODO: this should now also be able to parse \r\n terminated lines instead
// of only \n terminated oned. Though this has still to be tested properly...
//
//TODO: as said above, gzgets is too slow...
static retvalue indexfile_get(struct indexfile *f) {
char *bhead;
size_t already, without, l;
bool afternewline = false;
already = 0; without = 0;
bhead = f->buffer;
f->startlinenumber = f->linenumber + 1;
while( gzgets(f->f, bhead, f->size-1-already) != NULL ) {
f->linenumber++;
char *p;
p = bhead;
while( *p != '\0' ) {
if( *p != '\r' && *p != '\n' )
without = 1 + p - f->buffer;
p++;
}
if( without == 0 ) {
/* ignore leading newlines... */
bhead = f->buffer;
already = 0;
continue;
}
l = strlen(bhead);
/* if we are after a newline, and have a new newline,
* and only '\r' in between, then return the chunk: */
if( afternewline && without < already && l!=0 && bhead[l-1] == '\n' ) {
break;
}
already += l;
if( l != 0 ) // a bit of parania...
afternewline = bhead[l-1] == '\n';
if( f->size-already < 1024 ) {
char *n;
if( f->size >= 513*1024*1024 ) {
fprintf(stderr, "Will not process chunks larger than half a gigabyte!\n");
return RET_ERROR;
}
n = realloc(f->buffer, f->size*2 );
if( FAILEDTOALLOC(n) )
return RET_ERROR_OOM;
f->buffer = n;
f->size *= 2;
}
bhead = f->buffer + already;
}
if( without == 0 )
return RET_NOTHING;
assert( without < f->size );
/* we do not want to include the final newlines */
f->buffer[without] = '\0';
return RET_OK;
}
bool indexfile_getnext(struct indexfile *f, char **name_p, char **version_p, const char **control_p, const struct target *target, bool allowwrongarchitecture) {
retvalue r;
bool ignorecruft = false; // TODO
char *packagename, *version;
const char *control;
do {
r = indexfile_get(f);
if( !RET_IS_OK(r) ) {
RET_UPDATE(f->status, r);
return false;
}
control = f->buffer;
r = chunk_getvalue(control, "Package", &packagename);
if( r == RET_NOTHING ) {
fprintf(stderr,
"Error parsing %s line %d: Chunk without 'Package:' field!\n",
f->filename, f->linenumber);
if( !ignorecruft )
r = RET_ERROR_MISSING;
else
continue;
}
if( RET_WAS_ERROR(r) ) {
RET_UPDATE(f->status, r);
return false;
}
r = chunk_getvalue(control, "Version", &version);
if( r == RET_NOTHING ) {
fprintf(stderr,
"Error parsing %s line %d: Chunk without 'Version:' field!\n",
f->filename, f->linenumber);
if( !ignorecruft )
r = RET_ERROR_MISSING;
else {
free(packagename);
continue;
}
}
if( RET_WAS_ERROR(r) ) {
free(packagename);
RET_UPDATE(f->status, r);
return false;
}
if( strcmp(target->architecture, "source") != 0 ) {
// check if architecture fits for target and error
// out if not ignorewrongarchitecture
}
*control_p = control;
*name_p = packagename;
*version_p = version;
return true;
} while( true );
}
#ifndef REPREPRO_INDEXFILE_H
#define REPREPRO_INDEXFILE_H
#ifndef REPREPRO_ERROR_H
#include "error.h"
#warning "What's hapening here?"
#endif
#ifndef REPREPRO_TARGET_H
#include "target.h"
#endif
struct indexfile;
retvalue indexfile_open(/*@out@*/struct indexfile **, const char *);
retvalue indexfile_close(/*@only@*/struct indexfile *);
bool indexfile_getnext(struct indexfile *, /*@out@*/char **, /*@out@*/char **, /*@out@*/const char **, const struct target *, bool allowwrongarchitecture);
#endif
......@@ -115,18 +115,6 @@ static retvalue getBasenames(const struct strlist *filelines,/*@out@*/struct str
return r;
}
retvalue sources_getname(const char *control, char **packagename){
retvalue r;
r = chunk_getvalue(control,"Package",packagename);
if( RET_WAS_ERROR(r) )
return r;
if( r == RET_NOTHING ) {
fprintf(stderr, "Missing 'Package' field in chunk:'%s'\n", control);
return RET_ERROR;
}
return r;
}
retvalue sources_getversion(const char *control, char **version) {
retvalue r;
......
......@@ -13,7 +13,6 @@
retvalue sources_calcfilelines(const struct checksumsarray *, /*@out@*/char **item);
/* Functions for the target.h-stuff: */
retvalue sources_getname(const char *chunk, /*@out@*/char **packagename);
retvalue sources_getversion(const char *chunk, /*@out@*/char **version);
retvalue sources_getinstalldata(const struct target *t, const char *packagename, const char *version, const char *chunk, char **control, /*@out@*/struct strlist *filekeys, /*@out@*/struct checksumsarray *origfiles, /*@null@*//*@out@*/enum filetype *);
retvalue sources_getfilekeys(const char *, /*@out@*/struct strlist *);
......
......@@ -45,7 +45,7 @@
extern int verbose;
static retvalue target_initialize(const char *codename, const char *component, const char *architecture, /*@observer@*/const char *packagetype, get_name getname, get_version getversion, get_installdata getinstalldata, get_filekeys getfilekeys, get_checksums getchecksums, get_sourceandversion getsourceandversion, do_reoverride doreoverride,do_retrack doretrack, /*@null@*//*@only@*/char *directory, /*@dependent@*/const struct exportmode *exportmode, /*@out@*/struct target **d) {
static retvalue target_initialize(const char *codename, const char *component, const char *architecture, /*@observer@*/const char *packagetype, get_version getversion, get_installdata getinstalldata, get_filekeys getfilekeys, get_checksums getchecksums, get_sourceandversion getsourceandversion, do_reoverride doreoverride,do_retrack doretrack, /*@null@*//*@only@*/char *directory, /*@dependent@*/const struct exportmode *exportmode, /*@out@*/struct target **d) {
struct target *t;
assert(exportmode != NULL);
......@@ -69,7 +69,6 @@ static retvalue target_initialize(const char *codename, const char *component, c
(void)target_free(t);
return RET_ERROR_OOM;
}
t->getname = getname;
t->getversion = getversion;
t->getinstalldata = getinstalldata;
t->getfilekeys = getfilekeys;
......@@ -83,7 +82,7 @@ static retvalue target_initialize(const char *codename, const char *component, c
retvalue target_initialize_ubinary(const char *codename, const char *component, const char *architecture, const struct exportmode *exportmode, struct target **target) {
return target_initialize(codename, component, architecture, "udeb",
binaries_getname, binaries_getversion,
binaries_getversion,
binaries_getinstalldata,
binaries_getfilekeys, binaries_getchecksums,
binaries_getsourceandversion,
......@@ -93,7 +92,7 @@ retvalue target_initialize_ubinary(const char *codename, const char *component,
}
retvalue target_initialize_binary(const char *codename, const char *component, const char *architecture, const struct exportmode *exportmode, struct target **target) {
return target_initialize(codename, component, architecture, "deb",
binaries_getname, binaries_getversion,
binaries_getversion,
binaries_getinstalldata,
binaries_getfilekeys, binaries_getchecksums,
binaries_getsourceandversion,
......@@ -104,7 +103,7 @@ retvalue target_initialize_binary(const char *codename, const char *component, c
retvalue target_initialize_source(const char *codename, const char *component,const struct exportmode *exportmode,struct target **target) {
return target_initialize(codename, component, "source", "dsc",
sources_getname, sources_getversion,
sources_getversion,
sources_getinstalldata,
sources_getfilekeys, sources_getchecksums,
sources_getsourceandversion,
......
......@@ -23,7 +23,6 @@
struct target;
struct alloverrides;
typedef retvalue get_name(const char *, /*@out@*/char **);
typedef retvalue get_version(const char *, /*@out@*/char **);
typedef retvalue get_installdata(const struct target *,const char *,const char *,const char *,/*@out@*/char **,/*@out@*/struct strlist *,/*@out@*/struct checksumsarray *,/*@null@*//*@out@*/enum filetype *);
/* md5sums may be NULL */
......@@ -45,7 +44,6 @@ struct target {
/* the directory relative to <distdir>/<codename>/ to use */
char *relativedirectory;
/* functions to use on the packages included */
get_name *getname;
get_version *getversion;
get_installdata *getinstalldata;
get_filekeys *getfilekeys;
......
......@@ -1677,7 +1677,8 @@ static inline retvalue searchformissing(FILE *out,struct database *database,stru
file->origin->download,
file->filename,
ud_decide_by_pattern,
(void*)file->origin->pattern);
(void*)file->origin->pattern,
file->origin->pattern->flat != NULL);
if( RET_WAS_ERROR(r) ) {
u->incomplete = true;
u->ignoredelete = true;
......
......@@ -24,7 +24,7 @@
#include "error.h"
#include "strlist.h"
#include "chunks.h"
#include "indexfile.h"
#include "dpkgversions.h"
#include "target.h"
#include "downloadcache.h"
......@@ -72,9 +72,6 @@ struct upgradelist {
* (NULL=before start of list) */
/*@null@*//*@dependent@*/struct package_data *last;
/* internal...*/
/*@dependent@*/struct aptmethod *currentaptmethod;
/*@temp@*/upgrade_decide_function *predecide;
/*@temp@*/void *predecide_data;
};
static void package_data_free(/*@only@*/struct package_data *data){
......@@ -196,22 +193,11 @@ void upgradelist_free(struct upgradelist *upgrade) {
return;
}
static retvalue upgradelist_trypackage(void *data,const char *chunk){
struct upgradelist *upgrade = data;
char *packagename,*version;
static retvalue upgradelist_trypackage(struct upgradelist *upgrade, /*@null@*/struct aptmethod *aptmethod, upgrade_decide_function *predecide, void *predecide_data, const char *packagename_const, /*@null@*//*@only@*/char *packagename, /*@only@*/char *version, const char *chunk){
retvalue r;
upgrade_decision decision;
struct package_data *current,*insertafter;
r = upgrade->target->getname(chunk, &packagename);
if( RET_WAS_ERROR(r) )
return r;
r = upgrade->target->getversion(chunk, &version);
if( RET_WAS_ERROR(r) ) {
free(packagename);
return r;
}
/* insertafter = NULL will mean insert before list */
insertafter = upgrade->last;
/* the next one to test, current = NULL will mean not found */
......@@ -234,7 +220,7 @@ static retvalue upgradelist_trypackage(void *data,const char *chunk){
if( current == NULL )
cmp = -1; /* every package is before the end of list */
else
cmp = strcmp(packagename,current->name);
cmp = strcmp(packagename_const, current->name);
if( cmp == 0 )
break;
......@@ -249,7 +235,7 @@ static retvalue upgradelist_trypackage(void *data,const char *chunk){
break;
}
// I only hope noone creates indices anti-sorted:
precmp = strcmp(packagename,insertafter->name);
precmp = strcmp(packagename_const, insertafter->name);
if( precmp == 0 ) {
current = insertafter;
break;
......@@ -282,7 +268,7 @@ static retvalue upgradelist_trypackage(void *data,const char *chunk){
/* adding a package not yet known */
struct package_data *new;
decision = upgrade->predecide(upgrade->predecide_data,packagename,NULL,version,chunk);
decision = predecide(predecide_data, packagename_const, NULL, version, chunk);
if( decision != UD_UPGRADE ) {
upgrade->last = insertafter;
free(packagename);
......@@ -296,10 +282,18 @@ static retvalue upgradelist_trypackage(void *data,const char *chunk){
free(version);
return RET_ERROR_OOM;
}
// assert(upgrade->currentaptmethod!=NULL);
new->deleted = false; //to be sure...
new->aptmethod = upgrade->currentaptmethod;
new->name = packagename;
new->aptmethod = aptmethod;
if( packagename == NULL ) {
new->name = strdup(packagename_const);
if( FAILEDTOALLOC(new->name) ) {
free(packagename);
free(version);
free(new);
return RET_ERROR_OOM;
}
} else
new->name = packagename;
packagename = NULL; //to be sure...
new->new_version = version;
new->version = version;
......@@ -361,8 +355,8 @@ static retvalue upgradelist_trypackage(void *data,const char *chunk){
}
if( versioncmp > 0 && verbose > 30 )
fprintf(stderr,"'%s' from '%s' is newer than '%s' currently\n",
version,packagename,current->version);
decision = upgrade->predecide(upgrade->predecide_data,current->name,
version, packagename_const, current->version);
decision = predecide(predecide_data,current->name,
current->version,version,chunk);
if( decision != UD_UPGRADE ) {
/* Even if we do not install it, setting it on hold
......@@ -415,7 +409,9 @@ static retvalue upgradelist_trypackage(void *data,const char *chunk){
// if( versioncmp >= 0 && current->version == current->version_in_use
// && current->new_version != NULL ) {
r = upgrade->target->getinstalldata(upgrade->target, packagename, version, chunk, &control, &files, &origfiles, &filetype);
r = upgrade->target->getinstalldata(upgrade->target,
packagename_const, version, chunk,
&control, &files, &origfiles, &filetype);
free(packagename);
if( RET_WAS_ERROR(r) ) {
free(version);
......@@ -425,8 +421,7 @@ static retvalue upgradelist_trypackage(void *data,const char *chunk){
free(current->new_version);
current->new_version = version;
current->version = version;
// assert(upgrade->currentaptmethod!=NULL);
current->aptmethod = upgrade->currentaptmethod;
current->aptmethod = aptmethod;
strlist_move(&current->new_filekeys,&files);
checksumsarray_move(&current->new_origfiles, &origfiles);
free(current->new_control);
......@@ -436,14 +431,33 @@ static retvalue upgradelist_trypackage(void *data,const char *chunk){
return RET_OK;
}
retvalue upgradelist_update(struct upgradelist *upgrade,struct aptmethod *method,const char *filename,upgrade_decide_function *decide,void *decide_data){
retvalue upgradelist_update(struct upgradelist *upgrade, struct aptmethod *method, const char *filename, upgrade_decide_function *decide, void *decide_data, bool ignorewrongarchitecture) {
struct indexfile *i;
char *packagename, *version;
const char *control;
retvalue result, r;
upgrade->last = NULL;
upgrade->currentaptmethod = method;
upgrade->predecide = decide;
upgrade->predecide_data = decide_data;
r = indexfile_open(&i, filename);
if( !RET_IS_OK(r) )
return r;
return chunk_foreach(filename, upgradelist_trypackage, upgrade, false);
result = RET_NOTHING;
while( indexfile_getnext(i, &packagename, &version, &control,
upgrade->target, ignorewrongarchitecture) ) {
upgrade->last = NULL;
r = upgradelist_trypackage(upgrade, method, decide, decide_data,
packagename, packagename, version, control);
RET_UPDATE(result, r);
if( RET_WAS_ERROR(r) ) {
if( verbose > 0 )
fprintf(stderr,
"Stop reading further chunks from '%s' due to previous errors.\n", filename);
break;
}
}
r = indexfile_close(i);
RET_ENDUPDATE(result, r);
return result;
}
retvalue upgradelist_pull(struct upgradelist *upgrade,struct target *source,upgrade_decide_function *predecide,void *decide_data,struct database *database) {
......@@ -452,16 +466,23 @@ retvalue upgradelist_pull(struct upgradelist *upgrade,struct target *source,upgr
struct target_cursor iterator;
upgrade->last = NULL;
upgrade->currentaptmethod = NULL;
upgrade->predecide = predecide;
upgrade->predecide_data = decide_data;
r = target_openiterator(source, database, READONLY, &iterator);
if( RET_WAS_ERROR(r) )
return r;
result = RET_NOTHING;
while( target_nextpackage(&iterator, &package, &control) ) {
r = upgradelist_trypackage(upgrade, control);
char *version;
r = upgrade->target->getversion(control, &version);
assert( r != RET_NOTHING );
if( !RET_IS_OK(r) ) {
RET_UPDATE(result, r);
break;
}
r = upgradelist_trypackage(upgrade, NULL,
predecide, decide_data,
package, NULL, version, control);
RET_UPDATE(result, r);
if( RET_WAS_ERROR(r) )
break;
......
......@@ -29,7 +29,7 @@ void upgradelist_dump(struct upgradelist *upgrade);
retvalue upgradelist_listmissing(struct upgradelist *upgrade,struct database *);
/* Take all items in 'filename' into account, and remember them coming from 'method' */
retvalue upgradelist_update(struct upgradelist *upgrade,/*@dependent@*/struct aptmethod *method,const char *filename,upgrade_decide_function *predecide,void *decide_data);
retvalue upgradelist_update(struct upgradelist *upgrade, /*@dependent@*/struct aptmethod *method, const char *filename, upgrade_decide_function *predecide, void *decide_data, bool ignorewrongarchitecture);
/* Take all items in source into account */
retvalue upgradelist_pull(struct upgradelist *upgrade,struct target *source,upgrade_decide_function *predecide,void *decide_data,struct database *);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment