summaryrefslogtreecommitdiff
path: root/downtimedb.c
diff options
context:
space:
mode:
Diffstat (limited to 'downtimedb.c')
-rw-r--r--downtimedb.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/downtimedb.c b/downtimedb.c
new file mode 100644
index 0000000..007f5be
--- /dev/null
+++ b/downtimedb.c
@@ -0,0 +1,191 @@
+/*-
+ * Copyright (c) 2009-2013 EPIPE Communications. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are
+ * those of the authors and should not be interpreted as representing official
+ * policies, either expressed or implied, of EPIPE Communications.
+ *
+ *
+ * Software web site:
+ * http://dist.epipe.com/downtimed/
+ *
+ * Author contact information:
+ * opensource@epipe.com
+ */
+
+/* Include config.h in case we use autoconf. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <inttypes.h>
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "downtimedb.h"
+
+/*
+ * Swap bytes of uint64_t.
+ *
+ * We used to be trying to use htobe64() and be64toh().
+ * Or htobe64() and betoh64().
+ * Or OSSwapHostToBigInt64() and OSSwapBigToHostInt64().
+ *
+ * But the reality is that due to lack of standardization this became
+ * just a big mess as there is no portable function to do this. Some
+ * systems (for example RHEL/CentOS 5.5) lack the corresponding functions
+ * altogether.
+ *
+ * Therefore we ignore whatever is available and just define our own
+ * MY_BSWAP64() macro which is used on little endian architectures.
+ *
+ * The implementation is stolen from crypt-sha512.c released into the
+ * Public Domain by Ulrich Drepper <drepper@redhat.com>.
+ */
+
+#ifndef WORDS_BIGENDIAN
+#define MY_BSWAP64(n) \
+ (((n) << 56) \
+ | (((n) & 0xff00) << 40) \
+ | (((n) & 0xff0000) << 24) \
+ | (((n) & 0xff000000) << 8) \
+ | (((n) >> 8) & 0xff000000) \
+ | (((n) >> 24) & 0xff0000) \
+ | (((n) >> 40) & 0xff00) \
+ | ((n) >> 56))
+#endif
+
+/*
+ * Functions for reading from and writing to the downtime database.
+ */
+
+int
+downtimedb_read(int fd, struct downtimedb *buf)
+{
+ int ret;
+
+ errno = 0;
+ if ((ret = read(fd, (void *)buf, sizeof(struct downtimedb)))
+ < sizeof(struct downtimedb)) {
+ if (ret == 0)
+ return (0); /* eof */
+ else {
+ if (ret != -1) {
+ /* set errno when it is not a read error */
+ errno = EILSEQ;
+ }
+ return (-1); /* some sort of error */
+ }
+ }
+
+#ifndef WORDS_BIGENDIAN
+ buf->when = (int64_t) MY_BSWAP64((uint64_t) buf->when);
+#endif
+
+ return (1); /* 1 record read */
+}
+
+/* The write function modifies the buffer on the fly to match
+ * the endianness required in the database. Thus, the supplied
+ * struct downtimedb will be invalid after calling this function.
+ */
+
+int
+downtimedb_write(int fd, struct downtimedb *buf)
+{
+#ifndef WORDS_BIGENDIAN
+ buf->when = (int64_t) MY_BSWAP64((uint64_t) buf->when);
+#endif
+
+ errno = 0;
+ if (write(fd, (void *)buf, sizeof(struct downtimedb))
+ < sizeof(struct downtimedb))
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * Return time string of absolute time in static buffer.
+ * Certainly not thread-safe.
+ */
+
+char *
+timestr_abs(time_t t, const char *fmt, int utc)
+{
+ static char str[256];
+ struct tm *lt;
+
+ if (t != 0) {
+ if ((lt = (utc ? gmtime(&t) : localtime(&t))) == NULL)
+ goto err;
+ if (strftime(str, sizeof(str), fmt, lt) == 0)
+ goto err;
+
+ return (str);
+ }
+err:
+ /* we have the backslashes here to avoid interpretation as trigraphs */
+ return ("?\?\?\?-?\?-?\? ?\?:?\?:?\?");
+}
+
+/*
+ * Stolen from top.c. Return time interval in human-readable (?) static
+ * string. Definitely not thread-safe.
+ */
+
+char *
+timestr_int(time_t t)
+{
+ int days, hrs, mins, secs;
+ static char str[100];
+
+ days = t / 86400;
+ t %= 86400;
+ hrs = t / 3600;
+ t %= 3600;
+ mins = t / 60;
+ secs = t % 60;
+
+ if (days > 0)
+ snprintf(str, sizeof(str), "%d+%02d:%02d:%02d",
+ days, hrs, mins, secs);
+ else
+ snprintf(str, sizeof(str), "%02d:%02d:%02d",
+ hrs, mins, secs);
+
+ return (str);
+}
+
+/* eof */