]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
DVR: filename checker - more inteligent logic (keep extension), fixes #3136
authorJaroslav Kysela <perex@perex.cz>
Fri, 9 Oct 2015 09:57:28 +0000 (11:57 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 9 Oct 2015 09:57:28 +0000 (11:57 +0200)
src/dvr/dvr_rec.c
src/htsstr.c
src/htsstr.h

index 1db0d75dab1067a577b5f132f9a84669124680a0..77b5f95e67ce23cc385df7a26ba28adaba1a969b 100644 (file)
@@ -612,7 +612,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss)
   struct tm tm;
   dvr_config_t *cfg;
   htsmsg_t *m;
-  size_t l, j;
+  size_t l, j, k;
   long max;
   int dir_dosubs;
 
@@ -719,6 +719,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss)
   max = pathconf(filename, _PC_NAME_MAX);
   if (max < 8)
     max = NAME_MAX;
+  max -= 2;
   j = strlen(filename);
   snprintf(filename + j, sizeof(filename) - j, "/%s", dirsep);
   if (filename[j] == '/')
@@ -735,12 +736,24 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss)
     }
     /* Check the maximum filename length */
     l = strlen(number);
-    if (l + strlen(filename + j) > max) {
-      l = j + (max - l);
-      if (filename[l - 1] == '$') /* not optimal */
-        filename[l + 1] = '\0';
-      else
-        filename[l] = '\0';
+    k = strlen(filename + j);
+    if (l + k > max) {
+      s = (char *)htsstr_substitute_find(filename + j, '$');
+      if (s == NULL || s - (filename + j) < (l + k) - max) {
+cut1:
+        l = j + (max - l);
+        if (filename[l - 1] == '$') /* not optimal */
+          filename[l + 1] = '\0';
+        else
+          filename[l] = '\0';
+      } else {
+        x = (char *)htsstr_escape_find(filename + j, s - (filename + j) - ((l + k) - max));
+        if (x == NULL)
+          goto cut1;
+        k = strlen(s);
+        memmove(x, s, k);
+        x[k] = '\0';
+      }
     }
 
     htsstr_substitute(filename + j, ptmp, sizeof(ptmp), '$', dvr_subs_tally, number, tmp, sizeof(tmp));
index 3fc157badcad56253df4f5670eb57575ad8a35ac..71e33c9b554a32b018f19508e96cf20b1150373a 100644 (file)
@@ -101,6 +101,26 @@ htsstr_unescape_to(const char *src, char *dst, size_t dstlen)
   return res;
 }
 
+const char *
+htsstr_escape_find(const char *src, size_t upto_index)
+{
+  while (upto_index && *src) {
+    if (*src == '\\') {
+      src++;
+      upto_index--;
+      if (*src == '\0' || upto_index == 0) {
+        src--;
+        break;
+      }
+    }
+    src++;
+    upto_index--;
+  }
+  if (*src)
+    return src;
+  return NULL;
+}
+
 static void
 htsstr_argsplit_add(char ***argv, int *argc, char *s)
 {
@@ -185,6 +205,21 @@ htsstr_argsplit_free(char **argv) {
   free(argv);
 }
 
+const char *
+htsstr_substitute_find(const char *src, int first)
+{
+  while (*src) {
+    if (*src == '\\') {
+      src++;
+      if (*src == '\0')
+        break;
+    } else if (*src == first)
+      return src;
+    src++;
+  }
+  return NULL;
+}
+
 char *
 htsstr_substitute(const char *src, char *dst, size_t dstlen,
                   int first, htsstr_substitute_t *sub, const void *aux,
index 24a9ff4e0e39cc1b53ee7fcdc028a831ae2f5f25..719ba7cf179da8abcaa100d8907135b1b7b4a6a6 100644 (file)
@@ -27,6 +27,8 @@ char *htsstr_unescape(char *str);
 
 char *htsstr_unescape_to(const char *src, char *dst, size_t dstlen);
 
+const char *htsstr_escape_find(const char *src, size_t upto_index);
+
 char **htsstr_argsplit(const char *str);
 
 void htsstr_argsplit_free(char **argv);
@@ -36,6 +38,9 @@ typedef struct {
   const char *(*getval)(const char *id, const void *aux, char *tmp, size_t tmplen);
 } htsstr_substitute_t;
 
+const char *
+htsstr_substitute_find(const char *src, int first);
+
 char *
 htsstr_substitute(const char *src, char *dst, size_t dstlen,
                   int first, htsstr_substitute_t *sub, const void *aux,