From: Adam Sutton Date: Thu, 3 Apr 2014 20:50:55 +0000 (+0100) Subject: idnode uuid: move uuid routines to sep. file so it can be used more generally X-Git-Tag: v4.1~2207 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bd2525ed2a2886b24d3d8db42d007359fc13d2b6;p=thirdparty%2Ftvheadend.git idnode uuid: move uuid routines to sep. file so it can be used more generally --- diff --git a/Makefile b/Makefile index 275e34359..8bbdda640 100644 --- 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 \ diff --git a/src/idnode.c b/src/idnode.c index b06756e82..86fea08a8 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -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; } /** diff --git a/src/idnode.h b/src/idnode.h index a10c1056b..b883c55af 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -22,12 +22,10 @@ #include "tvheadend.h" #include "prop.h" +#include "uuid.h" #include -#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); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c index 9e8ed91bf..67cd2d42f 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c @@ -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 diff --git a/src/main.c b/src/main.c index c419af2a3..2fc1dd108 100644 --- a/src/main.c +++ b/src/main.c @@ -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 index 000000000..54f343da0 --- /dev/null +++ b/src/uuid.c @@ -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 . + */ + +#include "tvheadend.h" +#include "uuid.h" + +#include +#include +#include +#include + +#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 index 000000000..81c097573 --- /dev/null +++ b/src/uuid.h @@ -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 . + */ + +#ifndef __TVH_UUID_H__ +#define __TVH_UUID_H__ + +#include + +#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__ */