Commit 0b7e4921 authored by Bernhard Link's avatar Bernhard Link

add Contents file generation code

parent 9f81f744
2006-05-12 Bernhard R. Link <brlink@debian.org>
* add content file generation
2006-05-07 Bernhard R. Link <brlink@debian.org>
* add support for extracting filelists from
Debian packages for future usage and a
......
......@@ -5,20 +5,20 @@ EXTRA_DIST = autogen.sh
bin_PROGRAMS = reprepro
if HAVE_LIBARCHIVE
ARCHIVE_USED = ar.c debfile.c
ARCHIVE_UNUSED = extractcontrol.c
ARCHIVE_USED = ar.c debfile.c filelist.c
ARCHIVE_UNUSED = extractcontrol.c
else
ARCHIVE_USED = extractcontrol.c
ARCHIVE_UNUSED = ar.c debfile.c
ARCHIVE_UNUSED = ar.c debfile.c filelist.c
endif
AM_CPPFLAGS = -D_GNU_SOURCE=1 -Wall $(ARCHIVECPP)
reprepro_LDADD = $(ARCHIVELIBS)
reprepro_SOURCES = guesscomponent.c files.c md5.c md5sum.c dirs.c chunks.c reference.c packages.c binaries.c sources.c names.c dpkgversions.c release.c mprintf.c updates.c strlist.c signature.c distribution.c checkindeb.c checkindsc.c checkin.c copyfile.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 $(ARCHIVE_USED)
reprepro_SOURCES = guesscomponent.c files.c md5.c md5sum.c dirs.c chunks.c reference.c packages.c binaries.c sources.c names.c dpkgversions.c release.c mprintf.c updates.c strlist.c signature.c distribution.c checkindeb.c checkindsc.c checkin.c copyfile.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 $(ARCHIVE_USED)
EXTRA_reprepro_SOURCE = $(ARCHIVE_UNUSED)
noinst_HEADERS = guesscomponent.h md5.h md5sum.h dirs.h files.h chunks.h reference.h packages.h binaries.h sources.h names.h release.h error.h mprintf.h updates.h strlist.h signature.h distribution.h debfile.h checkindeb.h checkindsc.h copyfile.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
noinst_HEADERS = guesscomponent.h md5.h md5sum.h dirs.h files.h chunks.h reference.h packages.h binaries.h sources.h names.h release.h error.h mprintf.h updates.h strlist.h signature.h distribution.h debfile.h checkindeb.h checkindsc.h copyfile.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
MAINTAINERCLEANFILES = Makefile.in configure install-sh stamp-h.in aclocal.m4 config.h.in mkinstalldirs config.guess config.sub missing
......
......@@ -10,6 +10,7 @@ Updates since 0.8.2:
- fix segfault of checkupdate
- fix including a changes file with source and restricting
to some binary distribution or to binary package type.
- added Contents file generation support
Updates since 0.8.1:
- mark process list files and only skip those not marked
......
This diff is collapsed.
#ifndef REPREPRO_CONTENTS_H
#define REPREPRO_CONTENTS_H
#ifndef REPREPRO_STRLIST_H
#include "strlist.h"
#endif
#ifndef REPREPRO_RELEASE_H
#include "release.h"
#endif
struct contentsoptions {
size_t rate;
struct {
bool_t udebs:1;
bool_t nodebs:1;
} flags;
compressionset compressions;
struct strlist architectures,
components,
ucomponents;
};
void contentsoptions_done(struct contentsoptions *options);
struct distribution;
retvalue contentsoptions_parse(struct distribution *distribution,
const char *chunk);
retvalue contents_generate(filesdb files, struct distribution *distribution, const char *dbdir, struct release *release, bool_t onlyneeded);
#endif
......@@ -206,23 +206,24 @@ retvalue extractcontrol(char **control,const char *debfile) {
return RET_ERROR_MISSING;
}
static retvalue read_data_tar(/*@out@*/struct strlist *list, const char *debfile, struct ar_archive *ar, struct archive *tar) {
static retvalue read_data_tar(/*@out@*/char **list, const char *debfile, struct ar_archive *ar, struct archive *tar) {
struct archive_entry *entry;
struct strlist filelist;
char *filelist;
size_t size,len;
int a;
retvalue r;
r = strlist_init(&filelist);
if( RET_WAS_ERROR(r) ) {
return r;
}
size = 2000; len = 0;
filelist = malloc(size);
if( filelist == NULL )
return RET_ERROR_OOM;
archive_read_support_format_tar(tar);
a = archive_read_open(tar,ar,
ar_archivemember_open,
ar_archivemember_read,
ar_archivemember_close);
if( a != ARCHIVE_OK ) {
strlist_done(&filelist);
free(filelist);
fprintf(stderr,"open data.tar.gz within '%s' failed: %d:%d:%s\n",
debfile,
a,archive_errno(tar),
......@@ -232,7 +233,6 @@ static retvalue read_data_tar(/*@out@*/struct strlist *list, const char *debfile
while( (a=archive_read_next_header(tar, &entry)) == ARCHIVE_OK ) {
const char *name = archive_entry_pathname(entry);
mode_t mode;
char *n;
if( name[0] == '.' )
name++;
......@@ -242,16 +242,27 @@ static retvalue read_data_tar(/*@out@*/struct strlist *list, const char *debfile
continue;
mode = archive_entry_mode(entry);
if( !S_ISDIR(mode) ) {
n = strdup(name);
if( n == NULL ) {
strlist_done(&filelist);
return RET_ERROR_OOM;
}
r = strlist_add(&filelist, n);
if( RET_WAS_ERROR(r) ) {
strlist_done(&filelist);
return r;
size_t n_len = strlen(name);
if( len + n_len + 2 > size ) {
char *n;
if( size > 1024*1024*1024 ) {
fprintf(stderr, "Ridicilous long filelist for %s!",debfile);
free(filelist);
return RET_ERROR;
}
size = len + n_len + 2048;
n = realloc(filelist, size);
if( n == NULL ) {
free(filelist);
return RET_ERROR_OOM;
}
filelist = n;
}
memcpy(filelist + len, name, n_len+1);
len += n_len+1;
}
a = archive_read_data_skip(tar);
if( a != ARCHIVE_OK ) {
......@@ -260,7 +271,7 @@ static retvalue read_data_tar(/*@out@*/struct strlist *list, const char *debfile
archive_entry_pathname(entry),
debfile,
e, archive_error_string(tar));
strlist_done(&filelist);
free(filelist);
return (e!=0)?(RET_ERRNO(e)):RET_ERROR;
}
}
......@@ -269,14 +280,20 @@ static retvalue read_data_tar(/*@out@*/struct strlist *list, const char *debfile
printf("Error reading data.tar.gz from %s: %d=%s\n",
debfile,
e, archive_error_string(tar));
free(filelist);
return (e!=0)?(RET_ERRNO(e)):RET_ERROR;
}
strlist_move(list,&filelist);
filelist[len] = '\0';
*list = realloc(filelist, len+1);
if( *list == NULL ) {
free(filelist);
return RET_ERROR_OOM;
}
return RET_OK;
}
retvalue getfilelist(/*@out@*/struct strlist *filelist, const char *debfile) {
retvalue getfilelist(/*@out@*/char **filelist, const char *debfile) {
struct ar_archive *ar;
retvalue r;
......
......@@ -15,7 +15,7 @@ retvalue extractcontrol(/*@out@*/char **control,const char *debfile);
/* The following are only in debfile.c and not in extractcontrol.c,
* thus only available when compiled with libarchive */
retvalue getfilelist(/*@out@*/struct strlist *filelist, const char *debfile);
retvalue getfilelist(/*@out@*/char **filelist, const char *debfile);
#endif
......
......@@ -16,6 +16,7 @@
#include <config.h>
#include <errno.h>
#include <limits.h>
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
......@@ -27,6 +28,7 @@
#include <time.h>
#include <zlib.h>
#include "error.h"
#include "mprintf.h"
#include "chunks.h"
#include "sources.h"
#include "md5sum.h"
......@@ -62,6 +64,7 @@ retvalue distribution_free(struct distribution *distribution) {
exportmode_done(&distribution->dsc);
exportmode_done(&distribution->deb);
exportmode_done(&distribution->udeb);
contentsoptions_done(&distribution->contents);
result = RET_OK;
while( distribution->targets != NULL ) {
......@@ -175,7 +178,8 @@ static const char * const allowedfields[] = {
"Architectures", "Components", "Update", "SignWith", "DebOverride",
"UDebOverride", "DscOverride", "Tracking", "NotAutomatic",
"UDebComponents", "DebIndices", "DscIndices", "UDebIndices",
"Pull",
"Pull", "Contents", "ContentsArchitectures",
"ContentsComponents", "ContentsUComponents",
NULL};
assert( chunk !=NULL && distribution != NULL );
......@@ -321,6 +325,12 @@ NULL};
return ret;
}
ret = contentsoptions_parse(r, chunk);
if( RET_WAS_ERROR(ret) ) {
(void)distribution_free(r);
return ret;
}
ret = createtargets(r);
if( RET_WAS_ERROR(ret) ) {
(void)distribution_free(r);
......@@ -475,7 +485,7 @@ retvalue distribution_get(struct distribution **distribution,const char *confdir
static retvalue export(struct distribution *distribution,
const char *confdir, const char *dbdir, const char *distdir,
bool_t onlyneeded) {
filesdb files, bool_t onlyneeded) {
struct target *target;
retvalue result,r;
struct release *release;
......@@ -503,6 +513,9 @@ static retvalue export(struct distribution *distribution,
break;
}
}
if( !RET_WAS_ERROR(result) && distribution->contents.rate > 0 ) {
r = contents_generate(files, distribution, dbdir, release, onlyneeded);
}
if( RET_WAS_ERROR(result) )
release_free(release);
else {
......@@ -516,8 +529,8 @@ static retvalue export(struct distribution *distribution,
return result;
}
retvalue distribution_fullexport(struct distribution *distribution,const char *confdir,const char *dbdir,const char *distdir) {
return export(distribution,confdir,dbdir,distdir,FALSE);
retvalue distribution_fullexport(struct distribution *distribution,const char *confdir,const char *dbdir,const char *distdir, filesdb files) {
return export(distribution,confdir,dbdir,distdir,files,FALSE);
}
retvalue distribution_freelist(struct distribution *distributions) {
......@@ -535,7 +548,8 @@ retvalue distribution_freelist(struct distribution *distributions) {
retvalue distribution_exportandfreelist(enum exportwhen when,
struct distribution *distributions,
const char *confdir,const char *dbdir, const char *distdir) {
const char *confdir,const char *dbdir, const char *distdir,
filesdb files) {
retvalue result,r;
bool_t todo = FALSE;
struct distribution *d;
......@@ -585,7 +599,7 @@ retvalue distribution_exportandfreelist(enum exportwhen when,
"Please report this and how you got this message as bugreport. Thanks.\n"
"Doing a export despite --export=changed....\n",
d->codename);
r = export(d,confdir,dbdir,distdir,TRUE);
r = export(d,confdir,dbdir,distdir,files,TRUE);
RET_UPDATE(result,r);
break;
}
......@@ -595,7 +609,7 @@ retvalue distribution_exportandfreelist(enum exportwhen when,
( d->status == RET_NOTHING &&
when != EXPORT_CHANGED) ||
when == EXPORT_FORCE);
r = export(d,confdir,dbdir,distdir,TRUE);
r = export(d,confdir,dbdir,distdir,files, TRUE);
RET_UPDATE(result,r);
}
......@@ -605,7 +619,7 @@ retvalue distribution_exportandfreelist(enum exportwhen when,
return result;
}
retvalue distribution_export(enum exportwhen when, struct distribution *distribution,const char *confdir,const char *dbdir,const char *distdir) {
retvalue distribution_export(enum exportwhen when, struct distribution *distribution,const char *confdir,const char *dbdir,const char *distdir, filesdb files) {
if( when == EXPORT_NEVER ) {
if( verbose >= 10 )
fprintf(stderr,
......@@ -639,7 +653,7 @@ retvalue distribution_export(enum exportwhen when, struct distribution *distribu
"Doing a export despite --export=changed....\n",
distribution->codename);
return export(distribution,
confdir,dbdir,distdir,TRUE);
confdir,dbdir,distdir,files,TRUE);
break;
}
}
......@@ -648,6 +662,6 @@ retvalue distribution_export(enum exportwhen when, struct distribution *distribu
}
if( verbose >= 0 )
fprintf(stderr, "Exporting indices...\n");
return export(distribution,confdir,dbdir,distdir,TRUE);
return export(distribution,confdir,dbdir,distdir,files, TRUE);
}
......@@ -16,6 +16,9 @@ struct distribution;
#ifndef REPREPRO_EXPORTS_H
#include "exports.h"
#endif
#ifndef REPREPRO_CONTENTS_H
#include "contents.h"
#endif
struct distribution {
struct distribution *next;
......@@ -47,6 +50,8 @@ struct distribution {
bool_t needsources:1;
bool_t embargoalls:1;
} trackingoptions;
/* what content files to generate */
struct contentsoptions contents;
/* A list of all targets contained in the distribution*/
struct target *targets;
/* RET_NOTHING: do not export with EXPORT_CHANGED, EXPORT_NEVER
......@@ -67,14 +72,14 @@ retvalue distribution_foreach_part(struct distribution *distribution,/*@null@*/c
/*@dependent@*/struct target *distribution_getpart(const struct distribution *distribution,const char *component,const char *architecture,const char *packagetype);
retvalue distribution_fullexport(struct distribution *distribution,const char *confdir,const char *dbdir,const char *distdir);
retvalue distribution_fullexport(struct distribution *distribution,const char *confdir,const char *dbdir,const char *distdir,filesdb);
enum exportwhen {EXPORT_NEVER, EXPORT_CHANGED, EXPORT_NORMAL, EXPORT_FORCE };
retvalue distribution_export(enum exportwhen when, struct distribution *distribution,const char *confdir,const char *dbdir,const char *distdir);
retvalue distribution_export(enum exportwhen when, struct distribution *distribution,const char *confdir,const char *dbdir,const char *distdir,filesdb);
/* get all dists from <conf> fitting in the filter given in <argc,argv> */
retvalue distribution_getmatched(const char *conf,int argc,const char *argv[],/*@out@*/struct distribution **distributions);
retvalue distribution_freelist(/*@only@*/struct distribution *distributions);
retvalue distribution_exportandfreelist(enum exportwhen when, /*@only@*/struct distribution *distributions,const char *confdir, const char *dbdir, const char *distdir);
retvalue distribution_exportandfreelist(enum exportwhen when, /*@only@*/struct distribution *distributions,const char *confdir, const char *dbdir, const char *distdir, filesdb);
#endif
.TH REPREPRO 1 "03 May, 2006" "reprepro" REPREPRO
.TH REPREPRO 1 "12 May, 2006" "reprepro" REPREPRO
.SH NAME
reprepro \- produce, manage and sync a local repository of debian packages
.SH SYNOPSIS
......@@ -554,6 +554,45 @@ UDebIndices Packages . .gz
.br
DscIndices Sources Release .gz
.TP
.B Contents
Enable the creation of Contents files listing all the files
within the binary packages of a distribution.
(Which is quite slow, you have been warned).
The first argument is the rate at which to extract the files
from packages.
If it is 1, every file will be processed.
If it is 2, at least half of the uncached files and at most half
of all files are read to extract their filelist.
If it is 3, at least a third of yet uncached files and at most a
third of all files is read.
And so on...
After that a space seperated list of options can be given.
If there is a \fBudebs\fP keyword, \fB.udeb\fPs are also listed
(in a file called \fBuContents-\fP\fIarchitecture\fP.)
If there is a \fBnodebs\fP keyword, \fB.deb\fPs are not listed.
(Only usefull together with \fBudebs\fP)
If there is at least one of the keywords \fB.\fP, \fB.gz\fP and/or \fB.bz2\fP,
the Contents files are written uncompressed, gzipped and/or bzip2ed instead
of only gzipped.
.TP
.B ContentsArchitectures
Limit generation of Contents files to the architectures given.
If this field is not there or empty, all architectures are processed.
.TP
.B ContentsComponents
Limit what components are processed for the Contents files to
the components given.
If this field is not there or empty, all components are processed.
.TP
.B ContentsUComponents
Limit what components are processed for the uContents files to
the components given.
If this field is not there or empty, all components are processed.
(Note unless you specify \fBudebs\fP in the \fBContents:\fP line,
no udeb Components are processed at all.)
.TP
.B Tracking
Enable the (experimental) tracking of source packages.
The argument is a list of the following:
......
#include <config.h>
#include <malloc.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include "error.h"
#include "filelist.h"
#ifndef HAVE_LIBARCHIVE
#error Why is this included?
#endif
struct filelist_package {
struct filelist_package *next;
char name[];
};
struct dirlist;
struct filelist {
struct filelist *next;
char *name;
struct dirlist *dir;
size_t count;
const char *packages[];
};
struct dirlist {
struct dirlist *next;
char *name;
struct dirlist *subdirs;
/*@dependant@*/struct dirlist *lastsubdir;
struct filelist *files;
/*@dependant@*/struct filelist *lastfile;
};
struct filelist_list {
struct dirlist *root;
struct filelist_package *packages;
};
retvalue filelist_init(struct filelist_list **list) {
struct filelist_list *filelist;
filelist = calloc(1,sizeof(struct filelist_list));
if( filelist == NULL )
return RET_ERROR_OOM;
filelist->root = calloc(1,sizeof(struct dirlist));
if( filelist->root == NULL ) {
free(filelist);
return RET_ERROR_OOM;
}
*list = filelist;
return RET_OK;
};
static void dirlist_free(/*@only@*/struct dirlist *list) {
while( list != NULL ) {
struct dirlist *h = list->next;
struct filelist *f = list->files;
while( f != NULL ) {
struct filelist *fh = f;
f = f->next;
free(fh->name);
free(fh);
}
free(list->name);
dirlist_free(list->subdirs);
free(list);
list = h;
}
}
void filelist_free(struct filelist_list *list) {
if( list == NULL )
return;
dirlist_free(list->root);
while( list->packages != NULL ) {
struct filelist_package *package = list->packages;
list->packages = package->next;
free(package);
}
free(list);
};
retvalue filelist_newpackage(struct filelist_list *filelist, const char *name, const char *section, const struct filelist_package **pkg) {
struct filelist_package *p;
size_t name_len = strlen(name);
size_t section_len = strlen(section);
p = malloc(sizeof(struct filelist_package)+name_len+section_len+2);
if( p == NULL )
return RET_ERROR_OOM;
p->next = filelist->packages;
memcpy(p->name, section, section_len);
p->name[section_len] = '/';
memcpy(p->name+section_len+1, name, name_len+1);
filelist->packages = p;
*pkg = p;
return RET_OK;
};
static int
findfile(const char *basefilename, struct dirlist *parent,
const struct filelist_package *package) {
struct filelist *file,*n,**p;
if( parent->lastfile != NULL &&
strcmp(basefilename,parent->lastfile->name) > 0 )
p = &parent->lastfile->next;
else
p = &parent->files;
file = *p;
while( file != NULL ) {
int c = strcmp(basefilename, file->name);
if( c == 0 ) {
n = realloc(file,sizeof(struct filelist)+
(file->count+1)*sizeof(const char*));
if( n == NULL ) {
return -1;
}
n->packages[n->count++] = package->name;
parent->lastfile = n;
*p = n;
return 1;
} else if ( c > 0 ) {
p = &file->next;
file = *p;
} else
break;
}
n = malloc(sizeof(struct filelist)+sizeof(const char*));
if( n == NULL ) {
return -1;
}
n->name = strdup(basefilename);
n->next = file;
n->dir = parent;
n->count = 1;
n->packages[0] = package->name;
if( n->name == NULL ) {
free(n);
return -1;
}
*p = n;
parent->lastfile = n;
return 1;
}
static int search(const char *p, struct dirlist *dir, const struct filelist_package *package) {
const char *q;
struct dirlist **dir_p,*d;
size_t len;
q = p;
while( *q != '\0' && *q != '/' )
q++;
if( *q == '\0' ) {
return findfile(p,dir,package);
}
if( dir->lastsubdir != NULL ) {
len = *(unsigned char*)dir->lastsubdir->name;
if( len == (size_t)(q-p) &&
strncmp(p,dir->lastsubdir->name+1,len)==0 ) {
assert( p[len] == '/' );
return search(q+1, dir->lastsubdir, package);
}
}
dir_p = &dir->subdirs;
while( (d=*dir_p) != NULL ) {
int c;
len = *(unsigned char*)d->name;
c = strncmp(p,d->name+1,len);
if( c == 0 && p[len] == '/' ) {
assert( (size_t)(q-p) == len );
dir->lastsubdir = d;
return search(q+1,d,package);
} else if( c >= 0 ) {
dir_p = &(d->next);
} else
break;
}
d = malloc(sizeof(struct dirlist));
if( d == NULL ) {
return -1;
}
d->next = *dir_p;
d->name = malloc((q-p)+1);
if( d->name == NULL ) {
free(d);
return -1;
}
*dir_p = d;
len = q-p;
*d->name = len;
memcpy(d->name+1,p,len);
d->subdirs = NULL;
d->files = NULL;
d->lastsubdir = NULL;
d->lastfile = NULL;
dir->lastsubdir = d;
return search(q+1,d,package);
}
retvalue filelist_add(struct filelist_list *list,const struct filelist_package *package,const char *filekey) {
int r;
r = search(filekey, list->root, package);
assert( r != 0 );
return (r < 0)?RET_ERROR_OOM:RET_OK;
}
static const char header[] = "FILE LOCATION\n";
static const char seperator[] = "\t ";
static void filelist_writefiles(char *dir, size_t len,
struct filelist *files, struct filetorelease *file) {
unsigned int i;
bool_t first;
while( files != NULL ) {
(void)release_writedata(file,dir,len);
(void)release_writestring(file,files->name);
(void)release_writedata(file,seperator,sizeof(seperator)-1);
first = TRUE;
for( i = 0 ; i < files->count ; i ++ ) {
if( !first )
(void)release_writestring(file,",");
first = FALSE;
(void)release_writestring(file,files->packages[i]);
}
(void)release_writestring(file,"\n");
files = files->next;
}
}
static retvalue filelist_writedirs(char **buffer_p, size_t *size_p, char *start,
struct dirlist *dirs, struct filetorelease *file) {
struct dirlist *dir;
size_t len;
retvalue r;
for( dir = dirs ; dir != NULL ; dir = dir->next ) {
len = *dir->name;
if( start+len+2 >= *buffer_p+*size_p ) {
*size_p += 1024;
char *n = realloc( *buffer_p, *size_p );
if( n == NULL ) {
free(*buffer_p);
}
*buffer_p = n;
}
memcpy(start,dir->name+1,len);
start[len] = '/';
// TODO: output files and directories sorted together instead
filelist_writefiles(*buffer_p,1+len+start-*buffer_p,dir->files,file);
r = filelist_writedirs(buffer_p,size_p,start+len+1,dir->subdirs,file);
if( RET_WAS_ERROR(r) )
return r;
}
return RET_OK;
}
retvalue filelist_write(struct filelist_list *list, struct filetorelease *file) {
size_t size = 1024;
char *buffer = malloc(size);
retvalue r;
if( buffer == NULL )
return RET_ERROR_OOM;
(void)release_writedata(file,header,sizeof(header)-1);
buffer[0] = '\0';
filelist_writefiles(buffer,0,list->root->files,file);
r = filelist_writedirs(&buffer,&size,buffer,list->root->subdirs,file);
free(buffer);
return r;
}
#ifndef REPREPRO_FILELIST_H
#define REPREPRO_FILELIST_H
#ifndef REPREPRO_RELEASE_H
#include "release.h"
#endif
#ifdef HAVE_LIBARCHIVE
struct filelist_package;
struct filelist_list;
retvalue filelist_init(struct filelist_list **list);
retvalue filelist_newpackage(struct filelist_list *filelist, const char *name, const char *section, const struct filelist_package **pkg);
retvalue filelist_add(struct filelist_list *,const struct filelist_package *,const char *);
retvalue filelist_write(struct filelist_list *list, struct filetorelease *file);
void filelist_free(/*@only@*/struct filelist_list *);
#endif
#endif
......@@ -35,9 +35,12 @@
#include "files.h"
#include "copyfile.h"
#include "ignore.h"
#include "filelist.h"
#include "debfile.h"
struct s_filesdb {
DB *database;
DB *contents;
char *mirrordir;
};
......@@ -91,22 +94,52 @@ retvalue files_initialize(filesdb *fdb,const char *dbpath,const char *mirrordir)
return RET_DBERR(dbret);
}
free(filename);
filename = calc_dirconcat(dbpath,"contents.cache.db");
if( filename == NULL ) {
(void)db->database->close(db->database,0);
free(db->mirrordir);
free(db);
return RET_ERROR_OOM;
}
if ((dbret = db_create(&db->contents, NULL, 0)) != 0) {
fprintf(stderr, "db_create: %s\n", db_strerror(dbret));
(void)db->database->close(db->database,0);
free(filename);
free(db->mirrordir);
free(db);
return RET_DBERR(dbret);
}
dbret = db->contents->open(db->contents, filename, "filelists", DB_BTREE,
DB_CREATE, 0664);
if( dbret != 0 ) {
db->contents->err(db