Commit 8b11a1a8 authored by Bernhard Link's avatar Bernhard Link

allow more checksums: part 2 (support for abstract checksums in most of the code)

parent 5df0841d
......@@ -33,7 +33,7 @@
#include "names.h"
#include "dirs.h"
#include "chunks.h"
#include "md5sum.h"
#include "checksums.h"
#include "files.h"
#include "aptmethod.h"
#include "filecntl.h"
......@@ -79,7 +79,8 @@ static void free_todolist(/*@only@*/ struct tobedone *todo) {
free(todo->filekey);
free(todo->filename);
free(todo->md5sum);
if( todo->filekey != NULL )
checksums_free(todo->checksums);
free(todo->uri);
free(todo);
todo = h;
......@@ -350,7 +351,7 @@ inline static retvalue aptmethod_startup(struct aptmethodrun *run,struct aptmeth
/**************************how to add files*****************************/
/*@null@*/static inline struct tobedone *newtodo(const char *baseuri,const char *origfile,const char *destfile,/*@null@*/const char *md5sum,/*@null@*/const char *filekey) {
/*@null@*/static inline struct tobedone *newtodo(const char *baseuri, const char *origfile, const char *destfile, /*@null@*/const struct checksums *checksums, /*@null@*/const char *filekey) {
struct tobedone *todo;
todo = malloc(sizeof(struct tobedone));
......@@ -360,18 +361,20 @@ inline static retvalue aptmethod_startup(struct aptmethodrun *run,struct aptmeth
todo->next = NULL;
todo->uri = calc_dirconcat(baseuri,origfile);
todo->filename = strdup(destfile);
if( filekey != NULL )
if( filekey != NULL ) {
assert( checksums != NULL );
todo->filekey = strdup(filekey);
else
} else
todo->filekey = NULL;
if( md5sum != NULL ) {
todo->md5sum = strdup(md5sum);
if( checksums != NULL ) {
assert( filekey != NULL );
todo->checksums = checksums_dup(checksums);
} else
todo->md5sum = NULL;
todo->checksums = NULL;
if( todo->uri == NULL || todo->filename == NULL ||
(md5sum != NULL && todo->md5sum == NULL) ||
(checksums != NULL && todo->checksums == NULL) ||
(filekey != NULL && todo->filekey == NULL) ) {
free(todo->md5sum);
checksums_free(todo->checksums);
free(todo->uri);
free(todo->filename);
free(todo);
......@@ -380,14 +383,14 @@ inline static retvalue aptmethod_startup(struct aptmethodrun *run,struct aptmeth
return todo;
}
retvalue aptmethod_queuefile(struct aptmethod *method, const char *origfile, const char *destfile, const char *md5sum, const char *filekey, struct tobedone **t) {
retvalue aptmethod_queuefile(struct aptmethod *method, const char *origfile, const char *destfile, const struct checksums *checksums, const char *filekey, struct tobedone **t) {
struct tobedone *todo;
assert( origfile != NULL ); assert( destfile != NULL );
assert( md5sum != NULL ); assert( filekey != NULL );
assert( checksums != NULL ); assert( filekey != NULL );
assert( t != NULL );
todo = newtodo(method->baseuri, origfile, destfile, md5sum, filekey);
todo = newtodo(method->baseuri, origfile, destfile, checksums, filekey);
if( todo == NULL )
return RET_ERROR_OOM;
......@@ -401,15 +404,16 @@ retvalue aptmethod_queuefile(struct aptmethod *method, const char *origfile, con
return RET_OK;
}
retvalue aptmethod_queueindexfile(struct aptmethod *method, const char *origfile, const char *destfile, /*@null@*/const char *md5sum) {
retvalue aptmethod_queueindexfile(struct aptmethod *method, const char *origfile, const char *destfile, /*@null@*/struct checksums **checksums_p) {
struct tobedone *todo;
if( origfile == NULL || destfile == NULL )
return RET_ERROR_OOM;
todo = newtodo(method->baseuri, origfile, destfile, md5sum, NULL);
todo = newtodo(method->baseuri, origfile, destfile, NULL, NULL);
if( todo == NULL )
return RET_ERROR_OOM;
todo->checksums_p = checksums_p;
if( method->lasttobedone == NULL )
method->nexttosend = method->lasttobedone = method->tobedone = todo;
......@@ -423,8 +427,9 @@ retvalue aptmethod_queueindexfile(struct aptmethod *method, const char *origfile
/*****************what to do with received files************************/
/* process a received file, possibly copying it around... */
static inline retvalue todo_done(const struct tobedone *todo,const char *filename,const char *md5sum,struct database *database) {
char *calculatedmd5;
static inline retvalue todo_done(struct tobedone *todo,const char *filename,const char *md5sum,struct database *database) {
struct checksums *checksums;
struct checksums **checksums_p;
/* if the file is somewhere else, copy it: */
if( strcmp(filename,todo->filename) != 0 ) {
......@@ -434,14 +439,14 @@ static inline retvalue todo_done(const struct tobedone *todo,const char *filenam
if( verbose > 1 )
fprintf(stderr,
"Copy file '%s' to '%s'...\n", filename, todo->filename);
r = md5sum_copy(filename, todo->filename,
&calculatedmd5);
r = checksums_copyfile(todo->filename, filename,
&checksums);
} else {
if( verbose > 1 )
fprintf(stderr,
"Linking file '%s' to '%s'...\n", filename, todo->filename);
r = md5sum_place(filename, todo->filename,
&calculatedmd5);
r = checksums_linkorcopyfile(todo->filename, filename,
&checksums);
}
if( r == RET_NOTHING ) {
fprintf(stderr,"Cannot open '%s', which was given by method.\n",filename);
......@@ -449,41 +454,58 @@ static inline retvalue todo_done(const struct tobedone *todo,const char *filenam
}
if( RET_WAS_ERROR(r) )
return r;
/* this we trust more */
// todo: reimplement the pure copyfile without md5sum?
md5sum = calculatedmd5;
} else {
retvalue r;
/* if it should be in place, calculate its md5sum, if needed */
if( todo->md5sum != NULL && md5sum == NULL) {
r = md5sum_read(filename,&calculatedmd5);
/* if it is already in place, calculate its md5sum, if needed */
// TODO: use values supplied by method
// (research if methods nowadays supply more then md5sum)
if( todo->filekey != NULL || todo->checksums_p != NULL ) {
r = checksums_read(filename, &checksums);
if( r == RET_NOTHING ) {
fprintf(stderr,"Cannot open '%s', which was given by method.\n",filename);
r = RET_ERROR_MISSING;
}
if( RET_WAS_ERROR(r) )
return r;
md5sum = calculatedmd5;
} else
calculatedmd5 = NULL;
checksums = NULL;
}
if( todo->filekey != NULL )
checksums_p = &todo->checksums;
else
checksums_p = todo->checksums_p;
/* if we know what it should be, check it: */
if( todo->md5sum != NULL ) {
if( md5sum == NULL || strcmp(md5sum,todo->md5sum) != 0) {
fprintf(stderr,"Receiving '%s' wrong md5sum: got '%s' expected '%s'!\n",todo->uri,md5sum,todo->md5sum);
free(calculatedmd5);
if( checksums_p != NULL ) {
bool improves;
assert( checksums != NULL );
assert( *checksums_p != NULL );
if( !checksums_check(*checksums_p, checksums, &improves) ) {
fprintf(stderr,"Receiving '%s' wrong checksums: ", todo->uri);
checksums_printdifferences(stderr, *checksums_p,
checksums);
checksums_free(checksums);
return RET_ERROR_WRONG_MD5;
}
if( improves ) {
retvalue r;
r = checksums_combine(checksums_p, checksums);
if( RET_WAS_ERROR(r) ) {
checksums_free(checksums);
return r;
}
}
}
free(calculatedmd5); md5sum=NULL;
checksums_free(checksums);
if( todo->filekey != NULL ) {
retvalue r;
assert(todo->md5sum != NULL);
r = files_add(database, todo->filekey, todo->md5sum);
assert(todo->checksums != NULL);
r = files_add_checksums(database, todo->filekey, todo->checksums);
if( RET_WAS_ERROR(r) )
return r;
}
......@@ -595,7 +617,8 @@ static retvalue uridone(struct aptmethod *method,const char *uri,const char *fil
}
free(todo->uri);
free(todo->filename);
free(todo->md5sum);
if( todo->filekey != NULL )
checksums_free(todo->checksums);
free(todo->filekey);
free(todo);
/* if everything is done, redo failed */
......
......@@ -4,6 +4,9 @@
#ifndef REPREPRO_DATABASE_H
#include "database.h"
#endif
#ifndef REPREPRO_CHECKSUMS_H
#include "checksums.h"
#endif
struct aptmethodrun;
struct aptmethod;
......@@ -16,20 +19,23 @@ struct tobedone {
char *uri;
/*@notnull@*/
char *filename;
/* if non-NULL, what is expected...*/
/*@null@*/
char *md5sum;
/* if non-NULL, add to the database after found (only if md5sum != NULL) */
/* if non-NULL, add to the database after found (needs md5sum != NULL) */
/*@null@*/
char *filekey;
union {
/* if filekey != NULL */
struct checksums *checksums;
/* if filekey == NULL: */
/*@null@*/ struct checksums **checksums_p;
};
};
retvalue aptmethod_initialize_run(/*@out@*/struct aptmethodrun **run);
retvalue aptmethod_newmethod(struct aptmethodrun *, const char *uri, const char *fallbackuri, const struct strlist *config, /*@out@*/struct aptmethod **);
/* md5sum can be NULL(filekey then, too): if todo != NULL, then *todo will be set */
retvalue aptmethod_queuefile(struct aptmethod *, const char *origfile, const char *destfile, const char *md5sum, const char *filekey, /*@out@*/struct tobedone **);
retvalue aptmethod_queueindexfile(struct aptmethod *, const char *origfile, const char *destfile, /*@null@*/const char *md5sum);
retvalue aptmethod_queuefile(struct aptmethod *, const char *origfile, const char *destfile, const struct checksums *, const char *filekey, /*@out@*/struct tobedone **);
retvalue aptmethod_queueindexfile(struct aptmethod *, const char *origfile, const char *destfile, /*@null@*/struct checksums **);
retvalue aptmethod_download(struct aptmethodrun *run,const char *methoddir,struct database *);
retvalue aptmethod_shutdown(/*@only@*/struct aptmethodrun *run);
......
......@@ -39,11 +39,11 @@
extern int verbose;
/* get md5sums out of a "Packages.gz"-chunk. */
static retvalue binaries_parse_md5sum(const char *chunk,/*@out@*/struct strlist *md5sums) {
static retvalue binaries_parse_md5sum(const char *chunk, /*@out@*/struct checksums **checksums_p) {
retvalue r;
/* collect the given md5sum and size */
char *pmd5,*psize,*md5sum;
char *pmd5, *psize;
r = chunk_getvalue(chunk,"MD5sum",&pmd5);
if( r == RET_NOTHING ) {
......@@ -62,16 +62,7 @@ static retvalue binaries_parse_md5sum(const char *chunk,/*@out@*/struct strlist
free(pmd5);
return r;
}
md5sum = calc_concatmd5andsize(pmd5,psize);
free(pmd5);free(psize);
if( md5sum == NULL ) {
return RET_ERROR_OOM;
}
r = strlist_init_singleton(md5sum,md5sums);
if( RET_WAS_ERROR(r) ) {
return r;
}
return RET_OK;
return checksums_init(checksums_p, psize, pmd5);
}
/* get somefields out of a "Packages.gz"-chunk. returns RET_OK on success, RET_NOTHING if incomplete, error otherwise */
......@@ -121,7 +112,7 @@ static retvalue binaries_parse_chunk(const char *chunk,const char *packagename,c
}
/* get files out of a "Packages.gz"-chunk. */
static retvalue binaries_parse_getfilekeys(const char *chunk,struct strlist *files) {
retvalue binaries_getfilekeys(const char *chunk, struct strlist *files) {
retvalue r;
char *filename;
......@@ -194,50 +185,59 @@ retvalue binaries_getversion(UNUSED(struct target *t),const char *control,char *
return r;
}
retvalue binaries_getinstalldata(struct target *t,const char *packagename,const char *version,const char *chunk,char **control,struct strlist *filekeys,struct strlist *md5sums,struct strlist *origfiles) {
retvalue binaries_getinstalldata(struct target *t, const char *packagename, const char *version, const char *chunk, char **control, struct strlist *filekeys, struct checksumsarray *origfiles) {
char *sourcename IFSTUPIDCC(=NULL) ,*basename IFSTUPIDCC(=NULL);
struct strlist mymd5sums;
struct checksumsarray origfilekeys;
retvalue r;
r = binaries_parse_md5sum(chunk,&mymd5sums);
if( RET_WAS_ERROR(r) )
return r;
r = binaries_parse_chunk(chunk,packagename,t->packagetype,version,&sourcename,&basename);
if( RET_WAS_ERROR(r) ) {
strlist_done(&mymd5sums);
return r;
} else if( r == RET_NOTHING ) {
fprintf(stderr,"Does not look like a binary package: '%s'!\n",chunk);
return RET_ERROR;
}
r = binaries_parse_getfilekeys(chunk,origfiles);
r = binaries_getchecksums(chunk, &origfilekeys);
if( RET_WAS_ERROR(r) ) {
free(sourcename);free(basename);
strlist_done(&mymd5sums);
return r;
}
r = calcnewcontrol(chunk,sourcename,basename,t->component,filekeys,control);
if( RET_WAS_ERROR(r) ) {
strlist_done(&mymd5sums);
checksumsarray_done(&origfilekeys);
} else {
assert( r != RET_NOTHING );
strlist_move(md5sums,&mymd5sums);
checksumsarray_move(origfiles, &origfilekeys);
}
free(sourcename);free(basename);
return r;
}
retvalue binaries_getfilekeys(UNUSED(struct target *t),const char *chunk,struct strlist *filekeys,struct strlist *md5sums) {
retvalue binaries_getchecksums(const char *chunk, struct checksumsarray *filekeys) {
retvalue r;
r = binaries_parse_getfilekeys(chunk,filekeys);
struct checksumsarray a;
r = binaries_getfilekeys(chunk, &a.names);
if( RET_WAS_ERROR(r) )
return r;
if( md5sums == NULL )
return r;
r = binaries_parse_md5sum(chunk,md5sums);
return r;
assert( a.names.count == 1 );
a.checksums = malloc(sizeof(struct checksums *));
if( a.checksums == NULL ) {
strlist_done(&a.names);
return RET_ERROR_OOM;
}
r = binaries_parse_md5sum(chunk, a.checksums);
assert( r != RET_NOTHING );
if( RET_WAS_ERROR(r) ) {
free(a.checksums);
strlist_done(&a.names);
return RET_ERROR_OOM;
}
checksumsarray_move(filekeys, &a);
return RET_OK;
}
char *binaries_getupstreamindex(UNUSED(struct target *target),const char *suite_from,
const char *component_from,const char *architecture) {
return mprintf("dists/%s/%s/binary-%s/Packages.gz",suite_from,component_from,architecture);
......
......@@ -16,8 +16,9 @@
/* Functions for the target.h-stuff: */
retvalue binaries_getname(struct target *t,const char *chunk,char **packagename);
retvalue binaries_getversion(struct target *t,const char *chunk,char **version);
retvalue binaries_getinstalldata(struct target *t,const char *packagename,const char *version,const char *chunk,char **control,struct strlist *filekeys,struct strlist *md5sums,struct strlist *origfiles);
retvalue binaries_getfilekeys(struct target *t,const char *chunk,struct strlist *filekeys,struct strlist *md5sums);
retvalue binaries_getinstalldata(struct target *t, const char *packagename, const char *version, const char *chunk, /*@out@*/char **control, /*@out@*/struct strlist *filekeys, /*@out@*/struct checksumsarray *origfiles);
retvalue binaries_getfilekeys(const char *chunk, /*@out@*/struct strlist *);
retvalue binaries_getchecksums(const char *chunk, /*@out@*/struct checksumsarray *);
char *binaries_getupstreamindex(struct target *target,const char *suite_from,
const char *component_from,const char *architecture);
char *ubinaries_getupstreamindex(struct target *target,const char *suite_from,
......
......@@ -988,7 +988,7 @@ retvalue changes_add(struct database *database,trackingdb const tracks,const cha
r = files_include(database,
changesfilename,
changes->changesfilekey,
NULL, NULL, D_COPY);
NULL, D_COPY);
if( RET_WAS_ERROR(r) ) {
changes_free(changes);
trackingdata_done(&trackingdata);
......
......@@ -262,8 +262,7 @@ retvalue dsc_prepare(struct dscpackage **dsc, struct database *database, const c
const char *md5sum = pkg->dsc.md5sums.values[i];
r = files_includefile(database, sourcedir,
basename, filekey, md5sum,
NULL, D_INPLACE);
basename, filekey, md5sum, D_INPLACE);
}
}
......@@ -431,8 +430,7 @@ retvalue dsc_add(struct database *database,const char *forcecomponent,const char
const char *md5sum = pkg->dsc.md5sums.values[i];
r = files_includefile(database, origdirectory,
basename, filekey, md5sum,
NULL, delete);
basename, filekey, md5sum, delete);
}
}
free(origdirectory);
......
......@@ -15,15 +15,20 @@
*/
#include <config.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <sys/types.h>
#include <malloc.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include "error.h"
#include "checksums.h"
#include "names.h"
#include "md5sum.h"
/* yet only an evil stub, putting the old md5sums in faked struct pointers
......@@ -39,6 +44,25 @@ retvalue checksums_set(struct checksums **result, char *md5sum) {
return RET_OK;
}
retvalue checksums_init(/*@out@*/struct checksums **checksums_p, /*@only@*/char *size, /*@only@*/char *md5) {
char *md5sum = calc_concatmd5andsize(md5, size);
char **md5sum_p = (char**)checksums_p;
free(md5);free(size);
if( md5sum == NULL ) {
return RET_ERROR_OOM;
}
*md5sum_p = md5sum;
return RET_OK;
}
struct checksums *checksums_dup(const struct checksums *checksums) {
const char *md5sum = (char*)checksums;
char *result = strdup(md5sum);
return (struct checksums *)result;
}
retvalue checksums_get(const struct checksums *checksums, enum checksumtype type, char **result) {
char *md5sum;
......@@ -78,6 +102,33 @@ retvalue checksums_getpart(const struct checksums *checksums, enum checksumtype
return RET_NOTHING;
}
retvalue checksums_getfilesize(const struct checksums *checksums, off_t *size_p) {
const char *md5sum = (char*)checksums;
const char *p = md5sum;
off_t filesize;
/* over md5 part to the length part */
while( *p != ' ' && *p != '\0' )
p++;
if( *p != ' ' ) {
fprintf(stderr, "Cannot extract filesize from '%s'\n", md5sum);
return RET_ERROR;
}
while( *p == ' ' )
p++;
filesize = 0;
while( *p <= '9' && *p >= '0' ) {
filesize = filesize*10 + (*p-'0');
p++;
}
if( *p != '\0' ) {
fprintf(stderr, "Cannot extract filesize from '%s'\n", md5sum);
return RET_ERROR;
}
*size_p = filesize;
return RET_OK;
}
bool checksums_matches(const struct checksums *checksums,enum checksumtype type, const char *sum) {
if( type == cs_md5sum )
return strcmp((char*)checksums,sum) == 0;
......@@ -91,6 +142,12 @@ retvalue checksums_copyfile(const char *dest, const char *orig, struct checksums
return md5sum_copy(orig, dest, md5sum_p);
}
retvalue checksums_linkorcopyfile(const char *dest, const char *orig, struct checksums **checksum_p) {
char **md5sum_p = (char**)checksum_p;
return md5sum_place(orig, dest, md5sum_p);
}
retvalue checksums_read(const char *fullfilename, /*@out@*/struct checksums **checksum_p) {
char **md5sum_p = (char**)checksum_p;
......@@ -112,7 +169,93 @@ void checksums_printdifferences(FILE *f, const struct checksums *expected, const
fprintf(f, "expected: %s, got: %s\n", md5expected, md5got);
}
retvalue checksums_combine(struct checksums **checksums, struct checksums *by) {
free(by);
assert( checksums != checksums );
retvalue checksums_combine(struct checksums **checksums, const struct checksums *by) {
assert( checksums != checksums && by != by);
return RET_OK;
}
void checksumsarray_done(struct checksumsarray *array) {
if( array->names.count > 0 ) {
size_t i;
for( i = 0 ; i < array->names.count ; i++ ) {
checksums_free(array->checksums[i]);
}
} else
assert( array->checksums == NULL );
strlist_done(&array->names);
free(array->checksums);
}
retvalue checksumsarray_parse(struct checksumsarray *out, const struct strlist *lines) {
retvalue r;
int i;
struct checksumsarray a;
r = strlist_init_n(lines->count, &a.names);
if( RET_WAS_ERROR(r) )
return r;
a.checksums = calloc(lines->count, sizeof(struct checksums *));
if( lines->count > 0 && a.checksums == NULL ) {
strlist_done(&a.names);
return RET_ERROR_OOM;
}
for( i = 0 ; i < lines->count ; i++ ) {
char *filename, *md5sum;
r = calc_parsefileline(lines->values[i], &filename, &md5sum);
if( RET_WAS_ERROR(r) ) {
checksumsarray_done(&a);
return r;
}
r = checksums_set(&a.checksums[i], md5sum);
if( RET_WAS_ERROR(r) ) {
free(filename);
checksumsarray_done(&a);
return r;
}
r = strlist_add(&a.names, filename);
if( RET_WAS_ERROR(r) ) {
checksumsarray_done(&a);
return r;
}
}
checksumsarray_move(out, &a);
return RET_OK;
}
void checksumsarray_move(/*@out@*/struct checksumsarray *destination, struct checksumsarray *origin) {
strlist_move(&destination->names, &origin->names);
destination->checksums = origin->checksums;
origin->checksums = NULL;
}
/* check if the file has the given md5sum (only cheap tests like size),
* RET_NOTHING means file does not exist, RET_ERROR_WRONG_MD5 means wrong size */
retvalue checksums_cheaptest(const char *fullfilename, const struct checksums *checksums) {
off_t expectedsize;
retvalue r;
int i;
struct stat s;
i = stat(fullfilename, &s);
if( i < 0 ) {
i = errno;
if( i == EACCES || i == ENOENT )
return RET_NOTHING;
else {
fprintf(stderr,"Error %d stating '%s': %s!\n",
i, fullfilename, strerror(i));
return RET_ERRNO(i);
}
}
r = checksums_getfilesize(checksums, &expectedsize);
assert( r != RET_NOTHING );
if( RET_WAS_ERROR(r) )
return r;
if( s.st_size == expectedsize )
return RET_OK;
else
return RET_ERROR_WRONG_MD5;
}
......@@ -5,6 +5,9 @@
#include "error.h"
#warning "What's hapening here?"
#endif
#ifndef REPREPRO_STRLIST_H
#include "strlist.h"
#endif
enum checksumtype { cs_md5sum, cs_sha1sum, cs_count };
......@@ -12,11 +15,17 @@ struct checksums;
void checksums_free(/*@only@*//*@null@*/struct checksums *);
/* duplicate a checksum record, NULL means OOM */
struct checksums *checksums_dup(const struct checksums *);
/* create a checksum record from an md5sum: */
retvalue checksums_set(/*@out@*/struct checksums **, /*@only@*/char *);
retvalue checksums_init(/*@out@*/struct checksums **, /*@only@*/char *size, /*@only@*/char *md5);
/* extract a single checksum from the combined data: */
retvalue checksums_get(const struct checksums *, enum checksumtype, /*@out@*/char **);
retvalue checksums_getfilesize(const struct checksums *, off_t *);
/* get a static pointer to a specific part of a checksum (wihtout size) */
retvalue checksums_getpart(const struct checksums *, enum checksumtype, /*@out@*/const char **, /*@out@*/size_t *);
......@@ -27,19 +36,34 @@ bool checksums_matches(const struct checksums *,enum checksumtype, const char *)
/* Copy file <origin> to file <destination>, calculating checksums */
retvalue checksums_copyfile(const char *destination, const char *origin, /*@out@*/struct checksums **);
retvalue checksums_linkorcopyfile(const char *destination, const char *origin, /*@out@*/struct checksums **);
/* calculare checksums of a file: */
retvalue checksums_read(const char *fullfilename, /*@out@*/struct checksums **);
/* check if the file has the given md5sum (only cheap tests like size),
* RET_NOTHING means file does not exist, RET_ERROR_WRONG_MD5 means wrong size */
retvalue checksums_cheaptest(const char *fullfilename, const struct checksums *);
/* check if checksum of filekey in database and checksum of actual file, set improve if some new has is in the last */
bool checksums_check(const struct checksums *, const struct checksums *, /*@out@*/bool *improves);
void checksums_printdifferences(FILE *,const struct checksums *expected, const struct checksums *got);
retvalue checksums_combine(struct checksums **checksums, /*@only@*/struct checksums *by);
retvalue checksums_combine(struct checksums **checksums, const struct checksums *by);
struct checksumsarray {
struct strlist names;
/*@null@*/struct checksums **checksums;
};
void checksumsarray_move(/*@out@*/struct checksumsarray *, struct checksumsarray *);
void checksumsarray_done(struct checksumsarray *);
retvalue checksumsarray_parse(/*@out@*/struct checksumsarray *, const struct strlist *);
/* stuff still in md5sums.c: */
retvalue checksum_read(const char *filename, /*@out@*/char **md5sum, /*@out@*/char **sha1sum);
retvalue checksum_complete(const char *directory, const char *filename, char *hashes[cs_count]);
retvalue checksum_combine(char **, const char *[cs_count]);
retvalue checksum_dismantle(const char *, char *[cs_count]);
#endif
/* This file is part of "reprepro"
* Copyright (C) 2006 Bernhard R. Link
* Copyright (C) 2006,2007 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.
......@@ -25,9 +25,11 @@
#include "donefile.h"
#include "names.h"
#include "checksums.h"
retvalue donefile_isold(const char *filename, const char *expected) {
retvalue donefile_isold(const char *filename, const struct checksums *expected) {
char buffer[200];
const char *start;
size_t len;
ssize_t bytes;
int fd;
......@@ -66,13 +68,25 @@ retvalue donefile_isold(const char *filename, const char *expected) {
free(donefilename);
(void)close(fd);
buffer[len] = '\0';
if( strcmp(expected, buffer) == 0 )
start = buffer;
/* for future extensibility: */
while( *start == ':' ) {
start++;
while( *start != ' ' && *start != '\0' )
start++;
if( *start == ' ' )
start++;
}
if( checksums_matches(expected, cs_md5sum, start) )
return RET_NOTHING;
else
return RET_OK;
}
retvalue donefile_create(const char *filename, const char *expected) {
retvalue donefile_create(const char *filename, const struct checksums *checksums) {
retvalue r;
char *md5sum;
const char *start;
size_t len;
ssize_t written;
int fd;
......@@ -82,6 +96,11 @@ retvalue donefile_create(const char *filename, const char *expected) {
if( donefilename == NULL )
return RET_ERROR_OOM;
r = checksums_get(checksums, cs_md5sum, &md5sum);
assert( r != RET_NOTHING );
if( RET_WAS_ERROR(r) )
return r;
fd = open(donefilename, O_WRONLY|O_CREAT|O_TRUNC|O_NOCTTY|O_NOFOLLOW,
0666);
if( fd < 0 ) {
......@@ -89,15 +108,18 @@ retvalue donefile_create(const char *filename, const char *expected) {
fprintf(stderr, "Error creating file %s: %d=%s\n",
donefilename, e, strerror(e));
free(donefilename);
free(md5sum);
return RET_ERRNO(e);
}
len = strlen(expected);
start = md5sum;
len = strlen(md5sum);