Commit 9b2fde21 authored by Bernhard Link's avatar Bernhard Link

remove dbdir when created earlier and still empty

parent 5d9afe5e
2007-09-03 Bernhard R. Link <brlink@debian.org>
* remove the dbdirs and all its parents created at startup
that are still empty at shutdown. (Does not make much difference
yet, as most commands create an empty file database in there.)
2007-09-02 Bernhard R. Link <brlink@debian.org>
* fix uninitialized use of errno in listclean.
(might cause update to report error opening dir: file exists)
......
......@@ -71,8 +71,9 @@ retvalue database_lock(struct database *db, size_t waitforlock) {
retvalue r;
size_t tries = 0;
// TODO: create directory
r = dirs_make_recursive(db->directory);
assert( !db->locked );
db->dircreationdepth = 0;
r = dir_create_needed(db->directory, &db->dircreationdepth);
if( RET_WAS_ERROR(r) )
return r;
......@@ -120,6 +121,8 @@ retvalue database_lock(struct database *db, size_t waitforlock) {
static void releaselock(struct database *db) {
char *lockfile;
assert( db->locked );
lockfile = calc_dirconcat(db->directory, "lockfile");
if( lockfile == NULL )
return;
......@@ -129,6 +132,7 @@ static void releaselock(struct database *db) {
(void)unlink(lockfile);
}
free(lockfile);
dir_remove_new(db->directory, db->dircreationdepth);
db->locked = false;
}
......
......@@ -15,6 +15,7 @@ struct database {
struct filesdb *files;
struct references *references;
bool locked;
int dircreationdepth;
};
retvalue database_opentable(struct database *,const char *,const char *,DBTYPE,u_int32_t flags,u_int32_t preflags,int (*)(DB *,const DBT *,const DBT *),/*@out@*/DB **);
......
......@@ -20,6 +20,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include "error.h"
......@@ -79,6 +80,104 @@ retvalue dirs_make_recursive(const char *directory) {
return result;
}
/* create directory and return the number of created directoried */
retvalue dir_create_needed(const char *directory, int *createddepth) {
retvalue r;
int ret;
size_t len = strlen(directory);
int check, depth = 0;
char *this;
int e;
if( interrupted() ) {
return RET_ERROR_INTERUPTED;
}
while( len > 0 && directory[len-1] == '/' )
len--;
while( len > 0 ) {
this = strndup(directory, len);
if( this == NULL )
return RET_ERROR_OOM;
ret = mkdir(this, 0777);
e = errno;
if( ret == 0 ) {
if( verbose > 1)
printf("Created directory \"%s\"\n", this);
} else if( e == EEXIST ) {
free(this);
break;
/* normaly ENOENT should be the only problem, but check the others
* to be nice to annoying filesystems */
} else if( e != ENOENT && e != EACCES && e != EPERM ) {
fprintf(stderr,"Can not create directory \"%s\": %s(%d)m\n",
this, strerror(e), e);
free(this);
return RET_ERRNO(e);
}
free(this);
depth++;
while( len > 0 && directory[len-1] != '/' )
len--;
while( len > 0 && directory[len-1] == '/' )
len--;
}
check = depth;
while( directory[len] == '/' )
len++;
while( directory[len] != '\0' ) {
while( directory[len] != '\0' && directory[len] != '/' )
len++;
this = strndup(directory, len);
if( this == NULL )
return RET_ERROR_OOM;
r = dirs_check(this);
free(this);
if( RET_WAS_ERROR(r) )
return r;
// TODO: if we get RET_NOTHING here, reduce depth?
check--;
while( directory[len] == '/' )
len++;
}
assert(check == 0);
*createddepth = depth;
return RET_OK;
}
void dir_remove_new(const char *directory, int created) {
size_t len = strlen(directory);
char *this;
int ret;
while( len > 0 && directory[len-1] == '/' )
len--;
while( created > 0 && len > 0 ) {
this = strndup(directory, len);
if( this == NULL )
return;
ret = rmdir(this);
if( ret == 0 ) {
if( verbose > 1)
printf("Removed empty directory \"%s\"\n", this);
} else {
int e = errno;
if( e != ENOTEMPTY ) {
fprintf(stderr, "Error removing directory \"%s\": %s(%d)\n",
this, strerror(e), e);
}
free(this);
return;
}
free(this);
created--;
while( len > 0 && directory[len-1] != '/' )
len--;
while( len > 0 && directory[len-1] == '/' )
len--;
}
return;
}
retvalue dirs_getdirectory(const char *filename,char **directory) {
size_t len;
......
......@@ -14,6 +14,9 @@
retvalue dirs_make_parent(const char *filename);
/* create dirname and any '/'-separated part of it */
retvalue dirs_make_recursive(const char *directory);
/* create directory and parents as needed, and save count to remove them later */
retvalue dir_create_needed(const char *directory, int *createddepth);
void dir_remove_new(const char *directory, int created);
/* Behave like dirname(3) */
retvalue dirs_getdirectory(const char *filename,/*@out@*/char **directory);
......
......@@ -119,6 +119,32 @@ case $TESTTOOLVERSION in
esac
touch results.empty
dodo test ! -d db
testrun - -b . __extractcontrol 3<<EOF
return 255
stdout
-v2*=Created directory "./db"
-v2*=Removed empty directory "./db"
stderr
*=reprepro __extractcontrol <.deb-file>
-v0*=There have been errors!
EOF
dodo test ! -d db
mkdir d
testrun - -b . --dbdir d/ab/c//x __extractcontrol 3<<EOF
return 255
stdout
-v2*=Created directory "d/ab"
-v2*=Created directory "d/ab/c"
-v2*=Created directory "d/ab/c//x"
-v2*=Removed empty directory "d/ab/c//x"
-v2*=Removed empty directory "d/ab/c"
-v2*=Removed empty directory "d/ab"
stderr
*=reprepro __extractcontrol <.deb-file>
-v0*=There have been errors!
EOF
dodo test ! -d d/ab
mkdir -p conf
cat > conf/options <<CONFEND
export changed
......
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