+/***** LOG functions *****/
+
+#define M_DEBUG_CONFIG 0x001
+#define M_DEBUG_PHASE 0x002
+#define M_DEBUG 0x004
+#define M_INFO 0x008
+#define M_NOTICE 0x010
+#define M_WARNING 0x020
+#define M_ERR 0x040
+#define M_SECURITY 0x080
+#define M_FATAL 0x100
+
+/* The fatal() family of functions require messages that do not end in '\n' */
+extern NORETURN(fatal(const char *message, ...)) FORMAT(printf,1,2);
+extern NORETURN(fatal_perror(const char *message, ...)) FORMAT(printf,1,2);
+extern NORETURN(fatal_status(int status, const char *message, ...))
+ FORMAT(printf,2,3);
+extern NORETURN(fatal_perror_status(int status, const char *message, ...))
+ FORMAT(printf,2,3);
+
+/* Convenient nonfatal logging. Requires message that does not end in '\n'.
+ * If class contains M_FATAL, exits (after entering PHASE_SHUTDOWN).
+ * lg, errnoval and loc may sensibly be 0. desc must NOT be 0.
+ * lg_[v]perror save and restore errno. */
+void lg_vperror(struct log_if *lg, const char *desc, struct cloc *loc,
+ int class, int errnoval, const char *fmt, va_list al)
+ FORMAT(printf,6,0);
+void lg_perror(struct log_if *lg, const char *desc, struct cloc *loc,
+ int class, int errnoval, const char *fmt, ...)
+ FORMAT(printf,6,7);
+void lg_exitstatus(struct log_if *lg, const char *desc, struct cloc *loc,
+ int class, int status, const char *progname);
+
+/* The cfgfatal() family of functions require messages that end in '\n' */
+extern NORETURN(cfgfatal(struct cloc loc, cstring_t facility,
+ const char *message, ...)) FORMAT(printf,3,4);
+extern void cfgfile_postreadcheck(struct cloc loc, FILE *f);
+extern NORETURN(vcfgfatal_maybefile(FILE *maybe_f, struct cloc loc,
+ cstring_t facility, const char *message,
+ va_list))
+ FORMAT(printf,4,0);
+extern NORETURN(cfgfatal_maybefile(FILE *maybe_f, struct cloc loc,
+ cstring_t facility,
+ const char *message, ...))
+ FORMAT(printf,4,5);
+
+extern void Message(uint32_t class, const char *message, ...)
+ FORMAT(printf,2,3);
+extern void log_from_fd(int fd, cstring_t prefix, struct log_if *log);
+
+/***** END of log functions *****/
+
+#define STRING2(x) #x
+#define STRING(x) STRING2(x)
+
+#define FILLZERO(obj) (memset(&(obj),0,sizeof((obj))))
+#define ARRAY_SIZE(ary) (sizeof((ary))/sizeof((ary)[0]))
+
+/*
+ * void COPY_OBJ( OBJECT& dst, const OBJECT& src);
+ * void COPY_ARRAY(OBJECT *dst, const OBJECT *src, INTEGER count);
+ * // Typesafe: we check that the type OBJECT is the same in both cases.
+ * // It is OK to use COPY_OBJ on an array object, provided it's
+ * // _actually_ the whole array object and not decayed into a
+ * // pointer (e.g. a formal parameter).
+ */
+#define COPY_OBJ(dst,src) \
+ (&(dst)==&(src), memcpy(&(dst),&(src),sizeof((dst))))
+#define COPY_ARRAY(dst,src,count) \
+ (&(dst)[0]==&(src)[0], memcpy((dst),(src),sizeof((dst)[0])*(count)))
+