Commit f2972a65 authored by Bernhard Link's avatar Bernhard Link

Changed version comparisons. binaries_add gives oldfilekey instead of oldchunk, completed _adddeb

parent f63465b2
......@@ -33,7 +33,7 @@
extern int verbose;
/* get somefields out of a "Packages.gz"-chunk. returns 1 on success, 0 if incomplete, -1 on error */
retvalue binaries_parse_chunk(const char *chunk,char **packagename,char **origfilename,char **sourcename,char **basename,char **md5andsize) {
retvalue binaries_parse_chunk(const char *chunk,char **packagename,char **origfilename,char **sourcename,char **basename,char **md5andsize,char **version) {
char *pmd5,*psize,*ppackage;
retvalue r;
#define IFREE(p) if(p) free(*p);
......@@ -101,11 +101,24 @@ retvalue binaries_parse_chunk(const char *chunk,char **packagename,char **origfi
}
}
/* get the version */
if( version ) {
r = chunk_getvalue(chunk,"Version",version);
if( !RET_IS_OK(r) ) {
free(ppackage);
IFREE(origfilename);
IFREE(md5andsize);
IFREE(sourcename);
return r;
}
}
/* generate a base filename based on package,version and architecture */
if( basename ) {
char *parch,*pversion,*v;
// TODO combine the two looks for version...
r = chunk_getvalue(chunk,"Version",&pversion);
if( !RET_IS_OK(r) ) {
free(ppackage);
......@@ -146,24 +159,62 @@ retvalue binaries_parse_chunk(const char *chunk,char **packagename,char **origfi
return RET_OK;
}
/* check if one chunk describes a packages superseded by another
* return 1=new is better, 0=old is better, <0 error */
static int binaries_isnewer(const char *newchunk,const char *oldchunk) {
char *nv,*ov;
retvalue ret;
int r;
/* if new broken, old is better, if old broken, new is better: */
ret = chunk_getvalue(newchunk,"Version",&nv);
if( !RET_IS_OK(ret) )
return -1;
ret = chunk_getvalue(oldchunk,"Version",&ov);
if( !RET_IS_OK(ret) ) {
free(nv);
return 1;
/* Look for an older version of the Package in the database.
* Set *oldversion, if there is already a newer (or equal) version to
* <version> and <version> is != NULL */
retvalue binaries_lookforolder(
DB *packages,const char *packagename,
const char *newversion,char **oldversion,
char **oldfilekey) {
char *oldchunk,*ov;
retvalue r;
// TODO: why does packages_get return something else than a retvalue?
oldchunk = packages_get(packages,packagename);
if( oldchunk == NULL ) {
*oldfilekey = NULL;
if( oldversion != NULL && newversion != NULL )
*oldversion = NULL;
return RET_NOTHING;
}
r = isVersionNewer(nv,ov);
free(nv);free(ov);
if( newversion ) {
assert(oldversion != NULL);
r = binaries_parse_chunk(oldchunk,NULL,oldfilekey,NULL,NULL,NULL,&ov);
} else {
assert( oldversion == NULL );
r = binaries_parse_chunk(oldchunk,NULL,oldfilekey,NULL,NULL,NULL,NULL);
}
if( !RET_IS_OK(r) ) {
if( r == RET_NOTHING ) {
fprintf(stderr,"Does not look like binary control: '%s'\n",oldchunk);
r = RET_ERROR;
}
free(oldchunk);
return r;
}
if( newversion ) {
r = dpkgversions_isNewer(newversion,ov);
if( RET_WAS_ERROR(r) ) {
fprintf(stderr,"Parse errors processing versions of %s.\n",packagename);
free(ov);
free(*oldfilekey);
*oldfilekey = NULL;
free(oldchunk);
return r;
}
if( RET_IS_OK(r) ) {
*oldversion = NULL;
free(ov);
} else
*oldversion = ov;
}
free(oldchunk);
return r;
}
......@@ -173,11 +224,10 @@ struct binaries_add {DB *pkgs; void *data; const char *component; binary_package
static retvalue addbinary(void *data,const char *chunk) {
struct binaries_add *d = data;
retvalue r;
int newer;
char *oldchunk;
char *package,*basename,*origfile,*sourcename,*filekey,*md5andsize;
char *oldfilekey,*oldversion;
char *package,*basename,*origfile,*sourcename,*filekey,*md5andsize,*version;
r = binaries_parse_chunk(chunk,&package,&origfile,&sourcename,&basename,&md5andsize);
r = binaries_parse_chunk(chunk,&package,&origfile,&sourcename,&basename,&md5andsize,&version);
if( RET_WAS_ERROR(r) ) {
fprintf(stderr,"Cannot parse chunk: '%s'!\n",chunk);
return r;
......@@ -186,17 +236,19 @@ static retvalue addbinary(void *data,const char *chunk) {
return RET_ERROR;
}
assert(RET_IS_OK(r));
oldchunk = packages_get(d->pkgs,package);
if( oldchunk && (newer=binaries_isnewer(chunk,oldchunk)) != 0 ) {
if( newer < 0 ) {
fprintf(stderr,"Omitting %s because of parse errors.\n",package);
free(md5andsize);free(origfile);free(package);
free(sourcename);free(basename);
free(oldchunk);
return RET_ERROR;
}
r = binaries_lookforolder(d->pkgs,package,version,&oldversion,&oldfilekey);
if( RET_WAS_ERROR(r) ) {
free(version); free(package);free(md5andsize);
free(origfile);free(basename);free(sourcename);
return r;
}
if( oldchunk==NULL || newer > 0 ) {
if( oldversion != NULL ) {
if( verbose > 40 )
fprintf(stderr,"Ignoring '%s' with version '%s', as '%s' is already there.\n",package,version,oldversion);
free(oldversion);
r = RET_NOTHING;
} else {
/* add package (or whatever action wants to do) */
filekey = calc_filekey(d->component,sourcename,basename);
......@@ -205,16 +257,12 @@ static retvalue addbinary(void *data,const char *chunk) {
else {
r = (*d->action)(d->data,chunk,
package,sourcename,origfile,basename,
filekey,md5andsize,oldchunk);
filekey,md5andsize,oldfilekey);
free(filekey);
}
} else {
r = RET_NOTHING;
}
free(oldchunk);
free(package);free(md5andsize);
free(oldfilekey);
free(version); free(package);free(md5andsize);
free(origfile);free(basename);free(sourcename);
return r;
}
......
......@@ -12,7 +12,16 @@ retvalue binaries_parse_chunk(const char *chunk,
char **origfilename,
char **sourcename,
char **basename,
char **md5andsize);
char **md5andsize,
char **version);
/* Look for an older version of the Package in the database.
* Set *oldversion, if there is already a newer (or equal) version to
* <version> and <version> is != NULL */
retvalue binaries_lookforolder(
DB *packages,const char *packagename,
const char *newversion,char **oldversion,
char **oldfilekey);
/* the type of a action for binaries_add */
typedef retvalue binary_package_action(
......@@ -34,7 +43,7 @@ typedef retvalue binary_package_action(
const char *md5andsize,
/* the pkgs database had an entry of the same name already
(which was considered older), NULL otherwise */
const char *oldchunk);
const char *oldfilekey);
/* call action for each package in packages_file */
retvalue binaries_add(
......
......@@ -37,6 +37,7 @@
#include "checkindeb.h"
#include "reference.h"
#include "packages.h"
#include "binaries.h"
#include "files.h"
#include "extractcontrol.h"
......@@ -127,6 +128,45 @@ retvalue add_package(void *data,const char *chunk,const char *package,const char
return result;
}*/
static retvalue deb_addtodist(const char *dbpath,DB *references,struct distribution *distribution,const char *component,const char *architecture,struct debpackage *package,const char *filekey) {
retvalue result,r;
char *identifier,*oldfilekey,*oldversion;
DB *packages;
identifier = calc_identifier(distribution->codename,component,architecture);
if( ! identifier )
return RET_ERROR_OOM;
packages = packages_initialize(dbpath,identifier);
if( ! packages ) {
free(identifier);
return RET_ERROR;
}
r = binaries_lookforolder(packages,package->package,package->version,&oldversion,&oldfilekey);
if( RET_WAS_ERROR(r) ) {
(void)packages_done(packages);
free(identifier);
return r;
}
if( oldversion ) {
fprintf(stderr,"Version '%s' already in the archive, skipping '%s'\n",oldversion,package->version);
free(oldversion);
result = RET_NOTHING;
} else
result = checkindeb_insert(references,identifier,packages,
package->package, package->control,
filekey, oldfilekey);
r = packages_done(packages);
RET_ENDUPDATE(result,r);
free(identifier);
free(oldfilekey);
return result;
}
/* things to do with .deb's checkin by hand: (by comparison with apt-ftparchive)
- extract the control file (that's the hard part -> extractcontrol.c )
- check for Package, Version, Architecture, Maintainer, Description
......@@ -286,19 +326,14 @@ retvalue deb_complete(struct debpackage *pkg, const char *filekey, const char *m
return RET_OK;
}
retvalue deb_addtodist(const char *distribution,const char *architecture,struct debpackage *package) {
// TODO: implement this one..
return RET_NOTHING;
}
/* insert the given .deb into the mirror in <component> in the <distribution>
* putting things with architecture of "all" into <architectures> (and also
* putting things with architecture of "all" into <d->architectures> (and also
* causing error, if it is not one of them otherwise)
* ([todo:]if component is NULL, using translation table <guesstable>)
* ([todo:]using overwrite-database <overwrite>)*/
retvalue deb_add(DB *filesdb,const char *mirrordir,const char *component,const char *distribution,const struct strlist *architectures,const char *debfilename,int force){
retvalue deb_add(const char *dbdir,DB *references,DB *filesdb,const char *mirrordir,const char *component,struct distribution *distribution,const char *debfilename,int force){
retvalue r,result;
struct debpackage *pkg;
char *filekey,*md5andsize;
......@@ -315,13 +350,28 @@ retvalue deb_add(DB *filesdb,const char *mirrordir,const char *component,const c
// TODO: look for overwrites and things like this here...
/* decide where it has to go */
// TODO: decide what component is, if not yet set...
/* some sanity checks: */
if( component && !strlist_in(&distribution->components,component) ) {
fprintf(stderr,"While checking in '%s': '%s' is not listed in '",
debfilename,component);
strlist_fprint(stderr,&distribution->components);
fputs("'\n",stderr);
if( force <= 0 ) {
deb_free(pkg);
return RET_ERROR;
}
}
if( strcmp(pkg->architecture,"all") != 0 &&
!strlist_in( architectures, pkg->architecture )) {
!strlist_in( &distribution->architectures, pkg->architecture )) {
fprintf(stderr,"While checking in '%s': '%s' is not listed in '",
debfilename,pkg->architecture);
strlist_fprint(stderr,architectures);
strlist_fprint(stderr,&distribution->architectures);
fputs("'\n",stderr);
if( force <= 0 ) {
deb_free(pkg);
......@@ -329,9 +379,7 @@ retvalue deb_add(DB *filesdb,const char *mirrordir,const char *component,const c
}
}
/* decide where it has to go */
// TODO: decide what component is, if not yet set...
/* calculate it's filekey */
filekey = calc_filekey(component,pkg->source,pkg->basename);
/* then looking if we already have this, or copy it in */
......@@ -351,20 +399,20 @@ retvalue deb_add(DB *filesdb,const char *mirrordir,const char *component,const c
return r;
}
free(md5andsize);
free(filekey);
/* finaly put it into one or more distributions */
result = RET_NOTHING;
if( strcmp(pkg->architecture,"all") != 0 ) {
r = deb_addtodist(distribution,pkg->architecture,pkg);
r = deb_addtodist(dbdir,references,distribution,component,pkg->architecture,pkg,filekey);
RET_UPDATE(result,r);
} else for( i = 0 ; i < architectures->count ; i++ ) {
r = deb_addtodist(distribution,architectures->values[i],pkg);
} else for( i = 0 ; i < distribution->architectures.count ; i++ ) {
r = deb_addtodist(dbdir,references,distribution,component,distribution->architectures.values[i],pkg,filekey);
RET_UPDATE(result,r);
}
free(filekey);
deb_free(pkg);
return result;
......
......@@ -5,6 +5,9 @@
#include "error.h"
#warning "What's hapening here?"
#endif
#ifndef __MIRRORER_DISTRIBUTION_H
#include "distribution.h"
#endif
/* Add <package> with filename <filekey> and chunk <chunk> (which
* alreadycontains "Filename:"), add an reference to <referee> in
......@@ -33,6 +36,5 @@ void deb_free(struct debpackage *pkg);
* causing error, if it is not one of them otherwise)
* ([todo:]if component is NULL, using translation table <guesstable>)
* ([todo:]using overwrite-database <overwrite>)*/
retvalue deb_add(DB *filesdb,const char *mirrordir,const char *component,const char *distribution,const struct strlist *architectures,const char *debfilename,int force);
retvalue deb_add(const char *dbdir,DB *references,DB *filesdb,const char *mirrordir,const char *component,struct distribution *distribution,const char *debfilename,int force);
#endif
......@@ -149,3 +149,25 @@ int isVersionNewer(const char *first,const char *second) {
free((char*)v2.version);
return r>0;
}
retvalue dpkgversions_isNewer(const char *first,const char *second) {
struct versionrevision v1,v2;
const char *m;
int r;
if( (m = parseversion(&v1,first)) != NULL ) {
fprintf(stderr,"Error while parsing '%s' as version: %s\n",first,m);
return RET_ERROR;
}
if( (m = parseversion(&v2,second)) != NULL ) {
fprintf(stderr,"Error while parsing '%s' as version: %s\n",second,m);
return RET_ERROR;
}
r = versioncompare(&v1,&v2);
free((char*)v1.version);
free((char*)v2.version);
if( r > 0 )
return RET_OK;
else
return RET_NOTHING;
}
#ifndef __MIRRORER_DPKGVERSIONS
#define __MIRRORER_DPKGVERSIONS
#ifndef __MIRRORER_DPKGVERSIONS_H
#define __MIRRORER_DPKGVERSIONS_H
#ifndef __MIRRORER_ERROR_H
#include "error.h"
#warning wth?
#endif
/* code taken from dpkg to compare to version string, returns
* -2 on parsing errors, 1 if newer, 0 if not */
int isVersionNewer(const char *first,const char *second);
/* return RET_OK, if first >> second, RET_NOTHING if not,
* return error if those are not proper versions */
retvalue dpkgversions_isNewer(const char *first,const char *second);
#endif
......@@ -135,35 +135,40 @@ retvalue files_check(DB *filesdb,const char *filekey,const char *md5sum_and_size
}
}
static retvalue files_calcmd5(char **md5andsize,const char *mirrordir,const char *filekey) {
char *filename;
static retvalue files_calcmd5(char **md5andsize,const char *filename) {
retvalue ret;
filename = calc_fullfilename(mirrordir,filekey);
if( !filename )
return RET_ERROR_OOM;
*md5andsize = NULL;
ret = md5sum_and_size(md5andsize,filename,0);
if( ret == RET_NOTHING ) {
fprintf(stderr,"Error accessing file \"%s\": %m\n",filename);
free(filename);
return RET_ERROR;
}
if( RET_WAS_ERROR(ret) ) {
fprintf(stderr,"Error checking file \"%s\": %m\n",filename);
free(filename);
return ret;
}
free(filename);
if( verbose > 20 ) {
fprintf(stderr,"Md5sum of '%s' is '%s'.\n",filename,*md5andsize);
}
return ret;
}
static retvalue files_calcmd5sum(char **md5andsize,const char *mirrordir,const char *filekey) {
char *filename;
retvalue ret;
filename = calc_fullfilename(mirrordir,filekey);
if( !filename )
return RET_ERROR_OOM;
ret = files_calcmd5(md5andsize,filename);
free(filename);
return ret;
}
/* look for file, calculate its md5sum and add it */
......@@ -171,7 +176,7 @@ retvalue files_detect(DB *filesdb,const char *mirrordir,const char *filekey) {
char *md5andsize;
retvalue ret;
ret = files_calcmd5(&md5andsize,mirrordir,filekey);
ret = files_calcmd5sum(&md5andsize,mirrordir,filekey);
if( RET_WAS_ERROR(ret) )
return ret;
......@@ -332,7 +337,7 @@ retvalue files_checkin(DB *filesdb,const char *mirrordir,const char *filekey,
if( verbose > 10 ) {
fprintf(stderr,"Database says: '%s' already here as '%s'!\n",filekey,(const char *)data.data);
}
r = files_calcmd5(md5andsize,mirrordir,filekey);
r = files_calcmd5(md5andsize,origfilename);
if( RET_WAS_ERROR(r) )
return r;
if( strcmp(*md5andsize,data.data) != 0 ) {
......@@ -361,7 +366,7 @@ retvalue files_checkin(DB *filesdb,const char *mirrordir,const char *filekey,
return r;
}
r = files_calcmd5(md5andsize,mirrordir,filekey);
r = files_calcmd5sum(md5andsize,mirrordir,filekey);
if( RET_WAS_ERROR(r) )
return r;
......
......@@ -313,7 +313,8 @@ static int removepackage(int argc,char *argv[]) {
(void)references_done(refs);
return 1;
}
// TODO: split this in binary/source and use binaries_lookforold
result = RET_NOTHING;
for( i = 2 ; i< argc ; i++ ) {
chunk = packages_get(pkgs,argv[i]);
......@@ -321,7 +322,7 @@ static int removepackage(int argc,char *argv[]) {
fprintf(stderr,"removing '%s' from '%s'...\n",argv[i],argv[1]);
r = packages_remove(pkgs,argv[i]);
if( RET_IS_OK(r) ) {
r = binaries_parse_chunk(chunk,NULL,&filekey,NULL,NULL,NULL);
r = binaries_parse_chunk(chunk,NULL,&filekey,NULL,NULL,NULL,NULL);
if( RET_IS_OK(r) ) {
if( verbose > 1 )
fprintf(stderr,"unreferencing '%s' to '%s' \n",argv[1],filekey);
......@@ -355,7 +356,7 @@ static retvalue reference_binary(void *data,const char *package,const char *chun
char *filekey;
retvalue r;
r = binaries_parse_chunk(chunk,NULL,&filekey,NULL,NULL,NULL);
r = binaries_parse_chunk(chunk,NULL,&filekey,NULL,NULL,NULL,NULL);
if( verbose >= 0 && r == RET_NOTHING ) {
fprintf(stderr,"Package does not look binary: '%s'\n",chunk);
}
......@@ -582,7 +583,7 @@ static int prepareaddsources(int argc,char *argv[]) {
/****************************prepareaddpackages*******************************************/
static retvalue showmissing(void *data,const char *chunk,const char *package,const char *sourcename,const char *oldfile,const char *basename,const char *filekey,const char *md5andsize,const char *oldchunk) {
static retvalue showmissing(void *data,const char *chunk,const char *package,const char *sourcename,const char *oldfile,const char *basename,const char *filekey,const char *md5andsize,const char *oldfilechunk) {
retvalue r;
struct distributionhandles *dist = (struct distributionhandles*)data;
char *fn;
......@@ -647,10 +648,9 @@ static int prepareaddpackages(int argc,char *argv[]) {
/***********************************addpackages*******************************************/
retvalue add_package(void *data,const char *chunk,const char *package,const char *sourcename,const char *oldfile,const char *basename,const char *filekey,const char *md5andsize,const char *oldchunk) {
retvalue add_package(void *data,const char *chunk,const char *package,const char *sourcename,const char *oldfile,const char *basename,const char *filekey,const char *md5andsize,const char *oldfilekey) {
char *newchunk;
retvalue result,r;
char *oldfilekey;
struct distributionhandles *d = data;
/* look for needed files */
......@@ -668,19 +668,9 @@ retvalue add_package(void *data,const char *chunk,const char *package,const char
return RET_ERROR;
/* remove old references to files */
if( oldchunk ) {
r = binaries_parse_chunk(oldchunk,NULL,&oldfilekey,NULL,NULL,NULL);
if( RET_WAS_ERROR(r) ) {
free(newchunk);
return r;
}
} else
oldfilekey = NULL;
result = checkindeb_insert(d->refs,d->referee,d->pkgs,package,newchunk,filekey,oldfilekey);
free(newchunk);
free(oldfilekey);
return result;
}
......@@ -843,7 +833,7 @@ static retvalue exportbin(void *data,const char *component,const char *architect
char *dbname,*filename;
result = release_genbinary(d->distribution,architecture,component,distdir);
dbname = mprintf("%s-%s-%s",d->distribution->codename,component,architecture);
dbname = calc_identifier(d->distribution->codename,component,architecture);
if( !dbname ) {
return RET_ERROR_OOM;
}
......@@ -1025,7 +1015,7 @@ static retvalue rerefbin(void *data,const char *component,const char *architectu
struct referee refdata;
DB *pkgs;
dbname = mprintf("%s-%s-%s",d->distribution->codename,component,architecture);
dbname = calc_identifier(d->distribution->codename,component,architecture);
if( !dbname ) {
return RET_ERROR_OOM;
}
......@@ -1148,7 +1138,7 @@ static retvalue check_binary(void *data,const char *package,const char *chunk) {
char *filekey;
retvalue r;
r = binaries_parse_chunk(chunk,NULL,&filekey,NULL,NULL,NULL);
r = binaries_parse_chunk(chunk,NULL,&filekey,NULL,NULL,NULL,NULL);
if( verbose >= 0 && r == RET_NOTHING ) {
fprintf(stderr,"Package does not look binary: '%s'\n",chunk);
}
......@@ -1167,7 +1157,7 @@ static retvalue checkbin(void *data,const char *component,const char *architectu
char *dbname;
DB *pkgs;
dbname = mprintf("%s-%s-%s",d->distribution->codename,component,architecture);
dbname = calc_identifier(d->distribution->codename,component,architecture);
if( !dbname ) {
return RET_ERROR_OOM;
}
......@@ -1332,22 +1322,34 @@ static int check(int argc,char *argv[]) {
static int adddeb(int argc,char *argv[]) {
retvalue result,r;
DB *files;
DB *files,*references;
struct distribution *distribution;
if( argc < 4 ) {
fprintf(stderr,"mirrorer _adddeb <distribution> <part> <package>\n");
return 1;
}
result = distribution_get(&distribution,confdir,argv[1]);
if( result == RET_NOTHING ) {
fprintf(stderr,"Could not find '%s' in '%s/distributions'!",argv[1],confdir);
return 2;
}
files = files_initialize(dbdir);
if( !files )
return 1;
references = references_initialize(dbdir);
if( !files )
return 1;
//TODO check if distribution is valid and get's its architecture list
result =deb_add(files,mirrordir,argv[2],argv[1],NULL,argv[3],force);
result =deb_add(dbdir,references,files,mirrordir,argv[2],distribution,argv[3],force);
distribution_free(distribution);
r = files_done(files);
RET_ENDUPDATE(result,r);
r = references_done(references);
RET_ENDUPDATE(result,r);
return EXIT_RET(result);
}
......
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