Mythtvfs

From MythTV Official Wiki
Jump to: navigation, search

Warning.png Warning: The patches contained here only correct for the use of tokens in the communications protocol, and changes in the length of the ProgramInfo object. They do not account for changes in content of the ProgramInfo object, and thus cannot account for items being added or removed from the middle of the object. Expect use of these patches to result in strange, or potentially broken, behavior.

MythtvFS (http://outflux.net/software/pkgs/mythtvfs-fuse/) uses fuse (http://fuse.sf.net). It allows you to print the more verbose filenames, rather than the default filename that mythtv provides.

Instructions provided on the MythtvFS page above. NOTE: To mount and allow other users to access the mount, use -o allow_other.

Here is a experimental patch to get mythtvfs-0.6.1 working with MythTV 0.26 (apply the patch for mythtv 0.25 from below at first): Debian packages are available here: ftp://ftp.geierb.de/debian%20packages/mythtvfs/

--- mythtvfs-fuse-0.6.1.orig/mythtvfs.c
+++ mythtvfs-fuse-0.6.1/mythtvfs.c
@@ -92,7 +92,7 @@ struct mythtvfs {
     char * datetime_format;
     int short_display_flag;
     int backend_version_override; // manually override compile-time defaults
-    int backend_version_token_override; // manually override compile-time defaults
+    char * backend_version_token_override; // manually override compile-time defaults
     int program_width_override;   // manually override compile-time defaults
     char * invalid_chars;         // list of invalid characters
     char * replacement_char;      // character to replace invalid chars with
@@ -124,7 +124,7 @@ static struct fuse_opt mythtvfs_opts[] =
     MYTHTVFS_OPT("short-display",      short_display_flag, 1),
     MYTHTVFS_OPT("logfile=%s",         logfile_name, 0),
     MYTHTVFS_OPT("backend-version=%d", backend_version_override, 0),
-    MYTHTVFS_OPT("backend-token=%X",   backend_version_token_override, 0),
+    MYTHTVFS_OPT("backend-token=%s",   backend_version_token_override, 0),
     MYTHTVFS_OPT("program-width=%d",   program_width_override, 0),
     MYTHTVFS_OPT("invalid-chars=%s",   invalid_chars, 0),
     MYTHTVFS_OPT("replacement-char=%s",replacement_char, 0),
@@ -359,17 +359,17 @@ void backend_client_check()

 #define MYTH_SEP "[]:[]"

-int _version_check(int requested_version, int requested_token)
+int _version_check(int requested_version, char *requested_token)
 {
     char *check = NULL, *result, *version="unknown";
     char version_request[80];
     int rc = 0;

     // check for a valid token
-    if ( requested_token == 0x0 ) {
+    if ( strlen(requested_token) == 0 ) {
     snprintf(version_request, 80, "MYTH_PROTO_VERSION %d", requested_version);
     } else {
-      snprintf(version_request, 80, "MYTH_PROTO_VERSION %d %X", requested_version, requested_token);
+      snprintf(version_request, 80, "MYTH_PROTO_VERSION %d %s", requested_version, requested_token);
     }
     if (!backend_cmd(version_request, &check)) {
             fprintf(stderr,"Cannot check backend version!\n");
@@ -397,7 +397,7 @@ int _version_check(int requested_version
 struct backend_widths {
     int version;
     int width;
-  int token;
+    char* token;

 };
 int guess_program_cols(void);
@@ -408,16 +408,22 @@ void backend_version_check()
      * Version and Token found in libs/libmythdb/mythversion.h MYTH_PROTO_VERSION
      * Columns found in libs/libmyth/programinfo.h NUMPROGRAMLINES
      *
-     * Note: token does not appear to be needed for pre-0.25 mythtv so we set it to 0
+     * Note: token does not appear to be needed for pre-0.25 mythtv so we leave it empty
      */
     struct backend_widths versions[] = {
-      { 72, 44, 0xD78EFD6F },
-      { 50, 47, 0x0 },
-      { 40, 46, 0x0 },
-      { 31, 42, 0x0 },
-      { 26, 41, 0x0 },
-      { 15, 39, 0x0 },
-      { 0,  0, 0x0  },
+      { 77, 47, "WindMark" },
+      { 76, 47, "FireWild" },
+      { 75, 44, "SweetRock" },
+      { 74, 44, "SingingPotato" },
+      { 73, 44, "D7FE8D6F" },
+      { 72, 44, "D78EFD6F" },
+      { 69, 44, "63835135" },
+      { 50, 47, ""},
+      { 40, 46, "" },
+      { 31, 42, "" },
+      { 26, 41, "" },
+      { 15, 39, "" },
+      { 0,  0,  "" },
     };
     int idx, version = 0;
     int found=0;


Here is a lightly tested patch to get mythtvfs-0.6.1 to work with mythtv 0.25:

--- mythtvfs.c.orig     2009-11-01 18:52:17.000000000 -0500
+++ mythtvfs.c  2012-05-09 15:01:21.489783813 -0400
@@ -92,6 +92,7 @@
     char * datetime_format;
     int short_display_flag;
     int backend_version_override; // manually override compile-time defaults
+    int backend_version_token_override; // manually override compile-time defaults
     int program_width_override;   // manually override compile-time defaults
     char * invalid_chars;         // list of invalid characters
     char * replacement_char;      // character to replace invalid chars with
@@ -108,6 +109,9 @@
 
 static struct mythtvfs mythtvfs;
 
+// store the selected protocol version so that we can detect 0.25 mythtv
+static int global_protocol_version;
+
 #define MYTHTVFS_OPT(t, p, v) { t, offsetof(struct mythtvfs, p), v }
 
 static struct fuse_opt mythtvfs_opts[] = {
@@ -120,6 +124,7 @@
     MYTHTVFS_OPT("short-display",      short_display_flag, 1),
     MYTHTVFS_OPT("logfile=%s",         logfile_name, 0),
     MYTHTVFS_OPT("backend-version=%d", backend_version_override, 0),
+    MYTHTVFS_OPT("backend-token=%X",   backend_version_token_override, 0),
     MYTHTVFS_OPT("program-width=%d",   program_width_override, 0),
     MYTHTVFS_OPT("invalid-chars=%s",   invalid_chars, 0),
     MYTHTVFS_OPT("replacement-char=%s",replacement_char, 0),
@@ -354,13 +359,18 @@
 
 #define MYTH_SEP "[]:[]"
 
-int _version_check(int requested_version)
+int _version_check(int requested_version, int requested_token)
 {
     char *check = NULL, *result, *version="unknown";
     char version_request[80];
     int rc = 0;
 
+    // check for a valid token
+    if ( requested_token == 0x0 ) {
     snprintf(version_request, 80, "MYTH_PROTO_VERSION %d", requested_version);
+    } else { 
+      snprintf(version_request, 80, "MYTH_PROTO_VERSION %d %X", requested_version, requested_token);
+    }
     if (!backend_cmd(version_request, &check)) {
             fprintf(stderr,"Cannot check backend version!\n");
             exit(1);
@@ -370,11 +380,16 @@
     *version = '\0';
     version += strlen(MYTH_SEP);
     rc = atoi(version);
+    // fprintf(stderr,"dbg: vc(%d,%X) check(%s) result(%s) version(%s)\n",requested_version,requested_token,check,result,version);
     if (strcmp(result,"ACCEPT")) {
         backend_close();
         rc = 0 - rc;
+    } else {
+      // we have found a match, store the version
+       global_protocol_version = requested_version;
     }
 
+    // fprintf(stderr,"dbg: vc(%d,%X) rc(%d)\n",requested_version,requested_token,rc);
     if (check) free(check);
     return rc;
 }
@@ -382,6 +397,7 @@
 struct backend_widths {
     int version;
     int width;
+  int token;
 };
 
 int guess_program_cols(void);
@@ -389,30 +405,33 @@
 void backend_version_check()
 {
     /*
-     * Version found in libs/libmythdb/mythversion.h MYTH_PROTO_VERSION
+     * Version and Token found in libs/libmythdb/mythversion.h MYTH_PROTO_VERSION
      * Columns found in libs/libmyth/programinfo.h NUMPROGRAMLINES
+     *
+     * Note: token does not appear to be needed for pre-0.25 mythtv so we set it to 0
      */
     struct backend_widths versions[] = {
-        { 50, 47 },
-        { 40, 46 },
-        { 31, 42 },
-        { 26, 41 },
-        { 15, 39 },
-        { 0,  0  },
+      { 72, 44, 0xD78EFD6F },
+      { 50, 47, 0x0 },
+      { 40, 46, 0x0 },
+      { 31, 42, 0x0 },
+      { 26, 41, 0x0 },
+      { 15, 39, 0x0 },
+      { 0,  0, 0x0  },
     };
     int idx, version = 0;
     int found=0;
 
     // check for override version first
     if (mythtvfs.backend_version_override &&
-        (version = _version_check(mythtvfs.backend_version_override))>0) {
+        (version = _version_check(mythtvfs.backend_version_override, mythtvfs.backend_version_token_override))>0) {
         mythtvfs.program_cols = versions[0].width;
         found = 1;
     }
 
     // check for known versions
     for (idx = 0; !found && versions[idx].version; idx++) {
-        if ( (version = _version_check(versions[idx].version))<0 ) continue;
+      if ( (version = _version_check(versions[idx].version, versions[idx].token))<0 ) continue;
 
         mythtvfs.program_cols = versions[idx].width;
         found = 1;
@@ -422,7 +441,7 @@
         version = -version;
         if (mythtvfs.program_width_override) {
             fprintf(stderr,"Warning: unfamiliar backend version (%d), attempting width %d anyway.\n",version, mythtvfs.program_width_override);
-            if (_version_check(version) == version) {
+            if (_version_check(version,0x0) == version) {
                 mythtvfs.program_cols = mythtvfs.program_width_override;
                 found = 1;
             }
@@ -574,7 +593,7 @@
     memset(show,0,sizeof(*show));
 }
 
-char * backend_pop_program(char * buffer, struct show_t * show, int col_width)
+char * backend_pop_program_pre025(char * buffer, struct show_t * show, int col_width)
 {
     int col;
 
@@ -662,6 +681,105 @@
     return buffer;
 }
 
+// mythtv 0.25 version
+char * backend_pop_program_post025(char * buffer, struct show_t * show, int col_width)
+{
+    int col;
+
+    for (col = 0; buffer && col < col_width; col++) {
+        char * sep = NULL;
+        char * data = buffer;
+        if ((sep = strstr(data,MYTH_SEP))!=NULL) {
+            *sep = '\0';
+            sep+=strlen(MYTH_SEP);
+        }
+
+        // make sure we're not null
+        if (!data) data="";
+
+        /* Found in libs/libmyth/programinfo.cpp ProgramInfo::ToStringList */
+        switch (col) {
+            case 1: show->title = strdup(data); break;
+            case 2: show->subtitle = strdup(data); break;
+            case 3: show->description = strdup(data); break;
+            /*
+            case 4: show->category = strdup(data); break;
+            */
+            case 7: show->chanid = strdup(data); break;
+            /*
+            case 6: show->channum = strdup(data); break;
+            */
+            case 9: show->callsign = strdup(data); break;
+            /*
+            case 8: show->channame = strdup(data); break;
+            */
+            case 11: show->pathname = strdup(data); break;
+            /*
+            case 10: show->filesize_hi = strdup(data); break;
+            case 11: show->filesize_lo = strdup(data); break;
+            */
+            case 13: show->starttime = strdup(data); break;
+            case 14: show->endtime = strdup(data); break;
+            /*
+            case 14: show->duplicate = strdup(data); break;
+            case 15: show->shareable = strdup(data); break;
+            case 16: show->findid = strdup(data); break;
+            case 17: show->hostname = strdup(data); break;
+            case 18: show->sourceid = strdup(data); break;
+            case 19: show->cardid = strdup(data); break;
+            case 20: show->inputid = strdup(data); break;
+            case 21: show->recpriority = strdup(data); break;
+            case 22: show->recstatus = strdup(data); break;
+            case 23: show->recordid = strdup(data); break;
+            case 24: show->rectype = strdup(data); break;
+            case 25: show->dupin = strdup(data); break;
+            case 26: show->dupmethod = strdup(data); break;
+            case 27: show->recstartts = strdup(data); break;
+            case 28: show->recendts = strdup(data); break;
+            case 29: show->repeat = strdup(data); break;
+            */
+            case 28: show->flags = atoi(data); break;
+            /*
+            case 31: show->recgroup = strdup(data); break;
+            case 32: show->commfree = strdup(data); break;
+            case 33: show->outputfilters = strdup(data); break;
+            case 34: show->seriesid = strdup(data); break;
+            case 35: show->programid = strdup(data); break;
+            case 36: show->lastmodified = strdup(data); break;
+            case 37: show->stars = strdup(data); break;
+            */
+            case 36: show->airdate = strdup(data); break;
+            /*
+            case 39: show->hasairdate = strdup(data); break;
+            case 40: show->playgroup = strdup(data); break;
+            case 41: show->recpriority = strdup(data); break;
+            case 42: show->parentid = strdup(data); break;
+            case 43: show->storagegroup = strdup(data); break;
+            case 44: show->audioprop = strdup(data); break;
+            case 45: show->videoprop = strdup(data); break;
+            case 46: show->subtitletype = strdup(data); break;
+            case 47: show->year = strdup(data); break;
+            ...
+            */
+            default:
+                break;
+        }
+        buffer = sep;
+    }
+
+    return buffer;
+}
+
+// populate the program list - check for pre- or post-0.25 mythtv protocol
+char * backend_pop_program(char * buffer, struct show_t * show, int col_width) 
+{
+  if ( global_protocol_version >= 72 ) {
+    return backend_pop_program_post025(buffer, show, col_width);
+  } else {
+    return backend_pop_program_pre025(buffer, show, col_width);
+  }
+}
+
 /* return guessed program column width, or -1 for failure */
 int guess_program_cols(void)
 {
@@ -1441,6 +1560,7 @@
     struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
 
     // setup "defaults"
+    global_protocol_version = 0;
     mythtvfs.base_path = NULL;
     mythtvfs.host      = NULL;
     mythtvfs.format    = "{%T}{%a}{%S}{%s}{%c}{%d}{%D}%f.mpg";
@@ -1449,6 +1569,7 @@
     mythtvfs.port      = 6543;
     mythtvfs.short_display_flag = 0;
     mythtvfs.backend_version_override = 0;
+    mythtvfs.backend_version_token_override = 0;
     mythtvfs.program_width_override = 0;
     mythtvfs.invalid_chars = strdup("/");
     mythtvfs.replacement_char = strdup("-");


Here is a patch for protocol version 50, which is needed for mythtvfs-0.6.0 to work with mythtv 0.22:

--- mythtvfs.c      2009-08-18 21:28:56.000000000 +0300
+++ mythtvfs.c        2009-11-27 17:25:58.000000000 +0200
@@ -388,6 +388,7 @@
 void backend_version_check()
 {
     struct backend_widths versions[] = {
+        { 50, 47 },
         { 40, 46 },
         { 31, 42 },
         { 26, 41 },

(It is also possible to just use the "-o program-width=47" mount option)


Here is my patch for mythtvfs-0.4.0 to get it working with fuse 2.6.3 and mythtv 0.20:

NOTE: For mythtvfs-0.4.1, the patch is not needed.

--- mythtvfs.c  2006-05-12 17:12:09.000000000 -0700
+++ mythtvfs.c  2007-02-22 22:08:54.000000000 -0800
@@ -288,7 +288,7 @@
 }
 
 #define MYTH_SEP "[]:[]"
-#define MYTH_PROTO_VERSION "26"
+#define MYTH_PROTO_VERSION "31"
 #define MYTH_PROGRAM_COLS  (mythtvfs.program_cols)
 
 void backend_client_check()
@@ -326,6 +326,7 @@
     switch (atoi(version)) {
         case 15: mythtvfs.program_cols = 39; break;
         case 26: mythtvfs.program_cols = 41; break;
+        case 31: mythtvfs.program_cols = 42; break;
         default:
                  fprintf(stderr,"Unknown protocol version (backend=%s)\n",version);
     }
@@ -915,14 +916,14 @@
     case KEY_HELP:
         usage(outargs->argv[0]);
         fuse_opt_add_arg(outargs, "-ho");
-        fuse_main(outargs->argc, outargs->argv, &mythtvfs_oper);
+        fuse_main(outargs->argc, outargs->argv, &mythtvfs_oper, NULL);
         exit(1);
 
     case KEY_VERSION:
         fprintf(stderr, "MythTVfs version %s\n", PACKAGE_VERSION);
 #if FUSE_VERSION >= 25
         fuse_opt_add_arg(outargs, "--version");
-        fuse_main(outargs->argc, outargs->argv, &mythtvfs_oper);
+        fuse_main(outargs->argc, outargs->argv, &mythtvfs_oper, NULL);
 #endif
         exit(0);
     
@@ -973,7 +974,7 @@
     backend_client_check();
     backend_version_check();
 
-    rc = fuse_main(args.argc, args.argv, &mythtvfs_oper);
+    rc = fuse_main(args.argc, args.argv, &mythtvfs_oper, NULL);
 
     backend_done();
     if (mythtvfs.logfile) fclose(mythtvfs.logfile);