Commit 61084ff4 authored by Bernhard Link's avatar Bernhard Link

add 'dumbremove' to changestool

parent 338b3adb
2010-20-10
2010-03-19
* add "dumbremove" to changestool.
2010-02-10
* fix failure if trying to extract exactly one of
section or priority from a tar file.
......
.TH CHANGESTOOL 1 "2009-07-15" "reprepro" REPREPRO
.TH CHANGESTOOL 1 "2010-03-19" "reprepro" REPREPRO
.SH NAME
changestool \- verify, dump, modify, create or fix Debian .changes files
.SH SYNOPSIS
......@@ -142,6 +142,15 @@ and in the directories specified by the \fB\-\-searchpath\fP.
Behave like \fBadddsc\fP for filenames ending in \fB.dsc\fP,
like \fBadddeb\fP for filenames ending in \fB.deb\fP or \fB.udeb\fP,
and like \fBaddrawfile\fP for all other filenames
.TP
.B dumbremove \fIfilenames\fP
Remove the specified files from the .changes file.
No other fields (Architectures, Binaries, ...) are updated and
no related files is removed.
Just the given files (which must be specified without any \fB/\fP)
are no longer listen in the .changes file (and only no longer in the
changes file).
.SH "SEE ALSO"
.BR reprepro (1),
.BR dpkg\-genchanges (1),
......
/* This file is part of "reprepro"
* Copyright (C) 2006,2007,2008,2009 Bernhard R. Link
* Copyright (C) 2006,2007,2008,2009,2010 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.
......@@ -59,6 +59,7 @@ static void about(bool help) {
" addrawfile <filenames>\n"
" add <filenames processed by filename suffix>\n"
" setdistribution <distributions to list>\n"
" dumbremove <filenames>\n"
);
if( help )
exit(EXIT_SUCCESS);
......@@ -187,7 +188,7 @@ struct changes {
bool modified;
};
static void fileentry_free(struct fileentry *f) {
static void fileentry_free(/*@only@*/struct fileentry *f) {
if( f == NULL )
return;
free(f->basename);
......@@ -342,24 +343,37 @@ static retvalue findfile(const char *filename, const struct changes *c, /*@null@
return RET_OK;
}
static retvalue add_file(struct changes *c, /*@only@*/char *basefilename, /*@only@*/char *fullfilename, enum filetype type, struct fileentry **file) {
size_t basenamelen;
static struct fileentry **find_file(struct changes *c, const char *basefilename, size_t basenamelen) {
struct fileentry **fp = &c->files;
struct fileentry *f;
basenamelen = strlen(basefilename);
while( (f=*fp) != NULL ) {
if( f->namelen == basenamelen &&
strncmp(basefilename, f->basename, basenamelen) == 0 ) {
*file = f;
return RET_NOTHING;
return fp;
}
fp = &f->next;
}
assert( f == NULL );
return fp;
}
static retvalue add_file(struct changes *c, /*@only@*/char *basefilename, /*@only@*/char *fullfilename, enum filetype type, struct fileentry **file) {
size_t basenamelen = strlen(basefilename);
struct fileentry **fp = find_file(c, basefilename, basenamelen);
struct fileentry *f = *fp;
if( f != NULL ) {
*file = f;
free(basefilename);
free(fullfilename);
return RET_NOTHING;
}
assert( f == NULL );
f = calloc(1,sizeof(struct fileentry));
if( f == NULL ) {
free(basefilename);
free(fullfilename);
return RET_ERROR_OOM;
}
f->basename = basefilename;
......@@ -2236,16 +2250,12 @@ static retvalue adddsc(struct changes *c, const char *dscfilename, const struct
if( RET_WAS_ERROR(r) ) {
dscfile_free(dsc);
free(origdirectory);
free(fullfilename);
free(basefilename);
return r;
}
if( r == RET_NOTHING ) {
fprintf(stderr, "ERROR: '%s' already contains a file of the same name!\n", c->filename);
dscfile_free(dsc);
free(origdirectory);
free(fullfilename);
free(basefilename);
// TODO: check instead if it is already the same...
return RET_ERROR;
}
......@@ -2497,15 +2507,11 @@ static retvalue adddeb(struct changes *c, const char *debfilename, const struct
r = add_file(c, basefilename, fullfilename, type, &f);
if( RET_WAS_ERROR(r) ) {
binaryfile_free(deb);
free(fullfilename);
free(basefilename);
return r;
}
if( r == RET_NOTHING ) {
fprintf(stderr, "ERROR: '%s' already contains a file of the same name!\n", c->filename);
binaryfile_free(deb);
free(fullfilename);
free(basefilename);
// TODO: check instead if it is already the same...
return RET_ERROR;
}
......@@ -2599,9 +2605,10 @@ static retvalue addrawfile(struct changes *c, const char *filename, const struct
return r;
}
r = add_file(c, basefilename, fullfilename, ft_UNKNOWN, &f);
// fullfilename and basefilename now belong to *f or are already free'd
basefilename = NULL;
fullfilename = NULL;
if( RET_WAS_ERROR(r) ) {
free(fullfilename);
free(basefilename);
checksums_free(checksums);
return r;
}
......@@ -2613,28 +2620,18 @@ static retvalue addrawfile(struct changes *c, const char *filename, const struct
/* already listed in .changes */
if( !checksums_check(f->checksumsfromchanges, checksums, NULL) ) {
fprintf(stderr, "ERROR: '%s' already contains a file with name '%s' but different checksums!\n", c->filename, basefilename);
free(fullfilename);
free(basefilename);
fprintf(stderr, "ERROR: '%s' already contains a file with name '%s' but different checksums!\n", c->filename, f->basename);
checksums_free(checksums);
return RET_ERROR;
}
printf("'%s' already lists '%s' with same checksums. Doing nothing.\n", c->filename, basefilename);
free(fullfilename);
free(basefilename);
printf("'%s' already lists '%s' with same checksums. Doing nothing.\n", c->filename, f->basename);
checksums_free(checksums);
return RET_NOTHING;
} else {
/* file already expected by some other part (e.g. a .dsc) */
// TODO: find out whom this files belong to and warn if different
free(fullfilename);
free(basefilename);
}
} else {
// fullfilename and basefilename now belong to *f
basefilename = NULL;
fullfilename = NULL;
}
c->modified = true;
......@@ -2694,6 +2691,35 @@ static retvalue addfiles(const char *changesfilename, struct changes *c, int arg
return RET_NOTHING;
}
static retvalue dumbremovefiles(const char *changesfilename, struct changes *c, int argc, char **argv) {
if( argc <= 0 ) {
fprintf(stderr, "Filenames of files to remove (without further parsing) expected!\n");
return RET_ERROR;
}
while( argc > 0 ) {
struct fileentry **fp = find_file(c, argv[0], strlen(argv[0]));
/*@null@*/ struct fileentry *f = *fp;
if( f == NULL ) {
fprintf(stderr, "Not removing '%s' as not listed in '%s'!\n",
argv[0], c->filename);
} else if( f->checksumsfromchanges != NULL ) {
/* removing its checksums makes it vanish from the
* .changes file generated, while still keeping pointers
* from other files intact */
checksums_free(f->checksumsfromchanges);
f->checksumsfromchanges = NULL;
c->modified = true;
}
argc--; argv++;
}
if( c->modified ) {
return write_changes_file(changesfilename, c,
CHANGES_WRITE_FILES, false);
} else
return RET_NOTHING;
}
static retvalue setdistribution(const char *changesfilename, struct changes *c, int argc, char **argv) {
retvalue r;
struct strlist distributions;
......@@ -2797,6 +2823,15 @@ static int execute_command(int argc, char **argv, const char *changesfilename, c
changesfilename);
r = RET_ERROR;
}
} else if( strcasecmp(command, "dumbremove") == 0 ) {
if( file_exists )
r = dumbremovefiles(changesfilename, changesdata,
argc-1, argv+1);
else {
fprintf(stderr, "No such file '%s'!\n",
changesfilename);
r = RET_ERROR;
}
} else {
fprintf(stderr, "Unknown command '%s'\n", command);
r = RET_ERROR;
......
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