Commit 7f4dfb46 authored by Bernhard Link's avatar Bernhard Link

implement removesrc

parent 63319895
2007-09-16 Bernhard R. Link <brlink@debian.org>
* add removesrc action
2007-09-15 Bernhard R. Link <brlink@debian.org>
* move package database handling from packages.c to database.c
......
......@@ -24,6 +24,7 @@ Updates between 2.2.4 and 3.0.0:
* tidytracks now removes all tracking data from a distribution without tracking
* clearvanished removes tracking data from vanished distributions.
- make update's ListHook relative to confdir (unless absolute)
- added removesrc
Updates between 2.2.3 and 2.2.4:
- [SECURITY] fix bug causing a Release.gpg with only
......
......@@ -1015,6 +1015,29 @@ retvalue cursor_replace(struct table *table, struct cursor *cursor, const char *
return RET_OK;
}
retvalue cursor_delete(struct table *table, struct cursor *cursor, const char *key) {
int dbret;
assert( cursor != NULL );
assert( !table->readonly );
dbret = cursor->cursor->c_del(cursor->cursor, 0);
if( dbret != 0 ) {
table_printerror(table, dbret, "c_del");
return RET_DBERR(dbret);
}
if( table->verbose ) {
if( table->subname != NULL )
printf("db: '%s' removed from %s(%s).\n",
key, table->name, table->subname);
else
printf("db: '%s' removed from %s.\n",
key, table->name);
}
return RET_OK;
}
bool table_isempty(struct table *table) {
DBC *cursor;
DBT Key, Data;
......
......@@ -44,6 +44,7 @@ retvalue table_newduplicatecursor(struct table *, const char *key, /*@out@*/stru
bool cursor_nexttemp(struct table *, struct cursor *, /*@out@*/const char **, /*@out@*/const char **);
bool cursor_nexttempdata(struct table *, struct cursor *, /*@out@*/const char **, /*@out@*/size_t *);
retvalue cursor_replace(struct table *, struct cursor *, const char *);
retvalue cursor_delete(struct table *, struct cursor *, const char *);
retvalue cursor_close(struct table *, /*@only@*/struct cursor *);
#endif
......@@ -6,8 +6,9 @@ reprepro (3.0.0-0) UNRELEASED; urgency=low
- always read and check distributions config first (Closes: 439154)
- fix grammar error in manpage (Closes: 441300)
- warn about unused tracking data (Closes: 426596)
- add removesrc (Closes: 440101)
-- Bernhard R. Link <brlink@debian.org> Thu, 13 Sep 2007 17:45:12 +0200
-- Bernhard R. Link <brlink@debian.org> Sun, 16 Sep 2007 14:53:31 +0200
reprepro (2.2.4-1) unstable; urgency=high
......
......@@ -983,3 +983,54 @@ retvalue distribution_prepareforwriting(struct distribution *distribution) {
distribution->lookedat = true;
return RET_OK;
}
/* delete every package decider returns RET_OK for */
retvalue distribution_remove_packages(struct distribution *distribution, struct database *database, const char *component, const char *architecture, const char *packagetype, each_package_action decider, struct strlist *dereferenced, struct trackingdata *trackingdata, void *data) {
retvalue result,r;
struct target *t;
struct cursor *cursor;
const char *package, *control;
result = RET_NOTHING;
for( t = distribution->targets ; t != NULL ; t = t->next ) {
if( component != NULL && strcmp(component,t->component) != 0 )
continue;
if( architecture != NULL && strcmp(architecture,t->architecture) != 0 )
continue;
if( packagetype != NULL && strcmp(packagetype,t->packagetype) != 0 )
continue;
r = target_initpackagesdb(t, database); //TODO: readwrite
RET_UPDATE(result, r);
if( RET_WAS_ERROR(r) )
return result;
r = table_newglobaluniqcursor(t->packages, &cursor);
assert( r != RET_NOTHING );
if( RET_WAS_ERROR(r) ) {
(void)target_closepackagesdb(t);
return r;
}
while( cursor_nexttemp(t->packages, cursor,
&package, &control) ) {
r = decider(database, distribution, t,
package, control, data);
RET_UPDATE(result, r);
if( RET_WAS_ERROR(r) )
break;
if( RET_IS_OK(r) ) {
r = target_removepackage_by_cursor(t,
distribution->logger, database, cursor,
package, control, NULL, dereferenced,
trackingdata);
RET_UPDATE(result, r);
RET_UPDATE(distribution->status, r);
}
}
r = cursor_close(t->packages, cursor);
RET_ENDUPDATE(result, r);
r = target_closepackagesdb(t);
RET_ENDUPDATE(result, r);
if( RET_WAS_ERROR(result) )
return result;
}
return result;
}
......@@ -111,6 +111,9 @@ retvalue distribution_foreach_roopenedpart(struct distribution *,struct database
* setting distribution->status to some error if there are any*/
retvalue distribution_foreach_rwopenedpart(struct distribution *,struct database *,const char *component,const char *architecture,const char *packagetype,distribution_each_action action,void *data);
/* delete every package decider returns RET_OK for */
retvalue distribution_remove_packages(struct distribution *, struct database *, const char *component, const char *architecture, const char *packagetype, each_package_action decider, struct strlist *dereferenced, struct trackingdata *, void *);
/*@dependent@*/struct target *distribution_getpart(const struct distribution *distribution,const char *component,const char *architecture,const char *packagetype);
/* like distribtion_getpart, but returns NULL if there is no such target */
......
......@@ -291,6 +291,14 @@ number with its Source, as binary and source version differ).
.B remove \fIcodename\fP \fIpackage name\fP
same as list, but remove instead of list.
.TP
.B removesrc \fIcodename\fP \fIsource-name\fP \fR[\fP\fIversion\fP\fR]\fP
Remove all packages in distribution \fIcodename\fP belonging to source
package \fIsource-name\fP.
(Limited to those with source version \fIversion\fP if specified).
If package tracking is activated, it will use that information to find the
packages, otherwise it traverses all package indicies for the distribution.
.TP
.BR update " [ " \fIcodenames\fP " ]"
Sync the specified distributions (all if none given) as
specified in the config with their upstreams. See the
......
......@@ -493,10 +493,45 @@ ACTION_D(remove) {
return result;
}
struct removesrcdata {
const char *sourcename;
const char /*@null@*/*sourceversion;
};
static retvalue package_source_fits(UNUSED(struct database *da), UNUSED(struct distribution *di), struct target *target, const char *packagename, const char *control, void *data) {
struct removesrcdata *d = data;
char *sourcename, *sourceversion;
retvalue r;
r = target->getsourceandversion(target, control, packagename,
&sourcename, &sourceversion);
if( !RET_IS_OK(r) )
return r;
if( strcmp(sourcename, d->sourcename) != 0 ) {
free(sourcename);
free(sourceversion);
return RET_NOTHING;
}
if( d->sourceversion == NULL ) {
free(sourcename);
free(sourceversion);
return RET_OK;
}
if( strcmp(sourceversion, d->sourceversion) != 0 ) {
free(sourcename);
free(sourceversion);
return RET_NOTHING;
}
free(sourcename);
free(sourceversion);
return RET_OK;
}
ACTION_D(removesrc) {
retvalue result, r;
struct distribution *distribution;
trackingdb tracks;
struct removesrcdata data;
r = distribution_get(alldistributions, argv[1], true, &distribution);
assert( r != RET_NOTHING );
......@@ -552,8 +587,21 @@ ACTION_D(removesrc) {
RET_ENDUPDATE(result,r);
return result;
}
fprintf(stderr, "Continue implementing...\n");
return RET_ERROR;
data.sourcename = argv[2];
if( argc <= 3 )
data.sourceversion = NULL;
else
data.sourceversion = argv[3];
result = distribution_remove_packages(distribution, database,
NULL, NULL, NULL,
package_source_fits, dereferenced, NULL,
&data);
if( RET_IS_OK(result) ) {
r = distribution_export(export, distribution,
confdir, distdir, database);
RET_ENDUPDATE(result, r);
}
return result;
}
......
......@@ -30,6 +30,7 @@
#include "strlist.h"
#include "names.h"
#include "chunks.h"
#include "database.h"
#include "reference.h"
#include "binaries.h"
#include "sources.h"
......@@ -156,12 +157,67 @@ retvalue target_closepackagesdb(struct target *target) {
/* Remove a package from the given target. If dereferencedfilekeys != NULL, add there the
* filekeys that lost references */
retvalue target_removepackage(struct target *target,struct logger *logger,struct database *database,const char *name,const char *oldpversion,struct strlist *dereferencedfilekeys,struct trackingdata *trackingdata) {
char *oldchunk,*oldpversion_ifunknown = NULL;
retvalue target_removereadpackage(struct target *target, struct logger *logger, struct database *database, const char *name, const char *oldcontrol, const char *oldpversion, struct strlist *dereferencedfilekeys, struct trackingdata *trackingdata) {
char *oldpversion_ifunknown = NULL;
struct strlist files;
retvalue result,r;
char *oldsource,*oldsversion;
assert( target != NULL && target->packages != NULL );
assert( oldcontrol != NULL && name != NULL );
if( logger != NULL && oldpversion == NULL ) {
/* need to get the version for logging, if not available */
r = target->getversion(target, oldcontrol,
&oldpversion_ifunknown);
if( RET_IS_OK(r) )
oldpversion = oldpversion_ifunknown;
}
r = target->getfilekeys(target, oldcontrol, &files, NULL);
if( RET_WAS_ERROR(r) ) {
free(oldpversion_ifunknown);
return r;
}
if( trackingdata != NULL ) {
r = target->getsourceandversion(target, oldcontrol,
name, &oldsource, &oldsversion);
if( !RET_IS_OK(r) ) {
oldsource = oldsversion = NULL;
}
} else {
oldsource = oldsversion = NULL;
}
if( verbose > 0 )
printf("removing '%s' from '%s'...\n",
name, target->identifier);
result = table_deleterecord(target->packages, name);
if( RET_IS_OK(result) ) {
target->wasmodified = true;
if( oldsource!= NULL && oldsversion != NULL ) {
r = trackingdata_remove(trackingdata,
oldsource, oldsversion, &files);
RET_UPDATE(result,r);
}
if( logger != NULL )
logger_log(logger, target, name,
NULL, oldpversion,
NULL, oldcontrol,
NULL, &files);
r = references_delete(database, target->identifier, &files,
NULL, dereferencedfilekeys);
RET_UPDATE(result, r);
} else
strlist_done(&files);
free(oldpversion_ifunknown);
return result;
}
/* Remove a package from the given target. If dereferencedfilekeys != NULL, add there the
* filekeys that lost references */
retvalue target_removepackage(struct target *target,struct logger *logger,struct database *database,const char *name,const char *oldpversion,struct strlist *dereferencedfilekeys,struct trackingdata *trackingdata) {
char *oldchunk;
retvalue r;
assert(target != NULL && target->packages != NULL && name != NULL );
r = table_getrecord(target->packages, name, &oldchunk);
......@@ -171,23 +227,41 @@ retvalue target_removepackage(struct target *target,struct logger *logger,struct
else if( r == RET_NOTHING ) {
if( verbose >= 10 )
fprintf(stderr,"Could not find '%s' in '%s'...\n",
name,target->identifier);
name, target->identifier);
return RET_NOTHING;
}
r = target_removereadpackage(target, logger, database,
name, oldchunk, oldpversion, dereferencedfilekeys,
trackingdata);
free(oldchunk);
return r;
}
/* Like target_removepackage, but delete the package record by cursor */
retvalue target_removepackage_by_cursor(struct target *target, struct logger *logger, struct database *database, struct cursor *cursor, const char *name, const char *control, const char *oldpversion, struct strlist *dereferencedfilekeys, struct trackingdata *trackingdata) {
char *oldpversion_ifunknown = NULL;
struct strlist files;
retvalue result, r;
char *oldsource, *oldsversion;
assert(target != NULL && target->packages != NULL );
assert( name != NULL && control != NULL);
if( logger != NULL && oldpversion == NULL ) {
/* need to get the version for logging, if not available */
r = target->getversion(target,oldchunk,&oldpversion_ifunknown);
r = target->getversion(target, control,
&oldpversion_ifunknown);
if( RET_IS_OK(r) )
oldpversion = oldpversion_ifunknown;
}
r = target->getfilekeys(target,oldchunk,&files,NULL);
r = target->getfilekeys(target, control, &files, NULL);
if( RET_WAS_ERROR(r) ) {
free(oldpversion_ifunknown);
free(oldchunk);
return r;
}
if( trackingdata != NULL ) {
r = (*target->getsourceandversion)(target, oldchunk,
r = target->getsourceandversion(target, control,
name, &oldsource, &oldsversion);
if( !RET_IS_OK(r) ) {
oldsource = oldsversion = NULL;
......@@ -196,11 +270,12 @@ retvalue target_removepackage(struct target *target,struct logger *logger,struct
oldsource = oldsversion = NULL;
}
if( verbose > 0 )
printf("removing '%s' from '%s'...\n",name,target->identifier);
result = table_deleterecord(target->packages, name);
printf("removing '%s' from '%s'...\n",
name, target->identifier);
result = cursor_delete(target->packages, cursor, name);
if( RET_IS_OK(result) ) {
target->wasmodified = true;
if( oldsource!= NULL && oldsversion != NULL ) {
if( oldsource != NULL && oldsversion != NULL ) {
r = trackingdata_remove(trackingdata,
oldsource, oldsversion, &files);
RET_UPDATE(result,r);
......@@ -208,7 +283,7 @@ retvalue target_removepackage(struct target *target,struct logger *logger,struct
if( logger != NULL )
logger_log(logger, target, name,
NULL, oldpversion,
NULL, oldchunk,
NULL, control,
NULL, &files);
r = references_delete(database, target->identifier, &files,
NULL, dereferencedfilekeys);
......@@ -216,7 +291,6 @@ retvalue target_removepackage(struct target *target,struct logger *logger,struct
} else
strlist_done(&files);
free(oldpversion_ifunknown);
free(oldchunk);
return result;
}
......
......@@ -76,7 +76,12 @@ retvalue target_closepackagesdb(struct target *target);
struct logger;
retvalue target_addpackage(struct target *, /*@null@*/struct logger *, struct database *, const char *name, const char *version, const char *control, const struct strlist *filekeys, bool downgrade, /*@null@*/struct strlist *dereferencedfilekeys, /*@null@*/struct trackingdata *, enum filetype);
retvalue target_checkaddpackage(struct target *target, const char *name, const char *version, bool tracking, bool permitnewerold);
retvalue target_removepackage(struct target *,struct logger *,struct database *,const char *name,/*@null@*/const char *oldpversion,/*@null@*/struct strlist *dereferencedfilekeys,struct trackingdata *);
retvalue target_removepackage(struct target *, /*@null@*/struct logger *, struct database *, const char *name, /*@null@*/const char *oldpversion, /*@null@*/struct strlist *dereferencedfilekeys, struct trackingdata *);
/* like target_removepackage, but do not read control data yourself but use available */
retvalue target_removereadpackage(struct target *, /*@null@*/struct logger *, struct database *, const char *name, const char *oldcontrol, /*@null@*/const char *oldpversion, struct strlist *, /*@null@*/struct trackingdata *);
/* Like target_removepackage, but delete the package record by cursor */
retvalue target_removepackage_by_cursor(struct target *, /*@null@*/struct logger *, struct database *, struct cursor *, const char *name, const char *control, /*@null@*/const char *oldpversion, struct strlist *, /*@null@*/struct trackingdata *);
retvalue package_check(struct database *, struct distribution *, struct target *, const char *, const char *, void *);
retvalue target_rereference(struct target *, struct database *);
retvalue package_referenceforsnapshot(struct database *, struct distribution *, struct target *, const char *, const char *, void *);
......
......@@ -4247,6 +4247,67 @@ a|all|abacus pool/all/a/ab/ab_3-1_abacus.deb
b|all|abacus pool/all/a/ab/ab_3-1_abacus.deb
EOF
dodiff results.expected results
fi
rm -r -f db2
cp -a db db2
echo tracking is $tracking
testrun - --keepunreferenced --dbdir db2 -b . removesrc a ab 3-1 3<<EOF
stdout
-v1*=removing 'ab-addons' from 'a|all|abacus'...
-d1*=db: 'ab-addons' removed from packages.db(a|all|abacus).
-v1*=removing 'ab' from 'a|all|abacus'...
-d1*=db: 'ab' removed from packages.db(a|all|abacus).
-v1*=removing 'ab' from 'a|all|source'...
-d1*=db: 'ab' removed from packages.db(a|all|source).
-v0*=Exporting indices...
-v6*= looking for changes in 'a|all|abacus'...
-v6*= replacing './dists/a/all/binary-abacus/Packages' (uncompressed,gzipped)
-v6*= looking for changes in 'a|all|source'...
-v6*= replacing './dists/a/all/source/Sources' (gzipped)
EOF
if $tracking ; then
checklog logab <<EOF
DATESTR remove a deb all abacus ab-addons 3-1
DATESTR remove a deb all abacus ab 3-1
DATESTR remove a dsc all source ab 3-1
EOF
else
checklog logab <<EOF
DATESTR remove a deb all abacus ab 3-1
DATESTR remove a deb all abacus ab-addons 3-1
DATESTR remove a dsc all source ab 3-1
EOF
fi
rm -r db2
cp -a db db2
testrun - --keepunreferenced --dbdir db2 -b . removesrc a ab 3<<EOF
stdout
-v1*=removing 'ab-addons' from 'a|all|abacus'...
-d1*=db: 'ab-addons' removed from packages.db(a|all|abacus).
-v1*=removing 'ab' from 'a|all|abacus'...
-d1*=db: 'ab' removed from packages.db(a|all|abacus).
-v1*=removing 'ab' from 'a|all|source'...
-d1*=db: 'ab' removed from packages.db(a|all|source).
-v0*=Exporting indices...
-v6*= looking for changes in 'a|all|abacus'...
-v6*= replacing './dists/a/all/binary-abacus/Packages' (uncompressed,gzipped)
-v6*= looking for changes in 'a|all|source'...
-v6*= replacing './dists/a/all/source/Sources' (gzipped)
EOF
if $tracking ; then
checklog logab <<EOF
DATESTR remove a deb all abacus ab-addons 3-1
DATESTR remove a deb all abacus ab 3-1
DATESTR remove a dsc all source ab 3-1
EOF
else
checklog logab <<EOF
DATESTR remove a deb all abacus ab 3-1
DATESTR remove a deb all abacus ab-addons 3-1
DATESTR remove a dsc all source ab 3-1
EOF
fi
if $tracking ; then
testrun - -b . --delete removealltracks a 3<<EOF
stdout
-v0*=Deleting all tracks for a...
......@@ -4275,6 +4336,7 @@ Codename: X
Architectures: none
Components: test
EOF
checknolog logab
if $tracking ; then
testrun - -b . --delete clearvanished 3<<EOF
-v4*=Strange, 'X|test|none' does not appear in packages.db yet.
......@@ -4320,6 +4382,7 @@ stdout
-v1*=removed now empty directory ./pool
EOF
fi
checknolog logab
done
set +v +x
echo
......
......@@ -404,6 +404,7 @@ static retvalue tracking_get(trackingdb t,const char *sourcename,const char *ver
// printf("[tracking_get found %s %s %s]\n",t->codename,sourcename,version);
/* we have found it, now parse it */
r = parsedata(sourcename,version,versionlen,data,pkg);
assert( r != RET_NOTHING );
(void)cursor->c_close(cursor);
return r;
}
......@@ -975,8 +976,10 @@ static inline retvalue trackedpackage_removeall(trackingdb tracks, struct tracke
for( i = 0 ; i < pkg->filekeys.count ; i++ ) {
r = references_decrement(database, pkg->filekeys.values[i] ,id);
RET_UPDATE(result,r);
strlist_add(dereferenced, pkg->filekeys.values[i]);
pkg->filekeys.values[i] = NULL;
if( dereferenced != NULL ) {
strlist_add(dereferenced, pkg->filekeys.values[i]);
pkg->filekeys.values[i] = NULL;
}
}
free(id);
strlist_done(&pkg->filekeys);
......@@ -1402,16 +1405,18 @@ static retvalue targetremovesourcepackage(trackingdb t, struct trackedpackage *p
free(version);
r = target->getfilekeys(target, control, &filekeys, NULL);
assert( r != RET_NOTHING );
free(control);
if( RET_WAS_ERROR(r) ) {
free(package);
free(control);
return r;
}
/* that is a bit wasteful, as it parses some stuff again, but
* but that is better than reimplementing logger here */
r = target_removepackage(target, distribution->logger, database,
package, NULL, dereferenced, NULL);
r = target_removereadpackage(target, distribution->logger,
database, package, control, NULL,
dereferenced, NULL);
free(control);
free(package);
assert( r != RET_NOTHING );
if( RET_WAS_ERROR(r) ) {
......
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