summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorLibravatar bigfoot547 <bigfoot@figboot.dev>2026-01-16 16:54:39 -0600
committerLibravatar bigfoot547 <bigfoot@figboot.dev>2026-01-16 16:54:39 -0600
commit0566f0804b7e48a1070d0d3a5d0f6817b4003a05 (patch)
tree4a24ec6f813cde96295b981ba3f6e44a6c40b8c7 /include
parentdownload jobs (diff)
move include directory
Diffstat (limited to 'include')
-rw-r--r--include/arena.h28
-rw-r--r--include/log.h59
-rw-r--r--include/net.h93
-rw-r--r--include/sha1.h42
-rw-r--r--include/util.h8
-rw-r--r--include/vector.h27
6 files changed, 257 insertions, 0 deletions
diff --git a/include/arena.h b/include/arena.h
new file mode 100644
index 0000000..fa1674b
--- /dev/null
+++ b/include/arena.h
@@ -0,0 +1,28 @@
+#ifndef VL_ARENA_H_INCLUDED
+#define VL_ARENA_H_INCLUDED
+
+/* implements a basic arena allocator */
+
+#include <stddef.h>
+#include <stdarg.h>
+
+typedef struct vl__arena_tag vl_arena;
+
+/* returns NULL if an arena could not be allocated */
+vl_arena *vl_arena_new(size_t cap);
+
+/* aborts if the arena is overflowing */
+void *vl_arena_push(vl_arena *parena, size_t len);
+
+/* resets the arena (but does not free it) */
+void vl_arena_reset(vl_arena *parena);
+
+/* frees the arena */
+void vl_arena_free(vl_arena *parena);
+
+char *vl_arena_strdup(vl_arena *parena, const char *str);
+
+char *vl_arena_sprintf(vl_arena *parena, const char *fmt, ...);
+char *vl_arena_vsprintf(vl_arena *parena, const char *fmt, va_list ap);
+
+#endif /* include guard */
diff --git a/include/log.h b/include/log.h
new file mode 100644
index 0000000..1483559
--- /dev/null
+++ b/include/log.h
@@ -0,0 +1,59 @@
+#ifndef VL_LOG_H_INCLUDED
+#define VL_LOG_H_INCLUDED
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#define LOG_TRACE 0u
+#define LOG_DEBUG 1u
+#define LOG_INFO 2u
+#define LOG_WARN 3u
+#define LOG_ERROR 4u
+
+/* Log functions MUST leave errno untouched */
+
+void vl_log_setlevel(unsigned level);
+
+void vl_logv(unsigned level, const char *fmt, va_list args);
+void vl_log(unsigned level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
+
+#ifndef LOG_MIN_LEVEL
+#define LOG_MIN_LEVEL LOG_TRACE
+#endif
+
+#if LOG_TRACE >= LOG_MIN_LEVEL
+#define LOG_TRACE_ENABLED
+#define vl_trace(...) vl_log(LOG_TRACE, __VA_ARGS__)
+#define vl_tracev(...) vl_logv(LOG_TRACE, __VA_ARGS__)
+#else
+#define vl_trace(...)
+#define vl_tracev(...)
+#endif
+
+#if LOG_DEBUG >= LOG_MIN_LEVEL
+#define LOG_DEBUG_ENABLED
+#define vl_debug(...) vl_log(LOG_DEBUG, __VA_ARGS__)
+#define vl_debugv(...) vl_logv(LOG_DEBUG, __VA_ARGS__)
+#else
+#define vl_debug(...)
+#define vl_debugv(...)
+#endif
+
+#if LOG_INFO >= LOG_MIN_LEVEL
+#define LOG_INFO_ENABLED
+#define vl_info(...) vl_log(LOG_INFO, __VA_ARGS__)
+#define vl_infov(...) vl_logv(LOG_INFO, __VA_ARGS__)
+#else
+#define vl_info(...)
+#define vl_infov(...)
+#endif
+
+#define LOG_WARN_ENABLED
+#define vl_warn(...) vl_log(LOG_WARN, __VA_ARGS__)
+#define vl_warnv(...) vl_logv(LOG_WARN, __VA_ARGS__)
+
+#define LOG_ERROR_ENABLED
+#define vl_error(...) vl_log(LOG_ERROR, __VA_ARGS__)
+#define vl_errorv(...) vl_logv(LOG_ERROR, __VA_ARGS__)
+
+#endif
diff --git a/include/net.h b/include/net.h
new file mode 100644
index 0000000..610ed77
--- /dev/null
+++ b/include/net.h
@@ -0,0 +1,93 @@
+#ifndef VL_NET_H_INCLUDED
+#define VL_NET_H_INCLUDED
+
+#include "arena.h"
+#include "sha1.h"
+
+enum {
+ /* The operation completed successfully */
+ NET_OK = 0,
+
+ /* There was some kind of error relating to I/O on the local system */
+ NET_EIO = -1,
+
+ /* There was some kind of network error downloading the file. */
+ NET_ENETWORK = -2,
+
+ /* The server gave us a bad status code while downloading the file. */
+ NET_ESTATUS = -3,
+
+ /* An unrecoverable integrity error occurred. */
+ NET_EINTEGRITY = -4,
+
+ /* An unspecified error occurred. */
+ NET_EUNSPEC = -5,
+
+ /* An unspecified (remote) error occurred. */
+ NET_EREMOTEUNSPEC = -6
+};
+
+enum {
+ VERIFY_SIZE = 1u,
+ VERIFY_SHA1 = 2u
+};
+
+/* Ensures the latest version of the file available at 'url' is downloaded to 'target_path'.
+ * Will avoid downloading the file if it hasn't changed.
+ *
+ * Never returns NET_EINTEGRITY. */
+int vl_net_ensure_cached(vl_arena *scratch, const char *url, const char *target_path);
+
+/* Will verify that the file at 'target_path' hasn't been tampered with since being updated
+ * by vl_net_ensure_cached.
+ *
+ * Returns NET_EIO if the file doesn't exist or couldn't be read.
+ * Returns NET_EINTEGRITY if the file on disk doesn't match. */
+int vl_net_verify_cached(vl_arena *scratch, const char *target_path);
+
+/* Downloads a file for which you know the integrity information (SHA1 and/or size) from 'url' to
+ * 'target_path'. Will not download the file if the file already exists with correct SHA1 and size
+ * (as specified).
+ *
+ * Pass variadic arguments in the following order:
+ * - size_t size (if VERIFY_SIZE is set)
+ * - const uint8_t *hash (if VERIFY_SHA1 is set)
+ *
+ * Returns NET_EINTEGRITY if the file at 'url' doesn't match the provided integrity information. */
+int vl_net_ensure_verified(const char *url, const char *target_path, unsigned flags, ...);
+
+/* See vl_net_ensure_verified for information on the variadic argument list.
+ *
+ * Returns NET_EINTEGRITY if the file at 'target_path' doesn't match the provided integrity information.
+ * Returns NET_EIO if the downloaded file is not readable or could not be verified due to an I/O issue. */
+int vl_net_verify(const char *target_path, unsigned flags, ...);
+
+enum {
+ /* The job hasn't been started yet. */
+ STATUS_WAITING = 0u,
+
+ /* The job is in flight. */
+ STATUS_RUNNING = 1u,
+
+ /* The job is finished without errors. */
+ STATUS_COMPLETE = 2u,
+
+ /* The job is finished with errors. */
+ STATUS_ERROR = 3u,
+
+ /* The job finished successfully, but the downloaded file failed integrity checks. */
+ STATUS_INTEGRITY = 4u
+};
+
+struct vl_download_job {
+ const char *url;
+ const char *opath;
+ size_t expect_len;
+ vl_sha1 expect_hash;
+ unsigned verify_flags;
+ unsigned status;
+};
+
+int vl_net_download_all(struct vl_download_job *jobs, size_t njobs, size_t simult);
+
+#endif
diff --git a/include/sha1.h b/include/sha1.h
new file mode 100644
index 0000000..05cedd4
--- /dev/null
+++ b/include/sha1.h
@@ -0,0 +1,42 @@
+#ifndef VL_SHA1_H_INCLUDED
+#define VL_SHA1_H_INCLUDED
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define VL_SHA1_STATELEN_32 ( 5u) /* 160 bits / 32 (bits per int) = 5 ints */
+#define VL_SHA1_CHUNKLEN_BYTES (64u) /* 512 bits / 8 (bits per byte) = 64 bytes */
+
+#define VL_SHA1_DIGEST_BYTES (20u)
+#define VL_SHA1_DIGEST_HEX_STRLEN (VL_SHA1_DIGEST_BYTES << 1)
+
+typedef struct {
+ /* struct fields are internal (struct size is ABI doe) */
+ size_t vl_nchunk;
+ uint64_t vl_total;
+ uint32_t vl_state[VL_SHA1_STATELEN_32];
+ uint8_t vl_chunk[VL_SHA1_CHUNKLEN_BYTES];
+} vl_sha1_st;
+
+typedef uint8_t vl_sha1[VL_SHA1_DIGEST_BYTES];
+
+/* initializes a SHA1 state struct */
+void vl_sha1_init(vl_sha1_st *st);
+
+/* updates a SHA1 state struct with new data (must have been initialized with vl_sha1_init first) */
+void vl_sha1_update(vl_sha1_st *st, const void *data, size_t sz);
+
+/* finalizes a SHA1 state struct, writing the final digest to the second argument. the state struct
+ * is now invalid, and vl_sha1_init must be used on it again before it can be reused. */
+void vl_sha1_finalize(vl_sha1_st *st, vl_sha1 out);
+
+/* shortcut for hashing a buffer */
+void vl_sha1_buffer(vl_sha1 odigest, const void *data, size_t sz);
+
+/* converts digest bytes to a hex string (does NOT place a NUL byte) */
+void vl_sha1_encode(const vl_sha1 dig, char hex[VL_SHA1_DIGEST_HEX_STRLEN]);
+
+/* converts a hex string to digest bytes */
+int vl_sha1_decode(vl_sha1 odigest, const char hex[VL_SHA1_DIGEST_HEX_STRLEN]);
+
+#endif /* include guard */
diff --git a/include/util.h b/include/util.h
new file mode 100644
index 0000000..5ef3c8b
--- /dev/null
+++ b/include/util.h
@@ -0,0 +1,8 @@
+#ifndef VL_UTIL_H_INCLUDED
+#define VL_UTIL_H_INCLUDED
+
+#include <sys/stat.h>
+
+int vl_mkdir_parents(int fd, char *path, mode_t mode);
+
+#endif
diff --git a/include/vector.h b/include/vector.h
new file mode 100644
index 0000000..02ed84e
--- /dev/null
+++ b/include/vector.h
@@ -0,0 +1,27 @@
+#ifndef VL_VECTOR_H_INCLUDED
+#define VL_VECTOR_H_INCLUDED
+
+#include <stddef.h>
+
+/* implements a vector type (array of same-sized values) */
+
+typedef struct vl__vector_tag vl_vector;
+
+vl_vector *vl_vector_new(size_t sz);
+vl_vector *vl_vector_new_ex(size_t sz, size_t init_cap);
+void vl_vector_free(vl_vector *vec);
+
+/* will abort if realloc fails to shrink the allocation (should never happen) */
+void vl_vector_shrink_to_size(vl_vector *vec);
+
+#define vl_newvec(_t) vl_vector_new(sizeof(_t))
+#define vl_newvec_ex(_t, _ic) vl_vector_new_ex(sizeof(_t), _ic)
+
+int vl_vector_push(vl_vector *vec, void *data);
+int vl_vector_push_vec(vl_vector *vec, void *data, size_t n);
+int vl_vector_push_2d(vl_vector *vec, void **data, size_t n);
+
+size_t vl_vector_size(const vl_vector *vec);
+void *vl_vector_values(const vl_vector *vec, size_t *psz);
+
+#endif