summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard W.M. Jones <rjones@redhat.com>2012-07-18 12:32:21 +0100
committerRichard W.M. Jones <rjones@redhat.com>2012-07-18 12:32:21 +0100
commit781857a86b3bc8238995a9212ea09aa368fc2fc9 (patch)
tree1c686d2dd4105be75abc36b3e399b510bc706f14
parent9c2b9c2df6c3c10b090d71bc808d755dbf625cbe (diff)
downloadlibguestfs-781857a86b3bc8238995a9212ea09aa368fc2fc9.tar.gz
libguestfs-781857a86b3bc8238995a9212ea09aa368fc2fc9.tar.xz
libguestfs-781857a86b3bc8238995a9212ea09aa368fc2fc9.zip
daemon: Make 'random_name' into a utility function.
This is mostly code motion, although the precise contract of this function changes slightly to make it more generally useful
-rw-r--r--daemon/daemon.h2
-rw-r--r--daemon/guestfsd.c46
-rw-r--r--daemon/zero.c33
3 files changed, 51 insertions, 30 deletions
diff --git a/daemon/daemon.h b/daemon/daemon.h
index b4790788..85eec455 100644
--- a/daemon/daemon.h
+++ b/daemon/daemon.h
@@ -112,6 +112,8 @@ extern int prog_exists (const char *prog);
extern void udev_settle (void);
+extern int random_name (char *template);
+
/* This just stops gcc from giving a warning about our custom printf
* formatters %Q and %R. See guestfs(3)/EXTENDING LIBGUESTFS for more
* info about these.
diff --git a/daemon/guestfsd.c b/daemon/guestfsd.c
index b09f74e1..2b0acf96 100644
--- a/daemon/guestfsd.c
+++ b/daemon/guestfsd.c
@@ -1190,6 +1190,52 @@ prog_exists (const char *prog)
return 0;
}
+/* Pass a template such as "/sysroot/XXXXXXXX.XXX". This updates the
+ * template to contain a randomly named file. Any 'X' characters
+ * after the final '/' are replaced with random characters.
+ *
+ * Notes: You should probably use an 8.3 path, so it's compatible with
+ * all filesystems including basic FAT. Also this only substitutes
+ * lowercase ASCII letters and numbers, again for compatibility with
+ * lowest common denominator filesystems.
+ *
+ * This doesn't create a file or check whether or not the file exists
+ * (it would be extremely unlikely to exist as long as the RNG is
+ * working).
+ *
+ * If there is an error, -1 is returned.
+ */
+int
+random_name (char *template)
+{
+ int fd;
+ unsigned char c;
+ char *p;
+
+ fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC);
+ if (fd == -1)
+ return -1;
+
+ p = strrchr (template, '/');
+ if (p == NULL)
+ abort (); /* internal error - bad template */
+
+ while (*p) {
+ if (*p == 'X') {
+ if (read (fd, &c, 1) != 1) {
+ close (fd);
+ return -1;
+ }
+ *p = "0123456789abcdefghijklmnopqrstuvwxyz"[c % 36];
+ }
+
+ p++;
+ }
+
+ close (fd);
+ return 0;
+}
+
/* LVM and other commands aren't synchronous, especially when udev is
* involved. eg. You can create or remove some device, but the /dev
* device node won't appear until some time later. This means that
diff --git a/daemon/zero.c b/daemon/zero.c
index 3076a602..14aef75d 100644
--- a/daemon/zero.c
+++ b/daemon/zero.c
@@ -228,35 +228,6 @@ do_is_zero_device (const char *device)
return 1;
}
-static int
-random_name (char *p)
-{
- int fd;
- unsigned char c;
-
- fd = open ("/dev/urandom", O_RDONLY|O_CLOEXEC);
- if (fd == -1) {
- reply_with_perror ("/dev/urandom");
- return -1;
- }
-
- while (*p) {
- if (*p == 'X') {
- if (read (fd, &c, 1) != 1) {
- reply_with_perror ("read: /dev/urandom");
- close (fd);
- return -1;
- }
- *p = "0123456789abcdefghijklmnopqrstuvwxyz"[c % 36];
- }
-
- p++;
- }
-
- close (fd);
- return 0;
-}
-
/* Current implementation is to create a file of all zeroes, then
* delete it. The description of this function is left open in order
* to allow better implementations in future, including
@@ -277,8 +248,10 @@ do_zero_free_space (const char *dir)
* compatible with any filesystem type inc. FAT.
*/
snprintf (filename, sysroot_len+len+14, "%s%s/XXXXXXXX.XXX", sysroot, dir);
- if (random_name (&filename[sysroot_len+len]) == -1)
+ if (random_name (filename) == -1) {
+ reply_with_perror ("random_name");
return -1;
+ }
if (verbose)
printf ("random filename: %s\n", filename);