diff --git a/src/clipserve.c b/src/clipserve.c index 43cbf7f..52d4158 100644 --- a/src/clipserve.c +++ b/src/clipserve.c @@ -149,7 +149,7 @@ static void _nonnull_ serve_clipboard(uint64_t hash, _drop_(XFree) char *window_title = get_window_title(dpy, req->requestor); - dbg("Servicing request to window '%s' (0x%lx) for clip %" PRIu64 + dbg("Servicing request to window '%s' (0x%lX) for clip " PRI_HASH "\n", strnull(window_title), (unsigned long)req->requestor, hash); @@ -180,10 +180,10 @@ static void _nonnull_ serve_clipboard(uint64_t hash, } case SelectionClear: { if (--remaining_selections == 0) { - dbg("Finished serving clip %" PRIu64 "\n", hash); + dbg("Finished serving clip " PRI_HASH "\n", hash); running = false; } else { - dbg("%d selections remaining to serve for clip %" PRIu64 + dbg("%d selections remaining to serve for clip " PRI_HASH "\n", remaining_selections, hash); } @@ -204,7 +204,7 @@ int main(int argc, char *argv[]) { _drop_(config_free) struct config cfg = setup("clipserve"); uint64_t hash; - expect(str_to_uint64(argv[1], &hash) == 0); + expect(str_to_hex64(argv[1], &hash) == 0); _drop_(close) int content_dir_fd = open(get_cache_dir(&cfg), O_RDONLY); _drop_(close) int snip_fd = @@ -216,7 +216,7 @@ int main(int argc, char *argv[]) { _drop_(cs_content_unmap) struct cs_content content; die_on(cs_content_get(&cs, hash, &content) < 0, - "Hash %" PRIu64 " inaccessible\n", hash); + "Hash " PRI_HASH " inaccessible\n", hash); serve_clipboard(hash, &content); diff --git a/src/store.c b/src/store.c index 867fc9f..17255b5 100644 --- a/src/store.c +++ b/src/store.c @@ -408,7 +408,7 @@ static int _must_use_ _nonnull_ cs_content_add(struct clip_store *cs, bool dupe = false; char dir_path[CS_HASH_STR_MAX]; - snprintf(dir_path, sizeof(dir_path), "%" PRIu64, hash); + snprintf(dir_path, sizeof(dir_path), PRI_HASH, hash); int ret = mkdirat(cs->content_dir_fd, dir_path, 0700); if (ret < 0) { @@ -501,7 +501,7 @@ int cs_content_get(struct clip_store *cs, uint64_t hash, memset(content, '\0', sizeof(struct cs_content)); char filename[PATH_MAX]; - snprintf(filename, sizeof(filename), "%" PRIu64 "/1", hash); + snprintf(filename, sizeof(filename), PRI_HASH "/1", hash); _drop_(close) int fd = openat(cs->content_dir_fd, filename, O_RDONLY); if (fd < 0) { @@ -591,7 +591,7 @@ static int _must_use_ _nonnull_ cs_content_remove(struct clip_store *cs, uint64_t hash) { char hash_dir_name[CS_HASH_STR_MAX]; - snprintf(hash_dir_name, sizeof(hash_dir_name), "%" PRIu64, hash); + snprintf(hash_dir_name, sizeof(hash_dir_name), PRI_HASH, hash); _drop_(close) int hash_dir_fd = openat(cs->content_dir_fd, hash_dir_name, O_RDONLY); diff --git a/src/store.h b/src/store.h index a1bbfaf..650cc8b 100644 --- a/src/store.h +++ b/src/store.h @@ -9,7 +9,8 @@ #define CS_SNIP_SIZE 256 /* The size of each struct cs_snip */ #define CS_SNIP_ALLOC_BATCH 1024 /* How many snips to allocate when growing */ -#define CS_HASH_STR_MAX 21 /* String length of (1 << 64) - 1) + \0 */ +#define CS_HASH_STR_MAX 17 /* String length of 64bit hex + \0 */ +#define PRI_HASH "%016" PRIX64 /** * A single snip within the clip store. diff --git a/src/util.c b/src/util.c index 2beaa0e..3ba67ad 100644 --- a/src/util.c +++ b/src/util.c @@ -3,6 +3,7 @@ #include #include +#include "store.h" #include "util.h" /** @@ -54,8 +55,8 @@ size_t snprintf_safe(char *buf, size_t len, const char *fmt, ...) { * Runs clipserve to handle selection requests for a hash in the clip store. */ void run_clipserve(uint64_t hash) { - char hash_str[UINT64_MAX_STRLEN + 1]; - uint64_to_str(hash, hash_str); + char hash_str[CS_HASH_STR_MAX]; + snprintf(hash_str, sizeof(hash_str), PRI_HASH, hash); const char *const cmd[] = {"clipserve", hash_str, NULL}; pid_t pid = fork(); @@ -81,14 +82,14 @@ void run_clipserve(uint64_t hash) { int negative_errno(void) { return errno > 0 ? -errno : -EINVAL; } /** - * Convert a string to an unsigned 64-bit integer, validating the format and - * range of the input. + * Convert a string to an unsigned 64-bit integer in given base, validating the + * format and range of the input. */ -int str_to_uint64(const char *input, uint64_t *output) { +static int str_to_uint64_base(const char *input, uint64_t *output, int base) { char *endptr; errno = 0; - uint64_t val = strtoull(input, &endptr, 10); + uint64_t val = strtoull(input, &endptr, base); if (errno > 0) { return negative_errno(); } @@ -104,10 +105,19 @@ int str_to_uint64(const char *input, uint64_t *output) { } /** - * Convert an unsigned 64-bit integer to a string representation. + * Convert a string to an unsigned 64-bit integer, validating the format and + * range of the input. + */ +int str_to_uint64(const char *input, uint64_t *output) { + return str_to_uint64_base(input, output, 10); +} + +/** + * Convert a hex string to an unsigned 64-bit integer, validating the format + * and range of the input. */ -void uint64_to_str(uint64_t input, char *output) { - snprintf_safe(output, UINT64_MAX_STRLEN + 1, "%" PRIu64, input); +int str_to_hex64(const char *input, uint64_t *output) { + return str_to_uint64_base(input, output, 16); } /** diff --git a/src/util.h b/src/util.h index 10101aa..be1fe74 100644 --- a/src/util.h +++ b/src/util.h @@ -100,7 +100,7 @@ DEFINE_DROP_FUNC(DIR *, closedir) int _must_use_ negative_errno(void); int _nonnull_ str_to_uint64(const char *input, uint64_t *output); -void _nonnull_ uint64_to_str(uint64_t input, char *output); +int _nonnull_ str_to_hex64(const char *input, uint64_t *output); bool debug_mode_enabled(void); #endif