]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
htsp: some re-structuring and additons to HTSP file support.
authorAdam Sutton <dev@adamsutton.me.uk>
Thu, 15 Nov 2012 17:01:03 +0000 (17:01 +0000)
committerAdam Sutton <dev@adamsutton.me.uk>
Thu, 15 Nov 2012 17:05:11 +0000 (17:05 +0000)
src/htsp_server.c

index 612d5f2753b6ba7c13a8993a044064660f463fe4..70418b4a8381aaa7015c26fdf2a6eab74e76a623 100644 (file)
@@ -358,6 +358,69 @@ htsp_generate_challenge(htsp_connection_t *htsp)
   return n != 32;
 }
 
+/* **************************************************************************
+ * File helpers
+ * *************************************************************************/
+
+/**
+ *
+ */
+static htsmsg_t *
+htsp_file_open(htsp_connection_t *htsp, const char *path)
+{
+  struct stat st;
+  int fd = open(path, O_RDONLY);
+  tvhlog(LOG_DEBUG, "HTSP", "Opening file %s -- %s", path, fd < 0 ? strerror(errno) : "OK");
+  if(fd == -1)
+    return htsp_error("Unable to open file");
+
+  htsp_file_t *hf = calloc(1, sizeof(htsp_file_t));
+  hf->hf_fd = fd;
+  hf->hf_id = ++htsp->htsp_file_id;
+  hf->hf_path = strdup(path);
+ LIST_INSERT_HEAD(&htsp->htsp_files, hf, hf_link);
+
+  htsmsg_t *rep = htsmsg_create_map();
+  htsmsg_add_u32(rep, "id", hf->hf_id);
+
+  if(!fstat(hf->hf_fd, &st)) {
+    htsmsg_add_u64(rep, "size", st.st_size);
+    htsmsg_add_u64(rep, "mtime", st.st_mtime);
+  }
+
+  return rep;
+}
+
+/**
+ *
+ */
+static htsp_file_t *
+htsp_file_find(const htsp_connection_t *htsp, htsmsg_t *in)
+{
+  htsp_file_t *hf;
+
+  int id = htsmsg_get_u32_or_default(in, "id", 0);
+
+  LIST_FOREACH(hf, &htsp->htsp_files, hf_link) {
+    if(hf->hf_id == id)
+      return hf;
+  }
+  return NULL;
+}
+
+/**
+ *
+ */
+static void
+htsp_file_destroy(htsp_file_t *hf)
+{
+  tvhlog(LOG_DEBUG, "HTSP", "Closed opened file %s", hf->hf_path);
+  free(hf->hf_path);
+  close(hf->hf_fd);
+  LIST_REMOVE(hf, hf_link);
+  free(hf);
+}
+
 /* **************************************************************************
  * Output message generators
  * *************************************************************************/
@@ -1249,37 +1312,6 @@ htsp_method_change_weight(htsp_connection_t *htsp, htsmsg_t *in)
   return NULL;
 }
 
-
-/**
- *
- */
-static htsmsg_t *
-htsp_method_open_path(htsp_connection_t *htsp, const char *path)
-{
-  struct stat st;
-  int fd = open(path, O_RDONLY);
-  tvhlog(LOG_DEBUG, "HTSP", "Opening file %s -- %s", path, fd < 0 ? strerror(errno) : "OK");
-  if(fd == -1)
-    return htsp_error("Unable to open file");
-
-  htsp_file_t *hf = calloc(1, sizeof(htsp_file_t));
-  hf->hf_fd = fd;
-  hf->hf_id = ++htsp->htsp_file_id;
-  hf->hf_path = strdup(path);
- LIST_INSERT_HEAD(&htsp->htsp_files, hf, hf_link);
-
-  htsmsg_t *rep = htsmsg_create_map();
-  htsmsg_add_u32(rep, "id", hf->hf_id);
-
-  if(!fstat(hf->hf_fd, &st)) {
-    htsmsg_add_u64(rep, "size", st.st_size);
-    htsmsg_add_u64(rep, "mtime", st.st_mtime);
-  }
-
-  return rep;
-}
-
-
 /**
  * Open file
  */
@@ -1304,50 +1336,31 @@ htsp_method_file_open(htsp_connection_t *htsp, htsmsg_t *in)
     return htsp_error("Unknown file");
   }
 
-  return htsp_method_open_path(htsp, filename);
+  return htsp_file_open(htsp, filename);
 }
 
-/**
- *
- */
-static htsp_file_t *
-file_find(const htsp_connection_t *htsp, htsmsg_t *in)
-{
-  htsp_file_t *hf;
-
-  int id = htsmsg_get_u32_or_default(in, "id", 0);
-
-  LIST_FOREACH(hf, &htsp->htsp_files, hf_link) {
-    if(hf->hf_id == id)
-      return hf;
-  }
-  return NULL;
-}
-
-
-
 /**
  *
  */
 static htsmsg_t *
 htsp_method_file_read(htsp_connection_t *htsp, htsmsg_t *in)
 {
-  htsp_file_t *hf = file_find(htsp, in);
+  htsp_file_t *hf = htsp_file_find(htsp, in);
   uint64_t off;
-  uint32_t size;
-
-  if(htsmsg_get_u64(in, "offset", &off))
-    return htsp_error("Missing field 'offset'");
-
-  if(htsmsg_get_u32(in, "size", &size))
-    return htsp_error("Missing field 'size'");
+  uint64_t size;
 
   if(hf == NULL)
     return htsp_error("Unknown file id");
 
-  if(lseek(hf->hf_fd, off, SEEK_SET) != off)
-    return htsp_error("Seek error");
+  if(htsmsg_get_u64(in, "size", &size))
+    return htsp_error("Missing field 'size'");
+
+  /* Seek (optional) */
+  if (!htsmsg_get_u64(in, "offset", &off))
+    if(lseek(hf->hf_fd, off, SEEK_SET) != off)
+      return htsp_error("Seek error");
 
+  /* Read */
   void *m = malloc(size);
   if(m == NULL)
     return htsp_error("Too big segment");
@@ -1364,27 +1377,13 @@ htsp_method_file_read(htsp_connection_t *htsp, htsmsg_t *in)
   return rep;
 }
 
-
-/**
- *
- */
-static void
-htsp_file_destroy(htsp_file_t *hf)
-{
-  tvhlog(LOG_DEBUG, "HTSP", "Closed opened file %s", hf->hf_path);
-  free(hf->hf_path);
-  close(hf->hf_fd);
-  LIST_REMOVE(hf, hf_link);
-  free(hf);
-}
-
 /**
  *
  */
 static htsmsg_t *
 htsp_method_file_close(htsp_connection_t *htsp, htsmsg_t *in)
 {
-  htsp_file_t *hf = file_find(htsp, in);
+  htsp_file_t *hf = htsp_file_find(htsp, in);
 
   if(hf == NULL)
     return htsp_error("Unknown file id");
@@ -1393,14 +1392,13 @@ htsp_method_file_close(htsp_connection_t *htsp, htsmsg_t *in)
   return htsmsg_create_map();
 }
 
-
 /**
  *
  */
 static htsmsg_t *
 htsp_method_file_stat(htsp_connection_t *htsp, htsmsg_t *in)
 {
-  htsp_file_t *hf = file_find(htsp, in);
+  htsp_file_t *hf = htsp_file_find(htsp, in);
   struct stat st;
 
   if(hf == NULL)
@@ -1414,6 +1412,44 @@ htsp_method_file_stat(htsp_connection_t *htsp, htsmsg_t *in)
   return rep;
 }
 
+/**
+ *
+ */
+static htsmsg_t *
+htsp_method_file_seek(htsp_connection_t *htsp, htsmsg_t *in)
+{
+  htsp_file_t *hf = htsp_file_find(htsp, in);
+  htsmsg_t *rep;
+  const char *str;
+  int64_t off;
+  int whence;
+
+  if(hf == NULL)
+    return htsp_error("Unknown file id");
+
+  if (htsmsg_get_s64(in, "offset", &off))
+    return htsp_error("Missing field 'offset'");
+
+  if ((str = htsmsg_get_str(in, "whence"))) {
+    if (!strcmp(str, "SEEK_SET"))
+      whence = SEEK_SET;
+    else if (!strcmp(str, "SEEK_CUR"))
+      whence = SEEK_CUR;
+    else if (!strcmp(str, "SEEK_END"))
+      whence = SEEK_END;
+    else
+      return htsp_error("Field 'whence' contained invalid value");
+  } else {
+    whence = SEEK_CUR;
+  }
+
+  if(lseek(hf->hf_fd, off, whence) != off)
+    return htsp_error("Seek error");
+
+  rep = htsmsg_create_map();
+  htsmsg_add_s64(rep, "offset", off);
+  return rep;
+}
 
 /**
  * HTSP methods
@@ -1440,10 +1476,11 @@ struct {
   { "subscribe",                htsp_method_subscribe,      ACCESS_STREAMING},
   { "unsubscribe",              htsp_method_unsubscribe,    ACCESS_STREAMING},
   { "subscriptionChangeWeight", htsp_method_change_weight,  ACCESS_STREAMING},
-  { "openFile",                 htsp_method_file_open,      ACCESS_RECORDER},
-  { "readFile",                 htsp_method_file_read,      ACCESS_RECORDER},
-  { "closeFile",                htsp_method_file_close,     ACCESS_RECORDER},
-  { "statFile",                 htsp_method_file_stat,      ACCESS_RECORDER},
+  { "fileOpen",                 htsp_method_file_open,      ACCESS_RECORDER},
+  { "fileRead",                 htsp_method_file_read,      ACCESS_RECORDER},
+  { "fileClose",                htsp_method_file_close,     ACCESS_RECORDER},
+  { "fileStat",                 htsp_method_file_stat,      ACCESS_RECORDER},
+  { "fileSeek",                 htsp_method_file_seek,      ACCESS_RECORDER},
 };
 
 #define NUM_METHODS (sizeof(htsp_methods) / sizeof(htsp_methods[0]))