| git.druid.rocks | index | druid520 | q | src/ | q.h |
src/q.h
#ifndef Q_H
#define Q_H
#include <stdio.h>
#include <sys/types.h>
/* generously sized rather than exactly right-sized: static storage, not
* stack, so the cost of headroom is a few kb of bss, not a real
* constraint -- and getting a size limit wrong fails loudly (readfile's
* truncation detection, snap_add's overflow die) rather than silently
* corrupting data. */
#define MAXFILE (1024L * 1024L)
#define MAXKV 256
#define MAXKEY 32
#define MAXVAL 512
#define MAXPATH 1024
#define MAXSNAP (4L * 1024L * 1024L)
#define MAXPATHS 131072
struct kv
{
char key[MAXKEY];
char val[MAXVAL];
};
/* resolved runtime config: the config file's path plus the four values q
* derives from it (see conf.c's loadcfg). */
struct qcfg
{
char conf[MAXPATH];
char prefix[MAXPATH];
char db[MAXPATH];
char shell[MAXPATH];
char pkgs[MAXPATH];
};
/* one in-memory snapshot of every path under a prefix. q captures two
* (before/after an install) and diffs them to learn which files that
* install added. malloc'd, not static, so the several mb exist only
* while a command holds the snapshot, not as permanent bss. */
struct snap
{
char* buf; /* paths, nul-terminated and contiguous */
long cap; /* allocated bytes in buf */
long len; /* bytes used in buf */
long* idx; /* offset of each path in buf */
long icap; /* allocated entries in idx */
long n; /* number of paths */
};
/* util.c -- base helpers the rest of q depends on. die() always exit()s,
* but q stays pure c89 (no __attribute__((noreturn)), a gnu/clang
* extension) -- so every call site adds its own explicit "return;"
* immediately after die() to close the fall-through path off in plain,
* portable c89. */
void die(const char* msg);
long readfile(const char* path, char* buf, long max);
long writefile(const char* path, const char* buf, long n);
long bufcat(char* dst, size_t max, size_t* off, const char* str);
long pathjoin(char* dst, size_t max, const char* a, const char* b);
long pathfits(const char* a, const char* b);
long copystr(char* dst, size_t max, const char* src);
/* conf.c -- config resolution and recipe-metadata parsing. */
long parseconf(const char* buf, long n, struct kv* kv, long max);
const char* kvget(struct kv* kv, long nkv, const char* key);
void loadcfg(struct qcfg* c);
/* runsh.c -- run one recipe's command via "shell -e recipe cmd", with
* /etc/q.cfg sourced first and Q_PREFIX/Q_DB/Q_PKGS exported; 0 on
* success, 1 on failure. */
int runrecipe(const struct qcfg* c, const char* recipe, const char* cmd);
/* fstree.c -- filesystem-tree operations: walk a prefix into a snapshot
* (presence only, no type/mtime bookkeeping), plus recursive remove and
* mkdir -p. */
void walktree(struct snap* s, const char* base, const char* rel);
void rmtree(const char* path);
void makedirs(const char* path);
/* snap.c -- snapshot collection, sorting, lookup, and manifest io. */
void snap_init(struct snap* s);
void snap_add(struct snap* s, const char* rel);
void snap_sort(struct snap* s);
long snap_has(const struct snap* s, const char* rel);
const char* snap_path(const struct snap* s, long i);
long snap_readfile(struct snap* s, const char* path);
void snap_writefile(const struct snap* s, const char* path);
void snap_free(struct snap* s);
/* the manifest a package owns after an install/update: every path now
* present that either was already owned (still there) or appeared during
* the operation (in after, not before). old must be sorted. */
void manifest_diff(const struct snap* before, const struct snap* after,
const struct snap* old, struct snap* out);
/* db.c -- the installed-package database: <db>/<pkg>/{name,ver,manifest}. */
void db_pkgdir(const char* db, const char* pkg, char* out, size_t max);
long db_has(const char* db, const char* pkg);
void db_install(const char* db, const char* pkg, const char* name,
const char* ver, const struct snap* manifest);
void db_remove(const char* db, const char* pkg);
long db_list(const char* db, struct kv* out, long max);
/* q.c -- cli plumbing. */
void badusage(const char* prog, const char* syntax);
#endif