From: "Richard W.M. Jones" <rjones(a)redhat.com>
(cherry picked from commit e5285cc4210683887a5a4a853fe4e6a72c23e74d)
(cherry picked from commit 0a22c69b7f7b7fda8dbfdf06db3fbdf9c2994c8f)
---
src/guestfs-internal-frontend.h | 1 +
src/launch-libvirt.c | 34 ++--------------------------------
src/utils.c | 39 +++++++++++++++++++++++++++++++++++++++
3 files changed, 42 insertions(+), 32 deletions(-)
diff --git a/src/guestfs-internal-frontend.h b/src/guestfs-internal-frontend.h
index e4bf50c..06ed37f 100644
--- a/src/guestfs-internal-frontend.h
+++ b/src/guestfs-internal-frontend.h
@@ -95,6 +95,7 @@ extern char *guestfs___safe_asprintf (guestfs_h *g, const char *fs,
...)
extern void guestfs___free_string_list (char **);
extern size_t guestfs___count_strings (char *const *);
extern char *guestfs___exit_status_to_string (int status, const char *cmd_name, char
*buffer, size_t buflen);
+extern int guestfs___random_string (char *ret, size_t len);
/* These functions are used internally by the CLEANUP_* macros.
* Don't call them directly.
diff --git a/src/launch-libvirt.c b/src/launch-libvirt.c
index 5849421..6188671 100644
--- a/src/launch-libvirt.c
+++ b/src/launch-libvirt.c
@@ -133,7 +133,6 @@ static void debug_socket_permissions (guestfs_h *g);
static void libvirt_error (guestfs_h *g, const char *fs, ...) __attribute__((format
(printf,2,3)));
static int is_custom_qemu (guestfs_h *g);
static int is_blk (const char *path);
-static int random_chars (char *ret, size_t len);
static void ignore_errors (void *ignore, virErrorPtr ignore2);
static char *make_qcow2_overlay (guestfs_h *g, const char *path, const char *format);
static int make_qcow2_overlay_for_drive (guestfs_h *g, struct drive *drv);
@@ -799,8 +798,8 @@ construct_libvirt_xml_name (guestfs_h *g,
{
char name[DOMAIN_NAME_LEN+1];
- if (random_chars (name, DOMAIN_NAME_LEN) == -1) {
- perrorf (g, "/dev/urandom");
+ if (guestfs___random_string (name, DOMAIN_NAME_LEN) == -1) {
+ perrorf (g, "guestfs___random_string");
return -1;
}
@@ -1325,35 +1324,6 @@ is_blk (const char *path)
return S_ISBLK (statbuf.st_mode);
}
-static int
-random_chars (char *ret, size_t len)
-{
- int fd;
- size_t i;
- unsigned char c;
- int saved_errno;
-
- fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC);
- if (fd == -1)
- return -1;
-
- for (i = 0; i < len; ++i) {
- if (read (fd, &c, 1) != 1) {
- saved_errno = errno;
- close (fd);
- errno = saved_errno;
- return -1;
- }
- ret[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[c % 36];
- }
- ret[len] = '\0';
-
- if (close (fd) == -1)
- return -1;
-
- return 0;
-}
-
static void
ignore_errors (void *ignore, virErrorPtr ignore2)
{
diff --git a/src/utils.c b/src/utils.c
index fa60011..01c31d6 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -22,6 +22,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <libintl.h>
@@ -83,3 +85,40 @@ guestfs___exit_status_to_string (int status, const char *cmd_name,
return buffer;
}
+
+/* Notes:
+ *
+ * The 'ret' buffer must have length len+1 in order to store the final
+ * \0 character.
+ *
+ * There is about 5 bits of randomness per output character (so about
+ * 5*len bits of randomness in the resulting string).
+ */
+int
+guestfs___random_string (char *ret, size_t len)
+{
+ int fd;
+ size_t i;
+ unsigned char c;
+ int saved_errno;
+
+ fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC);
+ if (fd == -1)
+ return -1;
+
+ for (i = 0; i < len; ++i) {
+ if (read (fd, &c, 1) != 1) {
+ saved_errno = errno;
+ close (fd);
+ errno = saved_errno;
+ return -1;
+ }
+ ret[i] = "0123456789abcdefghijklmnopqrstuvwxyz"[c % 36];
+ }
+ ret[len] = '\0';
+
+ if (close (fd) == -1)
+ return -1;
+
+ return 0;
+}
--
1.8.3.1