]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
idnode uuid: move uuid routines to sep. file so it can be used more generally
authorAdam Sutton <dev@adamsutton.me.uk>
Thu, 3 Apr 2014 20:50:55 +0000 (21:50 +0100)
committerAdam Sutton <dev@adamsutton.me.uk>
Fri, 4 Apr 2014 08:55:07 +0000 (09:55 +0100)
Makefile
src/idnode.c
src/idnode.h
src/input/mpegts/linuxdvb/linuxdvb_adapter.c
src/main.c
src/uuid.c [new file with mode: 0644]
src/uuid.h [new file with mode: 0644]

index 275e343595ff41a891dc56ce9f3c844dc806f939..8bbdda6407972a13c00759243bb818999554c001 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -66,6 +66,7 @@ endif
 # Core
 #
 SRCS =  src/version.c \
+       src/uuid.c \
        src/main.c \
        src/tvhlog.c \
        src/idnode.c \
index b06756e82385af9328bbbc779df60e731aac7050..86fea08a8148a2ff23dfdfe1cba65a39e8196340 100644 (file)
@@ -28,6 +28,7 @@
 #include "idnode.h"
 #include "notify.h"
 #include "settings.h"
+#include "uuid.h"
 
 typedef struct idclass_link
 {
@@ -35,7 +36,6 @@ typedef struct idclass_link
   RB_ENTRY(idclass_link) link;
 } idclass_link_t;
 
-static int                    randfd = 0;
 static RB_HEAD(,idnode)       idnodes;
 static RB_HEAD(,idclass_link) idclasses;
 static pthread_cond_t         idnode_cond;
@@ -52,60 +52,6 @@ idclass_register(const idclass_t *idc);
  * Utilities
  * *************************************************************************/
 
-/**
- *
- */
-static int
-hexnibble(char c)
-{
-  switch(c) {
-  case '0' ... '9':    return c - '0';
-  case 'a' ... 'f':    return c - 'a' + 10;
-  case 'A' ... 'F':    return c - 'A' + 10;
-  default:
-    return -1;
-  }
-}
-
-
-/**
- *
- */
-static int
-hex2bin(uint8_t *buf, size_t buflen, const char *str)
-{
-  int hi, lo;
-
-  while(*str) {
-    if(buflen == 0)
-      return -1;
-    if((hi = hexnibble(*str++)) == -1)
-      return -1;
-    if((lo = hexnibble(*str++)) == -1)
-      return -1;
-
-    *buf++ = hi << 4 | lo;
-    buflen--;
-  }
-  return 0;
-}
-
-/**
- *
- */
-static void
-bin2hex(char *dst, size_t dstlen, const uint8_t *src, size_t srclen)
-{
-  while(dstlen > 2 && srclen > 0) {
-    *dst++ = "0123456789abcdef"[*src >> 4];
-    *dst++ = "0123456789abcdef"[*src & 0xf];
-    src++;
-    srclen--;
-    dstlen -= 2;
-  }
-  *dst = 0;
-}
-
 /**
  *
  */
@@ -127,10 +73,6 @@ pthread_t idnode_tid;
 void
 idnode_init(void)
 {
-  randfd = open("/dev/urandom", O_RDONLY);
-  if(randfd == -1)
-    exit(1);
-  
   idnode_queue = NULL;
   pthread_mutex_init(&idnode_mutex, NULL);
   pthread_cond_init(&idnode_cond, NULL);
@@ -163,15 +105,10 @@ idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class)
 {
   idnode_t *c;
   lock_assert(&global_lock);
-  if(uuid == NULL) {
-    if(read(randfd, in->in_uuid, sizeof(in->in_uuid)) != sizeof(in->in_uuid)) {
-      perror("read(random for uuid)");
-      exit(1);
-    }
-  } else {
-    if(hex2bin(in->in_uuid, sizeof(in->in_uuid), uuid))
-      return -1;
-  }
+  uuid_t u;
+  if (uuid_init_bin(&u, uuid))
+    return -1;
+  memcpy(in->in_uuid, u.bin, sizeof(in->in_uuid));
 
   in->in_class = class;
 
@@ -236,25 +173,14 @@ idnode_get_short_uuid (const idnode_t *in)
  *
  */
 const char *
-idnode_uuid_as_str0(const idnode_t *in, char *b)
-{
-  bin2hex(b, UUID_STR_LEN, in->in_uuid, sizeof(in->in_uuid));
-  return b;
-}
-const char *
 idnode_uuid_as_str(const idnode_t *in)
 {
-  static char ret[16][UUID_STR_LEN];
-  static int p = 0;
-  char *b = ret[p];
+  static uuid_t ret[16];
+  static uint8_t p = 0;
+  bin2hex(ret[p].hex, sizeof(ret[p].hex), in->in_uuid, sizeof(in->in_uuid));
+  const char *s = ret[p].hex;
   p = (p + 1) % 16;
-  return idnode_uuid_as_str0(in, b);
-}
-const char *
-idnode_uuid_as_str1 ( const uint8_t *bin, size_t len, char *b )
-{
-  bin2hex(b, UUID_STR_LEN, bin, len);
-  return b;
+  return s;
 }
 
 /**
index a10c1056b8f8547082f29ea5fb2403a491b8894f..b883c55aff0f72fe3afb11a0976331ba98250701 100644 (file)
 
 #include "tvheadend.h"
 #include "prop.h"
+#include "uuid.h"
 
 #include <regex.h>
 
-#define UUID_STR_LEN 33 // inc NUL char
-#define UUID_BIN_LEN 16
-
 struct htsmsg;
 typedef struct idnode idnode_t;
 
@@ -62,9 +60,9 @@ typedef struct idclass {
  * Node definition
  */
 struct idnode {
-  uint8_t           in_uuid[UUID_BIN_LEN]; ///< Unique ID
-  RB_ENTRY(idnode)  in_link;               ///< Global hash
-  const idclass_t  *in_class;              ///< Class definition
+  uint8_t           in_uuid[UUID_BIN_SIZE]; ///< Unique ID
+  RB_ENTRY(idnode)  in_link;                ///< Global hash
+  const idclass_t  *in_class;               ///< Class definition
 };
 
 /*
@@ -115,8 +113,6 @@ int  idnode_insert(idnode_t *in, const char *uuid, const idclass_t *idc);
 void idnode_unlink(idnode_t *in);
 
 uint32_t      idnode_get_short_uuid (const idnode_t *in);
-const char   *idnode_uuid_as_str1 (const uint8_t *bin, size_t len, char *b);
-const char   *idnode_uuid_as_str0 (const idnode_t *in, char *b);
 const char   *idnode_uuid_as_str  (const idnode_t *in);
 idnode_set_t *idnode_get_childs   (idnode_t *in);
 const char   *idnode_get_title    (idnode_t *in);
index 9e8ed91bf3c0d3124901b7b71758134bcfbe55e2..67cd2d42fdd49c8b16e885f7c78144c555ecefe8 100644 (file)
@@ -163,7 +163,8 @@ linuxdvb_adapter_add ( const char *path )
 {
   extern int linuxdvb_adapter_mask;
   int a, i, j, r, fd;
-  char fe_path[512], dmx_path[512], dvr_path[512], uuid[UUID_STR_LEN];
+  char fe_path[512], dmx_path[512], dvr_path[512];
+  uuid_t uuid;
   linuxdvb_adapter_t *la = NULL;
   struct dvb_frontend_info dfi;
   SHA_CTX sha1;
@@ -265,7 +266,7 @@ linuxdvb_adapter_add ( const char *path )
       SHA1_Update(&sha1, (void*)path,     strlen(path));
       SHA1_Update(&sha1, (void*)dfi.name, strlen(dfi.name));
       SHA1_Final(uuidbin, &sha1);
-      idnode_uuid_as_str1(uuidbin, sizeof(uuidbin), uuid);
+      bin2hex(uuid.hex, sizeof(uuid.hex), uuidbin, sizeof(uuidbin));
 
       /* Load config */
       conf = hts_settings_load("input/linuxdvb/adapters/%s", uuid);
@@ -275,7 +276,7 @@ linuxdvb_adapter_add ( const char *path )
         save = 1;
   
       /* Create */
-      if (!(la = linuxdvb_adapter_create(uuid, conf, path, a, &dfi))) {
+      if (!(la = linuxdvb_adapter_create(uuid.hex, conf, path, a, &dfi))) {
         tvhlog(LOG_ERR, "linuxdvb", "failed to create %s", path);
         htsmsg_destroy(conf);
         return; // Note: save to return here as global_lock is held
index c419af2a3b68c73440e3c1cf270e9063ef0d4684..2fc1dd108ea9b01b76e57071a6d941046fefe3fe 100644 (file)
@@ -725,6 +725,7 @@ main(int argc, char **argv)
     tvhlog_options &= ~TVHLOG_OPT_DECORATE;
   
   /* Initialise configuration */
+  uuid_init();
   idnode_init();
   hts_settings_init(opt_config);
 
diff --git a/src/uuid.c b/src/uuid.c
new file mode 100644 (file)
index 0000000..54f343d
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ *  TV headend - UUID generation routines
+ *
+ *  Copyright (C) 2014 Adam Sutton
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "tvheadend.h"
+#include "uuid.h"
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#define RANDOM_PATH "/dev/urandom"
+
+static int fd = -1;
+
+/* **************************************************************************
+ * Utilities
+ * *************************************************************************/
+
+/**
+ *
+ */
+static int
+hexnibble(char c)
+{
+  switch(c) {
+  case '0' ... '9':    return c - '0';
+  case 'a' ... 'f':    return c - 'a' + 10;
+  case 'A' ... 'F':    return c - 'A' + 10;
+  default:
+    return -1;
+  }
+}
+
+
+/**
+ *
+ */
+int
+hex2bin(uint8_t *buf, size_t buflen, const char *str)
+{
+  int hi, lo;
+
+  while(*str) {
+    if(buflen == 0)
+      return -1;
+    if((hi = hexnibble(*str++)) == -1)
+      return -1;
+    if((lo = hexnibble(*str++)) == -1)
+      return -1;
+
+    *buf++ = hi << 4 | lo;
+    buflen--;
+  }
+  return 0;
+}
+
+/**
+ *
+ */
+void
+bin2hex(char *dst, size_t dstlen, const uint8_t *src, size_t srclen)
+{
+  while(dstlen > 2 && srclen > 0) {
+    *dst++ = "0123456789abcdef"[*src >> 4];
+    *dst++ = "0123456789abcdef"[*src & 0xf];
+    src++;
+    srclen--;
+    dstlen -= 2;
+  }
+  *dst = 0;
+}
+
+/* **************************************************************************
+ * UUID Handling
+ * *************************************************************************/
+
+void
+uuid_init ( void )
+{
+  fd = open(RANDOM_PATH, O_RDONLY);
+  if (fd == -1) {
+    tvherror("uuid", "failed to open %s", RANDOM_PATH);
+    exit(1);
+  }
+}
+
+/* Initialise binary */
+int
+uuid_init_bin ( uuid_t *u, const char *str )
+{
+  memset(u, 0, sizeof(uuid_t));
+  if (str) {
+    return hex2bin(u->bin, sizeof(u->bin), str);
+  } else if (read(fd, u->bin, sizeof(u->bin)) != sizeof(u->bin)) {
+    tvherror("uuid", "failed to read from %s", RANDOM_PATH);
+    exit(1);
+  }
+  return 0;
+}
+
+/* Initialise hex string */
+int
+uuid_init_hex ( uuid_t *u, const char *str )
+{
+  uuid_t tmp;
+  if (uuid_init_bin(&tmp, str))
+    return 1;
+  return uuid_bin2hex(&tmp, u);
+}
+
+/* Convert bin to hex string */
+int
+uuid_bin2hex ( const uuid_t *a, uuid_t *b )
+{
+  uuid_t tmp;
+  memset(&tmp, 0, sizeof(tmp));
+  bin2hex(tmp.hex, sizeof(tmp.hex), a->bin, sizeof(a->bin));
+  memcpy(b, &tmp, sizeof(tmp));
+  return 0;
+}
+
+/* Convert hex string to bin (in place) */
+int
+uuid_hex2bin ( const uuid_t *a, uuid_t *b )
+{ 
+  uuid_t tmp;
+  memset(&tmp, 0, sizeof(tmp));
+  if (hex2bin(tmp.bin, sizeof(tmp.bin), a->hex))
+    return 1;
+  memcpy(b, &tmp, sizeof(tmp));
+  return 0;
+}
diff --git a/src/uuid.h b/src/uuid.h
new file mode 100644 (file)
index 0000000..81c0975
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  TV headend - UUID generation routines
+ *
+ *  Copyright (C) 2014 Adam Sutton
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __TVH_UUID_H__
+#define __TVH_UUID_H__
+
+#include <stdint.h>
+
+#define UUID_BIN_SIZE   (16)
+#define UUID_HEX_SIZE   (33) // inc NUL
+
+/* Structure to hold UUID */
+typedef struct uuid {
+  union {
+    uint8_t bin[UUID_BIN_SIZE];
+    char    hex[UUID_HEX_SIZE];
+  };
+} uuid_t;
+
+/* Initialise subsystem */
+void uuid_init ( void );
+
+/* Initialise binary */
+int uuid_init_bin ( uuid_t *u, const char *str );
+
+/* Initialise hex string */
+int uuid_init_hex ( uuid_t *u, const char *str );
+
+/**
+ * Convert bin to hex string
+ *
+ * Note: conversion is done such that a and b can be the same
+ */
+int uuid_bin2hex  ( const uuid_t *a, uuid_t *b );
+
+/**
+ * Convert hex string to bin (in place)
+ *
+ * Note: conversion is done such that a and b can be the same
+ */
+int uuid_hex2bin  ( const uuid_t *a, uuid_t *b );
+
+/**
+ * Hex string to binary
+ */
+int hex2bin ( uint8_t *buf, size_t buflen, const char *hex );
+
+/**
+ * Binary to hex string
+ */
+void bin2hex ( char *dst, size_t dstlen, const uint8_t *src, size_t srclen );
+
+#endif /* __TVH_UUID_H__ */