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);
#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);
}
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); }
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;
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;
}