Commit 675549b0 authored by Bernhard Link's avatar Bernhard Link

remove now deletes the files of the removed packages that are no longer...

remove now deletes the files of the removed packages that are no longer referenced by any other package
parent f21f06dc
......@@ -6,6 +6,9 @@
* includedsc and includedeb only export
files that changed.
* remove now deletes files of removed packages
not referenced by any other package.
2005-01-10 Bernhard R. Link <brlink@debian.org>
* Made updates using --force with failing parts
more graceful
......
TODO:
auto-remove files no longer needed after package remove/upgrade
auto-remove files no longer needed after package upgrade
- and think of a concept when to exactly do this
check values from conf/distributions for sane values
add override-support while updating (or decide if this should be done)
implement extractcontrol.c properly
......
......@@ -162,6 +162,33 @@ retvalue files_remove(filesdb db,const char *filekey) {
}
}
/* delete the file and remove its md5sum from database */
retvalue files_deleteandremove(filesdb filesdb,const char *filekey) {
int err,en;
char *filename;
retvalue r;
if( verbose >= 0 )
printf("deleting and forgetting %s\n",filekey);
filename = calc_fullfilename(filesdb->mirrordir,filekey);
if( !filename )
return RET_ERROR_OOM;
err = unlink(filename);
free(filename);
if( err != 0 ) {
en = errno;
r = RET_ERRNO(en);
if( errno == ENOENT ) {
fprintf(stderr,"%s not found, forgetting anyway\n",filename);
} else {
fprintf(stderr,"error while unlinking %s: %m(%d)\n",filename,en);
return r;
}
}
r = files_remove(filesdb,filekey);
return r;
}
static retvalue files_calcmd5(char **md5sum,const char *filename) {
retvalue ret;
......
......@@ -20,6 +20,9 @@ retvalue files_add(filesdb filesdb,const char *filekey,const char *md5sum);
/* remove file's md5sum from database */
retvalue files_remove(filesdb filesdb,const char *filekey);
/* delete the file and remove its md5sum from database */
retvalue files_deleteandremove(filesdb filesdb,const char *filekey);
/* check for file in the database and if not found there in the pool */
retvalue files_expect(filesdb filesdb,const char *filekey,const char *md5sum);
/* same for multiple files */
......
......@@ -220,31 +220,10 @@ static retvalue action_dumpunreferenced(int argc,const char *argv[]) {
static retvalue deleteifunreferenced(void *data,const char *filekey,const char *md5sum) {
struct fileref *dist = data;
retvalue r;
char *filename;
int err,en;
r = references_isused(dist->refs,filekey);
if( r == RET_NOTHING ) {
if( verbose >= 0 )
printf("deleting and forgetting %s\n\n",filekey);
filename = calc_fullfilename(mirrordir,filekey);
if( !filename )
r = RET_ERROR_OOM;
else {
err = unlink(filename);
if( err != 0 ) {
en = errno;
r = RET_ERRNO(en);
if( errno == ENOENT ) {
fprintf(stderr,"%s not found, forgetting anyway\n",filename);
} else {
fprintf(stderr,"error while unlinking %s: %m(%d)\n",filename,en);
}
}
if( err == 0 || en == ENOENT || force > 0 )
r = files_remove(dist->files,filekey);
free(filename);
}
r = files_deleteandremove(dist->files,filekey);
return r;
} else if( RET_IS_OK(r) ) {
return RET_NOTHING;
......@@ -294,7 +273,7 @@ static retvalue action_addreference(int argc,const char *argv[]) {
}
struct remove_args {references refs; int count; const char **names; bool_t *gotremoved; int todo;};
struct remove_args {references refs; int count; const char **names; bool_t *gotremoved; int todo;struct strlist removedfiles;};
static retvalue remove_from_target(void *data, struct target *target) {
retvalue result,r;
......@@ -308,7 +287,7 @@ static retvalue remove_from_target(void *data, struct target *target) {
result = RET_NOTHING;
for( i = 0 ; i < d->count ; i++ ){
r = target_removepackage(target,d->refs,d->names[i]);
r = target_removepackage(target,d->refs,d->names[i],&d->removedfiles);
if( RET_IS_OK(r) ) {
if( ! d->gotremoved[i] )
d->todo--;
......@@ -343,6 +322,13 @@ static retvalue action_remove(int argc,const char *argv[]) {
return r;
}
r = strlist_init(&d.removedfiles);
if( RET_WAS_ERROR(r) ) {
(void)references_done(d.refs);
distribution_free(distribution);
return r;
}
d.count = argc-2;
d.names = argv+2;
d.todo = d.count;
......@@ -358,6 +344,30 @@ static retvalue action_remove(int argc,const char *argv[]) {
}
r = distribution_free(distribution);
RET_ENDUPDATE(result,r);
if( d.removedfiles.count > 0 ) {
filesdb files;
if( verbose >= 0 )
fprintf(stderr,"Deleting files no longer referenced...\n");
r = files_initialize(&files,dbdir,mirrordir);
RET_ENDUPDATE(result,r);
if( RET_IS_OK(r) ) {
int i;
for( i = 0 ; i < d.removedfiles.count ; i++ ) {
const char *filekey = d.removedfiles.values[i];
r = references_isused(d.refs,filekey);
if( r == RET_NOTHING ) {
r = files_deleteandremove(files,filekey);
}
RET_ENDUPDATE(result,r);
}
r = files_done(files);
RET_ENDUPDATE(result,r);
}
}
strlist_done(&d.removedfiles);
r = references_done(d.refs);
RET_ENDUPDATE(result,r);
if( verbose >= 0 && !RET_WAS_ERROR(result) && d.todo > 0 ) {
......
......@@ -197,3 +197,29 @@ void strlist_move(struct strlist *dest,struct strlist *orig) {
orig->size = orig->count = 0;
orig->values = NULL;
}
/* empty orig and add everything to the end of dest, in case of error, nothing
* was done. */
retvalue strlist_mvadd(struct strlist *dest,struct strlist *orig) {
int i;
assert(dest != NULL && orig != NULL && dest != orig);
if( dest->count+orig->count >= dest->size ) {
int newsize = dest->count+orig->count+8;
char **v = realloc(dest->values, newsize*sizeof(char *));
if( !v ) {
return RET_ERROR_OOM;
}
dest->size = newsize;
dest->values = v;
}
for( i = 0 ; i < orig->count ; i++ )
dest->values[dest->count+i] = orig->values[i];
dest->count += orig->count;
free(orig->values);
orig->size = orig->count = 0;
orig->values = NULL;
return RET_OK;
}
......@@ -28,6 +28,8 @@ retvalue strlist_fprint(FILE *file,const struct strlist *strlist);
retvalue strlist_dup(struct strlist *dest,const struct strlist *orig);
/* replace the contents of dest with those from orig, which get emptied */
void strlist_move(struct strlist *dest,struct strlist *orig);
/* empty orig and add everything to the end of dest, on error nothing is freed */
retvalue strlist_mvadd(struct strlist *dest,struct strlist *orig);
bool_t strlist_in(const struct strlist *strlist,const char *element);
bool_t strlist_subset(const struct strlist *strlist,const struct strlist *subset);
......
......@@ -148,7 +148,9 @@ retvalue target_closepackagesdb(struct target *target) {
return r;
}
retvalue target_removepackage(struct target *target,references refs,const char *name) {
/* Remove a package from the given target. If removedfilekeys != NULL, add there the
* filekeys that lost references */
retvalue target_removepackage(struct target *target,references refs,const char *name, struct strlist *removedfilekeys) {
char *oldchunk;
struct strlist files;
retvalue r;
......@@ -176,7 +178,13 @@ retvalue target_removepackage(struct target *target,references refs,const char *
target->wasmodified = TRUE;
r = references_delete(refs,target->identifier,&files,NULL);
}
strlist_done(&files);
if( removedfilekeys != NULL ) {
retvalue r2 = strlist_mvadd(removedfilekeys,&files);
if( RET_WAS_ERROR(r2) )
strlist_done(&files);
} else {
strlist_done(&files);
}
return r;
}
......
......@@ -63,7 +63,7 @@ retvalue target_closepackagesdb(struct target *target);
/* The following calls can only be called if target_initpackagesdb was called before: */
retvalue target_addpackage(struct target *target,references refs,const char *name,const char *version,const char *control,const struct strlist *filekeys,int force,bool_t downgrade);
retvalue target_removepackage(struct target *target,references refs,const char *name);
retvalue target_removepackage(struct target *target,references refs,const char *name, struct strlist *removedfilekeys);
retvalue target_writeindices(struct target *target,const char *distdir, int force,bool_t onlyneeded);
retvalue target_check(struct target *target,filesdb filesdb,references refsdb,int force);
retvalue target_rereference(struct target *target,references refs,int force);
......
......@@ -502,7 +502,7 @@ retvalue upgradelist_install(struct upgradelist *upgrade,const char *dbdir,files
break;
}
if( pkg->deleted && pkg->version_in_use != NULL && !ignoredelete ) {
r = target_removepackage(upgrade->target,refs,pkg->name);
r = target_removepackage(upgrade->target,refs,pkg->name,NULL);
RET_UPDATE(result,r);
if( RET_WAS_ERROR(r) && !force )
break;
......
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