diff -Naur a/src/utils.c b/src/utils.c
--- a/src/utils.c	2019-10-21 02:08:47.000000000 +0600
+++ b/src/utils.c	2024-06-28 11:13:17.092091027 +0600
@@ -161,3 +161,48 @@
     }
     return 0;
 }
+
+#if !(defined(HAVE_ASPRINTF) && HAVE_ASPRINTF)
+int
+asprintf(char **strp, const char *fmt, ...)
+{
+    int ret;
+    va_list ap;
+    va_start(ap, fmt);
+    ret = vasprintf(strp, fmt, ap);
+    va_end(ap);
+    return ret;
+}
+
+# if !(defined(HAVE_VASPRINTF) && HAVE_VASPRINTF)
+int
+vasprintf(char **strp, const char *fmt, va_list ap)
+{
+    int ret;
+    char *buf;
+    va_list ap_copy;
+
+    /*
+     * The value of the va_list parameter is undefined after the call to
+     * vsnprintf() returns: pass a copy to make sure "ap" remains valid.
+     */
+    va_copy(ap_copy, ap);
+    ret = vsnprintf(NULL, 0, fmt, ap_copy);
+    va_end(ap_copy);
+
+    if (ret < 0)
+        return ret;
+
+    if (!(buf = malloc(ret + 1)))
+        return -1;
+
+    if ((ret = vsnprintf(buf, ret + 1, fmt, ap)) < 0) {
+        free(buf);
+        return ret;
+    }
+
+    *strp = buf;
+    return ret;
+}
+# endif /* !HAVE_VASPRINTF */
+#endif /* !HAVE_ASPRINTF */
diff -Naur a/src/utils.h b/src/utils.h
--- a/src/utils.h	2019-10-21 02:08:47.000000000 +0600
+++ b/src/utils.h	2024-06-28 11:12:29.634354358 +0600
@@ -186,6 +186,29 @@
     return pos;
 }
 
+static inline bool
+streq_null(const char *s1, const char *s2)
+{
+    if (s1 == NULL || s2 == NULL)
+        return s1 == s2;
+    return streq(s1, s2);
+}
+
+
+static inline bool
+check_eaccess(const char *path, int mode)
+{
+    #if defined(HAVE_EACCESS)
+    if (eaccess(path, mode) != 0)
+        return false;
+    #elif defined(HAVE_EUIDACCESS)
+    if (euidaccess(path, mode) != 0)
+        return false;
+    #endif
+
+    return true;
+}
+
 static inline int
 one_bit_set(uint32_t x)
 {
@@ -240,6 +263,28 @@
 # define ATTR_PRINTF(x,y)
 #endif
 
+#if !(defined(HAVE_ASPRINTF) && HAVE_ASPRINTF)
+int asprintf(char **strp, const char *fmt, ...) ATTR_PRINTF(2, 3);
+# if !(defined(HAVE_VASPRINTF) && HAVE_VASPRINTF)
+#  include <stdarg.h>
+int vasprintf(char **strp, const char *fmt, va_list ap);
+# endif /* !HAVE_VASPRINTF */
+#endif /* !HAVE_ASPRINTF */
+
+static inline bool
+ATTR_PRINTF(3, 4)
+snprintf_safe(char *buf, size_t sz, const char *format, ...)
+{
+    va_list ap;
+    int rc;
+
+    va_start(ap, format);
+    rc = vsnprintf(buf, sz, format, ap);
+    va_end(ap);
+
+    return rc >= 0 && (size_t)rc < sz;
+}
+
 #if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \
     || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590))
 # define ATTR_NORETURN __attribute__((__noreturn__))
