Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
deferred_unlink: add (fix) the directory tree removal, fixes #2814
  • Loading branch information
perexg committed May 2, 2015
1 parent 8d8374b commit 9273680
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 33 deletions.
37 changes: 7 additions & 30 deletions src/dvr/dvr_db.c
Expand Up @@ -2208,9 +2208,10 @@ dvr_val2pri(dvr_prio_t v)
void
dvr_entry_delete(dvr_entry_t *de)
{
dvr_config_t *cfg = de->de_config;
time_t t;
struct tm tm;
char tbuf[64];
char tbuf[64], *rdir;
int r;

t = dvr_entry_get_start_time(de);
Expand All @@ -2229,38 +2230,14 @@ dvr_entry_delete(dvr_entry_t *de)
#if ENABLE_INOTIFY
dvr_inotify_del(de);
#endif
r = deferred_unlink(de->de_filename);
rdir = NULL;
if(cfg->dvr_title_dir || cfg->dvr_channel_dir || cfg->dvr_dir_per_day || de->de_directory)
rdir = cfg->dvr_storage;

r = deferred_unlink(de->de_filename, rdir);
if(r && r != -ENOENT)
tvhlog(LOG_WARNING, "dvr", "Unable to remove file '%s' from disk -- %s",
de->de_filename, strerror(-errno));

/* Also delete directories, if they were created for the recording and if they are empty */

dvr_config_t *cfg = de->de_config;
char path[500];

snprintf(path, sizeof(path), "%s", cfg->dvr_storage);

if(cfg->dvr_title_dir || cfg->dvr_channel_dir || cfg->dvr_dir_per_day || de->de_directory) {
char *p;
int l;

l = strlen(de->de_filename);
p = alloca(l + 1);
memcpy(p, de->de_filename, l);
p[l--] = 0;

for(; l >= 0; l--) {
if(p[l] == '/') {
p[l] = 0;
if(strncmp(p, cfg->dvr_storage, strlen(p)) == 0)
break;
if(rmdir(p) == -1)
break;
}
}
}

}
dvr_entry_destroy(de, 1);
}
Expand Down
2 changes: 1 addition & 1 deletion src/tvheadend.h
Expand Up @@ -759,7 +759,7 @@ char *url_encode(char *str);

int mpegts_word_count(const uint8_t *tsb, int len, uint32_t mask);

int deferred_unlink(const char *filename);
int deferred_unlink(const char *filename, const char *rootdir);

static inline int32_t deltaI32(int32_t a, int32_t b) { return (a > b) ? (a - b) : (b - a); }
static inline uint32_t deltaU32(uint32_t a, uint32_t b) { return (a > b) ? (a - b) : (b - a); }
Expand Down
49 changes: 47 additions & 2 deletions src/utils.c
Expand Up @@ -653,9 +653,45 @@ deferred_unlink_cb(void *s, int dearmed)
free(s);
}

typedef struct {
char *filename;
char *rootdir;
} deferred_unlink_t;

static void
deferred_unlink_dir_cb(void *s, int dearmed)
{
deferred_unlink_t *du = s;
char *p;
int l;

if (unlink((const char *)du->filename))
tvherror("main", "unable to remove file '%s'", (const char *)du->filename);

/* Remove all directories up to rootdir */

l = strlen(du->filename) - 1;
p = du->filename;

for(; l >= 0; l--) {
if(p[l] == '/') {
p[l] = 0;
if(strncmp(p, du->rootdir, l) == 0)
break;
if(rmdir(p) == -1)
break;
}
}

free(du->filename);
free(du->rootdir);
free(du);
}

int
deferred_unlink(const char *filename)
deferred_unlink(const char *filename, const char *rootdir)
{
deferred_unlink_t *du;
char *s;
size_t l;
int r;
Expand All @@ -672,6 +708,15 @@ deferred_unlink(const char *filename)
free(s);
return r;
}
tasklet_arm_alloc(deferred_unlink_cb, s);
if (rootdir == NULL)
tasklet_arm_alloc(deferred_unlink_cb, s);
else {
du = calloc(1, sizeof(*du));
if (du == NULL)
return -ENOMEM;
du->filename = s;
du->rootdir = strdup(rootdir);
tasklet_arm_alloc(deferred_unlink_dir_cb, du);
}
return 0;
}

0 comments on commit 9273680

Please sign in to comment.