summary refs log tree commit diff
path: root/misc/subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc/subr.c')
-rw-r--r--misc/subr.c87
1 files changed, 86 insertions, 1 deletions
diff --git a/misc/subr.c b/misc/subr.c
index ffa5d46..3198189 100644
--- a/misc/subr.c
+++ b/misc/subr.c
@@ -31,6 +31,49 @@ has_bit(const uint8_t *bits, unsigned long index)
     return bits[index / 8] & (1 << (7 - index % 8));
 }
 
+uint8_t
+hex2i(char c)
+{
+    if (c >= '0' && c <= '9')
+        return c - '0';
+    else if (c >= 'a' && c <= 'f')
+        return 10 + c - 'a';
+    else
+        abort();
+}
+
+int
+ishex(char *str)
+{
+    while (*str != '\0') {
+        if (!((*str >= '0' && *str <= '9') || (*str >= 'a' && *str <= 'f')))
+            return 0;
+        str++;
+    }
+    return 1;
+}
+
+uint8_t *
+hex2bin(const char *hex, uint8_t *bin, size_t bsize)
+{
+    for (size_t i = 0; i < bsize; i++)
+        bin[i] = hex2i(hex[i * 2]) << 4 | hex2i(hex[i * 2 + 1]);
+    return bin;
+}
+
+char *
+bin2hex(const uint8_t *bin, char *hex, size_t bsize)
+{
+    size_t i;
+    const char *hexc = "0123456789abcdef";
+    for (i = 0; i < bsize; i++) {
+        hex[i * 2] = hexc[(bin[i] >> 4) & 0xf];
+        hex[i * 2 + 1] = hexc[bin[i] &0xf];
+    }
+    hex[i * 2] = '\0';
+    return hex;
+}
+
 int
 set_nonblocking(int fd)
 {
@@ -174,7 +217,7 @@ read_fully(int fd, void *buf, size_t len)
     while (off < len) {
         nread = read(fd, buf + off, len - off);
         if (nread == 0)
-            return ECONNRESET;
+            return EIO;
         else if (nread == -1)
             return errno;
         off += nread;
@@ -182,6 +225,48 @@ read_fully(int fd, void *buf, size_t len)
     return 0;
 }
 
+int
+read_whole_file(void **out, size_t *size, const char *fmt, ...)
+{
+    int err, fd;
+    int didmalloc = 0;
+    struct stat sb;
+    va_list ap;
+
+    va_start(ap, fmt);
+    err = vaopen(&fd, O_RDONLY, fmt, ap);
+    va_end(ap);
+    if (err != 0)
+        return err;
+    if (fstat(fd, &sb) != 0) {
+        err = errno;
+        goto error;
+    }
+    if (*size != 0 && *size < sb.st_size) {
+        err = EFBIG;
+        goto error;
+    }
+    *size = sb.st_size;
+    if (*out == NULL) {
+        if ((*out = malloc(*size)) == NULL) {
+            err = errno;
+            goto error;
+        }
+        didmalloc = 1;
+    }
+    if ((err = read_fully(fd, *out, *size)) != 0)
+        goto error;
+
+    close(fd);
+    return 0;
+
+error:
+    if (didmalloc)
+        free(*out);
+    close(fd);
+    return err;
+}
+
 char *
 find_btpd_dir(void)
 {