From a27913a47d81b61ca176d927cd5d43e64c11def9 Mon Sep 17 00:00:00 2001 From: Richard Nyberg Date: Tue, 12 Sep 2006 08:55:53 +0000 Subject: [PATCH] Add functions for conversions between binary data and ascii hex. Add function for reading a whole file. Enable printf format checking for some functions. --- misc/subr.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++- misc/subr.h | 11 +++++++ 2 files changed, 97 insertions(+), 1 deletion(-) 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) { diff --git a/misc/subr.h b/misc/subr.h index 9260ed9..bf30433 100644 --- a/misc/subr.h +++ b/misc/subr.h @@ -5,14 +5,18 @@ #include #define min(x, y) ((x) <= (y) ? (x) : (y)) +#define SHAHEXSIZE 41 int set_nonblocking(int fd); int set_blocking(int fd); int mkdirs(char *path); +__attribute__((format (printf, 3, 0))) int vaopen(int *resfd, int flags, const char *fmt, va_list ap); +__attribute__((format (printf, 3, 4))) int vopen(int *resfd, int flags, const char *fmt, ...); +__attribute__((format (printf, 3, 4))) int vfopen(FILE **ret, const char *mode, const char *fmt, ...); int vfsync(const char *fmt, ...); @@ -20,10 +24,17 @@ void set_bit(uint8_t *bits, unsigned long index); int has_bit(const uint8_t *bits, unsigned long index); void clear_bit(uint8_t *bits, unsigned long index); +char *bin2hex(const uint8_t *bin, char *hex, size_t bsize); +uint8_t *hex2bin(const char *hex, uint8_t *bin, size_t bsize); +uint8_t hex2i(char c); +int ishex(char *str); + long rand_between(long min, long max); int read_fully(int fd, void *buf, size_t len); int write_fully(int fd, const void *buf, size_t len); +__attribute__((format (printf, 3, 4))) +int read_whole_file(void **out, size_t *size, const char *fmt, ...); char *find_btpd_dir(void);