daemon: Move useful is_zero function to header file.
[libguestfs.git] / daemon / daemon.h
index 4a686c0..b4f99a8 100644 (file)
@@ -1,5 +1,5 @@
 /* libguestfs - the guestfsd daemon
- * Copyright (C) 2009 Red Hat Inc.
+ * Copyright (C) 2009-2011 Red Hat Inc.
  *
  * 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
@@ -36,7 +36,7 @@ extern int verbose;
 extern int autosync_umount;
 
 extern const char *sysroot;
-extern int sysroot_len;
+extern size_t sysroot_len;
 
 extern char *sysroot_path (const char *path);
 
@@ -128,6 +128,9 @@ extern struct optgroup optgroups[];
 /* Use this as a replacement for sync(2). */
 extern int sync_disks (void);
 
+/*-- in ext2.c --*/
+extern int e2prog (char *name); /* Massive hack for RHEL 5. */
+
 /*-- in lvm.c --*/
 extern int lv_canonical (const char *device, char **ret);
 
@@ -152,10 +155,6 @@ extern int receive_file (receive_cb cb, void *opaque);
 
 /* daemon functions that receive files (FileIn) can call this
  * to cancel incoming transfers (eg. if there is a local error).
- *
- * If and only if this function does NOT return -2, they MUST then
- * call reply_with_*
- * (see https://bugzilla.redhat.com/show_bug.cgi?id=576879#c5).
  */
 extern int cancel_receive (void);
 
@@ -175,14 +174,49 @@ extern void reply (xdrproc_t xdrp, char *ret);
  */
 extern void notify_progress (uint64_t position, uint64_t total);
 
+/* Pulse mode progress messages.
+ *
+ * Call pulse_mode_start to start sending progress messages.
+ *
+ * Call pulse_mode_end along the ordinary exit path (ie. before a
+ * reply message is sent).
+ *
+ * Call pulse_mode_cancel along all error paths *before* any reply is
+ * sent.  pulse_mode_cancel does not modify errno, so it is safe to
+ * call it before reply_with_perror.
+ *
+ * Pulse mode and ordinary notify_progress must not be mixed.
+ */
+extern void pulse_mode_start (void);
+extern void pulse_mode_end (void);
+extern void pulse_mode_cancel (void);
+
+/* Return true iff the buffer is all zero bytes.
+ *
+ * Note that gcc is smart enough to optimize this properly:
+ * http://stackoverflow.com/questions/1493936/faster-means-of-checking-for-an-empty-buffer-in-c/1493989#1493989
+ */
+static inline int
+is_zero (const char *buffer, size_t size)
+{
+  size_t i;
+
+  for (i = 0; i < size; ++i) {
+    if (buffer[i] != 0)
+      return 0;
+  }
+
+  return 1;
+}
+
 /* Helper for functions that need a root filesystem mounted.
  * NB. Cannot be used for FileIn functions.
  */
 #define NEED_ROOT(cancel_stmt,fail_stmt)                                \
   do {                                                                 \
     if (!is_root_mounted ()) {                                         \
-      if ((cancel_stmt) != -2)                                          \
-        reply_with_error ("%s: you must call 'mount' first to mount the root filesystem", __func__); \
+      cancel_stmt;                                                      \
+      reply_with_error ("%s: you must call 'mount' first to mount the root filesystem", __func__); \
       fail_stmt;                                                       \
     }                                                                  \
   }                                                                    \
@@ -194,8 +228,8 @@ extern void notify_progress (uint64_t position, uint64_t total);
 #define ABS_PATH(path,cancel_stmt,fail_stmt)                            \
   do {                                                                 \
     if ((path)[0] != '/') {                                            \
-      if ((cancel_stmt) != -2)                                          \
-        reply_with_error ("%s: path must start with a / character", __func__); \
+      cancel_stmt;                                                      \
+      reply_with_error ("%s: path must start with a / character", __func__); \
       fail_stmt;                                                       \
     }                                                                  \
   } while (0)
@@ -210,18 +244,17 @@ extern void notify_progress (uint64_t position, uint64_t total);
 #define RESOLVE_DEVICE(path,cancel_stmt,fail_stmt)                      \
   do {                                                                 \
     if (STRNEQLEN ((path), "/dev/", 5)) {                              \
-      if ((cancel_stmt) != -2)                                          \
-        reply_with_error ("%s: %s: expecting a device name", __func__, (path)); \
+      cancel_stmt;                                                      \
+      reply_with_error ("%s: %s: expecting a device name", __func__, (path)); \
       fail_stmt;                                                       \
     }                                                                  \
     if (is_root_device (path))                                          \
       reply_with_error ("%s: %s: device not found", __func__, path);    \
     if (device_name_translation ((path)) == -1) {                       \
       int err = errno;                                                  \
-      int r = cancel_stmt;                                              \
+      cancel_stmt;                                                      \
       errno = err;                                                      \
-      if (r != -2)                                                      \
-        reply_with_perror ("%s: %s", __func__, path);                   \
+      reply_with_perror ("%s: %s", __func__, path);                     \
       fail_stmt;                                                       \
     }                                                                   \
   } while (0)