package

simple and robust package manager
Log | Files | Refs | README

commit 0521e5ef966ebbf55c7cb0224c2e8981d4c352f3
Author: Josuah Demangeon <mail@josuah.net>
Date:   Tue,  1 Jan 2019 21:01:28 +0100

building up a library for dealing with package directories

Diffstat:
A.gitignore | 1+
AMakefile | 23+++++++++++++++++++++++
Abuffer.c | 177+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Abuffer.h | 40++++++++++++++++++++++++++++++++++++++++
Aenv.h | 10++++++++++
Afmt.c | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afmt.h | 20++++++++++++++++++++
Afs.c | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Afs.h | 8++++++++
Agenalloc.h | 22++++++++++++++++++++++
Alog.c | 74++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Alog.h | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amake-a | 4++++
Amake-bin | 2++
Amake-h | 47+++++++++++++++++++++++++++++++++++++++++++++++
Amake-man | 119+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amake-mk | 11+++++++++++
Amake-o | 2++
Amem.c | 15+++++++++++++++
Amem.h | 17+++++++++++++++++
Aopen.h | 12++++++++++++
Aopenreadclose.c | 29+++++++++++++++++++++++++++++
Aopenreadclose.h | 8++++++++
Apack-build | 0
Apack-build.c | 34++++++++++++++++++++++++++++++++++
Apack.c | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apack.h | 18++++++++++++++++++
Astr.c | 15+++++++++++++++
Astr.h | 18++++++++++++++++++
Astralloc.c | 95+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Astralloc.h | 38++++++++++++++++++++++++++++++++++++++
31 files changed, 1307 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1 @@ +*.o diff --git a/Makefile b/Makefile @@ -0,0 +1,23 @@ +.PHONY: all +all: pack-build + +.PHONY: clean +clean: + rm -f *.o leapsecs leapsecs.dat + +pack-build-o = pack-build.o pack.o buffer.o fmt.o fs.o log.o mem.o openreadclose.o str.o stralloc.o +pack-build: ${pack-build-o} + ./make-bin $@ ${pack-build-o} + +.c.o: + ./make-o $< + +buffer.o: buffer.c buffer.h mem.h stralloc.h +fmt.o: fmt.c fmt.h str.h +fs.o: fs.c fs.h mem.h open.h str.h stralloc.h +log.o: log.c buffer.h log.h +mem.o: mem.c mem.h +openreadclose.o: openreadclose.c stralloc.h open.h +pack.o: pack.c pack.h stralloc.h fs.h mem.h +str.o: str.c str.h +stralloc.o: stralloc.c mem.h fmt.h str.h stralloc.h diff --git a/buffer.c b/buffer.c @@ -0,0 +1,177 @@ +#include <errno.h> +#include <stdio.h> +#include <unistd.h> +#include "buffer.h" +#include "mem.h" +#include "stralloc.h" + +char buffer_0_buf[8192]; +static buffer buffer_0_x = BUFFER_INIT(read, 0, buffer_0_buf, sizeof buffer_0_buf); +buffer *buffer_0 = &buffer_0_x; + +char buffer_1_buf[8192]; +static buffer buffer_1_x = BUFFER_INIT(write, 1, buffer_1_buf, sizeof buffer_1_buf); +buffer *buffer_1 = &buffer_1_x; + +char buffer_2_buf[256]; +static buffer buffer_2_x = BUFFER_INIT(write, 2, buffer_2_buf, sizeof buffer_2_buf); +buffer *buffer_2 = &buffer_2_x; + +ssize_t +buffer_fill(buffer *b) +{ + ssize_t r; + + if (b->n < b->a) return 0; + if (b->p) return 0; // Eat your spinach first! + r = buffer_readall(b->op, b->fd, b->x, b->n); + if (r == -1) return -1; + b->p = b->n = r; + return r; +} + +ssize_t +buffer_flush(buffer *b) +{ + ssize_t w; + + w = buffer_writeall(b->op, b->fd, b->x, b->p); + if (w == -1) return -1; + b->p = 0; + return w; +} + +static size_t +buffer_getthis(buffer *b, char *buf, size_t len) +{ + if (len > b->p) len = b->p; + mem_copy(buf, b->x + (b->n - b->p), len); + b->p -= len; + return len; +} + +ssize_t +buffer_get(buffer *b, char *buf, size_t len) +{ + ssize_t r; + size_t n = 0; + + if (b->p > 0) { + n += r = buffer_getthis(b, buf, len); + len -= r; buf += r; + } + if (len == 0) return n; + if (len > b->n && b->n == b->a) { + n += r = buffer_readall(b->op, b->fd, buf + n, len); + if (r == -1) return -1; + } else { + r = buffer_fill(b); if (r == -1) return -1; + n += buffer_getthis(b, buf, len); + } + + return n; +} + +void +buffer_init(buffer *b, ssize_t (*op)(), int fd, char *s, size_t n) +{ + b->fd = fd; + b->op = op; + b->x = s; + b->a = b->n = n; + b->p = 0; +} + +int +buffer_put(buffer *b, const char *buf, size_t len) +{ + if (len > b->n - b->p) if (buffer_flush(b) == -1) return -1; + if (len > b->n) return buffer_write(b->op, b->fd, buf, len) < 0 ? -1 : 0; + mem_copy(b->x + b->p, buf, len); + b->p += len; + return 0; +} + +ssize_t +buffer_write(ssize_t (*op)(), int fd, char const *buf, size_t len) +{ + ssize_t w; + + while (1) { + w = op(fd, buf, len); + if (w > 0) break; + if (errno == EINTR) continue; + if (errno == EAGAIN) continue; + if (errno == EWOULDBLOCK) continue; + break; + } + return w; +} + +ssize_t +buffer_read(ssize_t (*op)(), int fd, char *buf, size_t len) +{ + ssize_t r; + + while (1) { + r = op(fd, buf, len); + if (r > 0) break; + if (errno == EINTR) continue; + if (errno == EAGAIN) continue; + if (errno == EWOULDBLOCK) continue; + break; + } + return r; +} + +ssize_t +buffer_writeall(ssize_t (*op)(), int fd, char const *buf, size_t len) +{ + ssize_t w = 0; + size_t n = 0; + + while (len > 0) { + w = buffer_write(op, fd, buf, len); + if (w == -1) return -1; + if (w == 0) break; + buf += w; len -= w; n += w; + } + return n; +} + +ssize_t +buffer_readall(ssize_t (*op)(), int fd, char *buf, size_t len) +{ + ssize_t r = 0; + size_t n = 0; + + while (len > 0) { + r = buffer_read(op, fd, buf, len); + if (r == -1) return -1; + if (r == 0) break; + buf += r; len -= r; n += r; + } + return n; +} + +size_t +buffer_gettoken(buffer *b, stralloc *sa, char x) +{ + ssize_t r; + size_t n = 0; + char c; + + while ((r = buffer_getc(b, &c)) > 0) { + stralloc_append(sa, c); + if (c == x) return n; + ++n; + } + return r; +} + +size_t +buffer_putc(buffer *b, char c) +{ + return buffer_put(b, &c, 1); +} + diff --git a/buffer.h b/buffer.h @@ -0,0 +1,40 @@ +#ifndef BUFFER_H +#define BUFFER_H + +#include <stddef.h> +#include <unistd.h> +#include "stralloc.h" +#include "str.h" + +typedef struct { + char *x; + size_t a; // allocated size + size_t n; // used size, (n != a) means end of feed + size_t p; // amount of data held in + int fd; + ssize_t (*op)(); +} buffer; + +#define BUFFER_INIT(op, fd, x, n) { (x), (n), (n), (0), (fd), (op) } + +extern buffer *buffer_0; +extern buffer *buffer_1; +extern buffer *buffer_2; + +#define buffer_puts(b, s) buffer_put(b, s, str_len(s)) +#define buffer_getc(b, p) buffer_get(b, p, 1) +#define buffer_getline(b, sa) buffer_gettoken(b, sa, '\n') + +int buffer_put(buffer *, const char *, size_t); +size_t buffer_gettoken(buffer *, stralloc *, char); +size_t buffer_putc(buffer *, char); +ssize_t buffer_fill(buffer *); +ssize_t buffer_flush(buffer *); +ssize_t buffer_get(buffer *, char *, size_t); +ssize_t buffer_read(ssize_t (*op)(), int, char *, size_t); +ssize_t buffer_readall(ssize_t (*op)(), int, char *, size_t); +ssize_t buffer_write(ssize_t (*op)(), int, char const *, size_t); +ssize_t buffer_writeall(ssize_t (*op)(), int, char const *, size_t); +void buffer_init(buffer *, ssize_t (*op)(), int, char *, size_t); + +#endif diff --git a/env.h b/env.h @@ -0,0 +1,10 @@ +#ifndef ENV_H +#define ENV_H + +#include <stdlib.h> + +#define env_get(name) getenv(name) +#define env_set(name, value) setenv(name, value, 1) +#define env_unset(name, value) unsetenv(name, value, 1) + +#endif diff --git a/fmt.c b/fmt.c @@ -0,0 +1,166 @@ +#include "fmt.h" +#include "str.h" + +size_t +fmt_8long(char *buf, unsigned long i) +{ + size_t n = 0; + unsigned long x; + + x = i; do { x >>= 3; ++n; } while (x); + if (!buf) return n; + + buf += n; + x = i; do { *--buf = (x & 7) + '0'; x >>= 3; } while (x); + return n; +} + +/* "foo" -> "foo " */ +size_t +fmt_fill(char* dest, size_t srclen, size_t padlen, size_t maxlen) +{ + size_t n; + + n = maxlen < padlen ? srclen : padlen < srclen ? srclen : padlen; + if (!dest) return n; + + dest += n; + for (n = srclen; n < maxlen && n < padlen; n++) *dest++ = ' '; + return n; +} + +size_t +fmt_long(char *dest, long i) +{ + if (i < 0) { + if (dest) *dest++ = '-'; + return fmt_ulong(dest, (unsigned long) -i) + 1; + } else { + return fmt_ulong(dest, (unsigned long) i); + } +} + +size_t +fmt_minus(char *dest, int i) +{ + if (i >= 0) return 0; + if (dest) *dest = '-'; + return 1; +} + +/* "foo" -> " foo" */ +size_t +fmt_pad(char *dest, char const *src, size_t srclen, size_t padlen, size_t maxlen) +{ + size_t n, max; + + if (!dest) return maxlen < padlen ? maxlen : padlen < srclen ? srclen : padlen; + + n = 0; + max = maxlen < srclen ? maxlen : srclen; + for (; n < padlen - srclen; ++n) *dest++ = ' '; + for (; n < max; ++n) *dest++ = *src++; + return n; +} + +size_t +fmt_plusminus(char *dest, int i) +{ + if (dest) *dest = (i > 0 ? '+' : i < 0 ? '-' : ' '); + return 1; +} + +size_t +fmt_strn(char *out, size_t n, char const *in) +{ + size_t len; + + if (*out) return str_copy(out, in, n); + len = str_len(in); + return n < len ? n : len; +} + +size_t +fmt_ulong(char *buf, unsigned long i) +{ + size_t n = 0; + unsigned long x; + + x = i; do { x /= 10; ++n; } while (x); + if (!buf) return n; + + buf += n; + x = i; do { *--buf = '0' + x % 10; x /= 10; } while (x); + return n; +} + +size_t +fmt_ulong0(char *dest, unsigned long i, size_t pad) +{ + size_t n = 1; + unsigned long x; + + x = i; while (x > 9) { x /= 10; ++n; } + if (!dest) return pad > n ? pad : n; + + while (n <= pad) { *dest++ = '0'; ++n; } + fmt_ulong(dest, i); + return n; +} + +size_t +fmt_utf8(char *dest, uint32_t u) +{ + size_t v, n, n2; + + if (u <= 0x7f) { + if (dest) *dest = u; + return 1; + } + + for (v = 0x3f, n = 0; v >= u; ++n) v = (v << 5) | 0x1f; + if (v >= 0x7fffffff) return 0; /* cannot be encoded */ + if (!dest) return 1 + n; + + *dest++ = (0xff << (7 - n)) | (u >> n * 6); + for (n2 = n - 1; n2 ; --n2) { + *dest++ = 0x80 | (u & 0x3f); + u >>= 6; + } + return 1 + n; +} + +static inline char +hex(char c) +{ + if (c >= 10) return 'a' + c - 10; + return '0' + c; +} + +size_t +fmt_xlong(char *buf, unsigned long u) +{ + size_t n = 0; + unsigned long x; + + x = u; do { x >>= 4; ++n; } while (x); + if (!buf) return n; + + buf += n; + x = u; do { *--buf = hex(x & 15); x >>= 4; } while (x); + return n; +} + +size_t +fmt_xlong0(char *buf, unsigned long i, size_t pad) +{ + size_t n = 0; + unsigned long x = i; + + do { x >>= 4; ++n; } while (x > 15); + if (!buf) return pad > n ? pad : n; + + while (n < pad) { *buf++ = '0'; ++n; } + if (buf) fmt_xlong(buf, i); + return n; +} diff --git a/fmt.h b/fmt.h @@ -0,0 +1,20 @@ +#ifndef FMT_H +#define FMT_H + +#include <stddef.h> +#include <stdint.h> + +size_t fmt_8long(char *, unsigned long); +size_t fmt_fill(char*, size_t, size_t, size_t); +size_t fmt_long(char *, long); +size_t fmt_minus(char *, int); +size_t fmt_pad(char *, char const *, size_t, size_t, size_t); +size_t fmt_plusminus(char *, int); +size_t fmt_strn(char *, size_t, char const *); +size_t fmt_ulong(char *, unsigned long); +size_t fmt_ulong0(char *, unsigned long, size_t); +size_t fmt_utf8(char *, uint32_t); +size_t fmt_xlong(char *, unsigned long); +size_t fmt_xlong0(char *, unsigned long, size_t); + +#endif diff --git a/fs.c b/fs.c @@ -0,0 +1,115 @@ +#include <dirent.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> + +#include "fs.h" +#include "mem.h" +#include "open.h" +#include "str.h" +#include "stralloc.h" + +int +fs_mkdirr(char *dir) +{ + char *d = dir + (*dir == '/'); + int end = 0; + + do { + d += str_chr(d, '/'); + if (*d == '\0') end = 1; + + *d = '\0'; + if (mkdir(dir, 0600) == -1 && errno != EEXIST) return 0; + *d = '/'; + + } while (!end); + + return 1; +} + +int +fs_copy(char const *from, char const *to, unsigned int mode) +{ + char buf[1024 * 8]; + int fd_f; + int fd_t; + int r = -1; + int w = -1; + + fd_f = open_read(from); if (fd_f == -1) return 0; + fd_t = open_trunc(to); if (fd_t == -1) { close(fd_f); return 0; } + + if (chmod(to, mode) == -1) goto err; + + while (1) { + r = read(fd_f, buf, sizeof buf); if (r <= 0) break; + w = write(fd_t, buf, r); if (w < r) break; + } + +err: close(fd_f); + close(fd_t); + return r == 0 && w == 0; +} + +static int +fs_copyr_recurse(stralloc *f, stralloc *t) +{ + DIR *dp; + struct dirent *de; + struct stat st; + char ln[4096]; + + dp = opendir(f->x); if (!dp) return 0; + + errno = 0; + while ((de = readdir(dp))) { + if (str_equal(de->d_name, ".")) continue; + if (str_equal(de->d_name, "..")) continue; + + if (!stralloc_append(f, '/')) break; + if (!stralloc_cats(f, de->d_name)) break; + if (!stralloc_append(f, '\0')) break; + + if (!stralloc_append(t, '/')) break; + if (!stralloc_cats(t, de->d_name)) break; + if (!stralloc_append(t, '\0')) break; + + if (lstat(f->x, &st) == -1) break; + + if (S_ISDIR(st.st_mode)) { + if (mkdir(t->x, st.st_mode) == -1) break; + if (!fs_copyr_recurse(f, t)) break; + } + if (S_ISREG(st.st_mode)) { + if (!fs_copy(f->x, t->x, st.st_mode)) break; + } + if (S_ISLNK(st.st_mode)) { + if (readlink(f->x, ln, sizeof ln) == -1) break; + if (symlink(ln, t->x) == -1) break; + } else break; + + f->n = mem_rchr(f->x, '/', f->n) - 1; + t->n = mem_rchr(t->x, '/', t->n) - 1; + } + + closedir(dp); + return errno == 0; +} + +int +fs_copyr(char const *from, char const *to) +{ + stralloc sa_f = STRALLOC_ZERO; + stralloc sa_t = STRALLOC_ZERO; + int ret = 0; + + if (!stralloc_copys(&sa_f, from)) goto err; + if (!stralloc_copys(&sa_t, to)) goto err; + + ret = fs_copyr_recurse(&sa_f, &sa_t); + +err: stralloc_free(&sa_f); + stralloc_free(&sa_t); + return ret; +} diff --git a/fs.h b/fs.h @@ -0,0 +1,8 @@ +#ifndef FS_H +#define FS_H + +int fs_copy(char const *, char const *, unsigned int); +int fs_copyr(char const *, char const *); +int fs_mkdirr(char *); + +#endif diff --git a/genalloc.h b/genalloc.h @@ -0,0 +1,22 @@ +#ifndef GENALLOC_H +#define GENALLOC_H + +#include <stddef.h> +#include "stralloc.h" + +typedef stralloc genalloc; + +#define GENALLOC_ZERO STRALLOC_ZERO +#define genalloc_ready(type, sa, n) stralloc_ready((sa), (n) * sizeof (type)) +#define genalloc_len(type, sa) ((sa)->n / sizeof (type)) +#define genalloc_cat(sa1, sa2) stralloc_cat((sa1), (sa2)) +#define genalloc_catb(sa, b) stralloc_catb((sa), (x), sizeof *(x) * (n)) +#define genalloc_append(sa, x) stralloc_catb((sa), (char *)&(x), sizeof (x)) +#define genalloc_copy(sa1, sa2) stralloc_copy((sa1), (sa2)) +#define genalloc_copyb(sa, x, n) genalloc_copyb((sa), (char const) (x), (n) * sizeof (x)) +#define genalloc_free(sa) stralloc_free(sa) +#define genalloc_init(sa) stralloc_init(sa) +#define genalloc_zero(sa) stralloc_zero(sa) +#define genalloc_get(type, sa, i) (((type *)(sa)->x) + i) + +#endif diff --git a/log.c b/log.c @@ -0,0 +1,74 @@ +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "buffer.h" +#include "log.h" + +int log_level = 3; + +void +log_init(int level) +{ + log_level = level; +} + +void +log_put(int level, char const *s0, + char const *s1, char const *s2, char const *s3, char const *s4, + char const *s5, char const *s6, char const *s7, char const *s8) +{ + if (level < log_level) return; + + if (s0) buffer_puts(buffer_2, s0); + if (s1) buffer_puts(buffer_2, s1); + if (s2) buffer_puts(buffer_2, s2); + if (s3) buffer_puts(buffer_2, s3); + if (s4) buffer_puts(buffer_2, s4); + if (s5) buffer_puts(buffer_2, s5); + if (s6) buffer_puts(buffer_2, s6); + if (s7) buffer_puts(buffer_2, s7); + if (s8) buffer_puts(buffer_2, s8); + + buffer_puts(buffer_2, "\n"); + buffer_flush(buffer_2); +} + +void +log_putsys(int level, char const *s0, + char const *s1, char const *s2, char const *s3, char const *s4, + char const *s5, char const *s6) +{ + log_put(level, s0, s1, s2, s3, s4, s5, s6, ": ", strerror(errno)); +} + +void +log_usage(char const *prog, char const *usage) +{ + buffer_puts(buffer_2, "usage: "); + buffer_puts(buffer_2, prog); + buffer_puts(buffer_2, " "); + buffer_puts(buffer_2, usage); + buffer_puts(buffer_2, "\n"); + buffer_flush(buffer_2); + + exit(1); +} + +void +log_die(int e, char const *s0, + char const *s1, char const *s2, char const *s3, char const *s4, + char const *s5, char const *s6, char const *s7, char const *s8) +{ + log_put(5, s0, s1, s2, s3, s4, s5, s6, s7, s8); + exit(e); +} + +void +log_diesys(int e, char const *s0, + char const *s1, char const *s2, char const *s3, char const *s4, + char const *s5, char const *s6) +{ + log_putsys(5, s0, s1, s2, s3, s4, s5, s6); + exit(e); +} diff --git a/log.h b/log.h @@ -0,0 +1,71 @@ +#ifndef STRERR_H +#define STRERR_H + +#define log_die1(e, s1) log_die(e, "fatal: ", s1,0,0,0,0,0,0,0) +#define log_die2(e, s1,s2) log_die(e, "fatal: ", s1,s2,0,0,0,0,0,0) +#define log_die3(e, s1,s2,s3) log_die(e, "fatal: ", s1,s2,s3,0,0,0,0,0) +#define log_die4(e, s1,s2,s3,s4) log_die(e, "fatal: ", s1,s2,s3,s4,0,0,0,0) +#define log_die5(e, s1,s2,s3,s4,s5) log_die(e, "fatal: ", s1,s2,s3,s4,s5,0,0,0) +#define log_die6(e, s1,s2,s3,s4,s5,s6) log_die(e, "fatal: ", s1,s2,s3,s4,s5,s6,0,0) +#define log_die7(e, s1,s2,s3,s4,s5,s6,s7) log_die(e, "fatal: ", s1,s2,s3,s4,s5,s6,s7,0) +#define log_diesys1(e, s1) log_diesys(e, "fatal: ", s1,0,0,0,0,0) +#define log_diesys2(e, s1,s2) log_diesys(e, "fatal: ", s1,s2,0,0,0,0) +#define log_diesys3(e, s1,s2,s3) log_diesys(e, "fatal: ", s1,s2,s3,0,0,0) +#define log_diesys4(e, s1,s2,s3,s4) log_diesys(e, "fatal: ", s1,s2,s3,s4,0,0) +#define log_diesys5(e, s1,s2,s3,s4,s5) log_diesys(e, "fatal: ", s1,s2,s3,s4,s5,0) +#define log_diesys6(e, s1,s2,s3,s4,s5,s6) log_diesys(e, "fatal: ", s1,s2,s3,s4,s5,s6) + +#define log_err1(s1) log_put(2, "error: ", s1,0,0,0,0,0,0,0) +#define log_err2(s1,s2) log_put(2, "error: ", s1,s2,0,0,0,0,0,0) +#define log_err3(s1,s2,s3) log_put(2, "error: ", s1,s2,s3,0,0,0,0,0) +#define log_err4(s1,s2,s3,s4) log_put(2, "error: ", s1,s2,s3,s4,0,0,0,0) +#define log_err5(s1,s2,s3,s4,s5) log_put(2, "error: ", s1,s2,s3,s4,s5,0,0,0) +#define log_err6(s1,s2,s3,s4,s5,s6) log_put(2, "error: ", s1,s2,s3,s4,s5,s6,0,0) +#define log_err7(s1,s2,s3,s4,s5,s6,s7) log_put(2, "error: ", s1,s2,s3,s4,s5,s6,s7,0) +#define log_errsys1(s1) log_putsys(2, "error: ", s1,0,0,0,0,0) +#define log_errsys2(s1,s2) log_putsys(2, "error: ", s1,s2,0,0,0,0) +#define log_errsys3(s1,s2,s3) log_putsys(2, "error: ", s1,s2,s3,0,0,0) +#define log_errsys4(s1,s2,s3,s4) log_putsys(2, "error: ", s1,s2,s3,s4,0,0) +#define log_errsys5(s1,s2,s3,s4,s5) log_putsys(2, "error: ", s1,s2,s3,s4,s5,0) +#define log_errsys6(s1,s2,s3,s4,s5,s6) log_putsys(2, "error: ", s1,s2,s3,s4,s5,s6) + +#define log_warn1(s1) log_put(3, "warning: ", s1,0,0,0,0,0,0,0) +#define log_warn2(s1,s2) log_put(3, "warning: ", s1,s2,0,0,0,0,0,0) +#define log_warn3(s1,s2,s3) log_put(3, "warning: ", s1,s2,s3,0,0,0,0,0) +#define log_warn4(s1,s2,s3,s4) log_put(3, "warning: ", s1,s2,s3,s4,0,0,0,0) +#define log_warn5(s1,s2,s3,s4,s5) log_put(3, "warning: ", s1,s2,s3,s4,s5,0,0,0) +#define log_warn6(s1,s2,s3,s4,s5,s6) log_put(3, "warning: ", s1,s2,s3,s4,s5,s6,0,0) +#define log_warn7(s1,s2,s3,s4,s5,s6,s7) log_put(3, "warning: ", s1,s2,s3,s4,s5,s6,s7,0) +#define log_warnsys1(s1) log_putsys(3, "warning: ", s1,0,0,0,0) +#define log_warnsys2(s1,s2) log_putsys(3, "warning: ", s1,s2,0,0,0) +#define log_warnsys3(s1,s2,s3) log_putsys(3, "warning: ", s1,s2,s3,0,0) +#define log_warnsys4(s1,s2,s3,s4) log_putsys(3, "warning: ", s1,s2,s3,s4,0) +#define log_warnsys5(s1,s2,s3,s4,s5) log_putsys(3, "warning: ", s1,s2,s3,s4,s5) +#define log_warnsys6(s1,s2,s3,s4,s5,s6) log_putsys(3, "warning: ", s1,s2,s3,s4,s5,s6) + +#define log_info1(s1) log_put(4, "info: ", s1,0,0,0,0,0,0) +#define log_info2(s1,s2) log_put(4, "info: ", s1,s2,0,0,0,0,0,0) +#define log_info3(s1,s2,s3) log_put(4, "info: ", s1,s2,s3,0,0,0,0,0) +#define log_info4(s1,s2,s3,s4) log_put(4, "info: ", s1,s2,s3,s4,0,0,0,0) +#define log_info5(s1,s2,s3,s4,s5) log_put(4, "info: ", s1,s2,s3,s4,s5,0,0,0) +#define log_info6(s1,s2,s3,s4,s5,s6) log_put(4, "info: ", s1,s2,s3,s4,s5,s6,0,0) +#define log_info7(s1,s2,s3,s4,s5,s6,s7) log_put(4, "info: ", s1,s2,s3,s4,s5,s6,s7,0) + +#define log_debug1(s1) log_put(5, "debug: ", s1,0,0,0,0,0,0,0) +#define log_debug2(s1,s2) log_put(5, "debug: ", s1,s2,0,0,0,0,0,0) +#define log_debug3(s1,s2,s3) log_put(5, "debug: ", s1,s2,s3,0,0,0,0,0) +#define log_debug4(s1,s2,s3,s4) log_put(5, "debug: ", s1,s2,s3,s4,0,0,0,0) +#define log_debug5(s1,s2,s3,s4,s5) log_put(5, "debug: ", s1,s2,s3,s4,s5,0,0,0) +#define log_debug6(s1,s2,s3,s4,s5,s6) log_put(5, "debug: ", s1,s2,s3,s4,s5,s6,0,0) +#define log_debug7(s1,s2,s3,s4,s5,s6,s7) log_put(5, "debug: ", s1,s2,s3,s4,s5,s6,s7,0) + +extern int log_level; + +void log_die(int, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *); +void log_diesys(int, char const *, char const *, char const *, char const *, char const *, char const *, char const *); +void log_init(int); +void log_put(int, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *, char const *); +void log_putsys(int, char const *, char const *, char const *, char const *, char const *, char const *, char const *); +void log_usage(char const *, char const *); + +#endif diff --git a/make-a b/make-a @@ -0,0 +1,4 @@ +#!/bin/sh -e +rm -f "$1" +ar cr "$@" +ranlib "$1" diff --git a/make-bin b/make-bin @@ -0,0 +1,2 @@ +#!/bin/sh +exec cc -static -s -o "$@" diff --git a/make-h b/make-h @@ -0,0 +1,47 @@ +#!/bin/sh -e +# usage: tool/h prefix + +awk ' +function declare(type, symbol, args) +{ + printf("%-7s %s(%s);\n", type, symbol, args); + +} + +/^[a-zA-Z0-9_]+\(/ { + if (match(type, "static") || match($0, ";$")) + next; + + symbol = $0; + sub("\\(.*", "", symbol); + sub("[a-zA-Z0-9_]*\\(", "", $0); + + if (symbol == "main") + next; + + IN = 1; +} + +IN { + args = args " " $0; +} + +IN && /\)/ { + gsub("[ \t]+", " ", args); + sub("^ ", "", args); + gsub("[*][a-zA-Z0-9_]+,", "*,", args); + gsub("[*][a-zA-Z0-9_]+\\)[^)]*$", "*", args); + gsub("[ ][a-zA-Z0-9_]+,", ",", args); + gsub("[ ][a-zA-Z0-9_]+\\)[^)]*$", "", args); + gsub("\\.\\.\\. *\\)", "...", args); + + declare(type, symbol, args); + + args = "" + IN = 0; +} + +!IN { + type = $0; +} +' "$@" | sed -r 's,^([a-zA-Z_ ]+)( *)\*+( +),\1\2\3*,' | sort diff --git a/make-man b/make-man @@ -0,0 +1,119 @@ +#!/bin/sh + +if [ "$#" != 3 ]; then + echo "usage: ${0##*/} <section> <name> <description>" + exit 1 +fi + +section="$1" +name="$2" +description="$3" +author=${NAME:-<author-name>} +mail=${EMAIL:-<author-email>} + +case "$section" in (*) cat <<EOF ;; esac +.Dt $(echo "$name" | tr a-z A-Z) $section +.Dd $(date +'$Mdocdate: %B %d %Y$') +.Os +. +. +.Sh NAME +. +.Nm $name +.Nd $description +. +. +.Sh SYNOPSIS +. +.Nm $name +.Op Fl options +.Ar +. +. +.Sh DESCRIPTION +. +The +.Nm +utility +. +EOF +case "$section" in (9) cat <<EOF ;; esac +. +. +.Sh CONTEXT +. +EOF +case "$section" in (2|3|9) cat <<EOF ;; esac +. +. +.Sh RETURN VALUES +. +.Rv -std +. +EOF +case "$section" in (1|6|7|8) cat <<EOF ;; esac +. +. +.Sh ENVIRONMENT +. +EOF +cat <<EOF +. +. +.Sh FILES +. +EOF +case "$section" in (1|6|8) cat <<EOF ;; esac +. +. +.Sh EXIT STATUS +. +.Ex -std +EOF +cat <<EOF +. +. +.Sh EXAMPLES +. +EOF +case "$section" in (1|4|6|7|8) cat <<EOF ;; esac +. +. +.Sh DIAGNOSTICS +. +EOF +case "$section" in (2|3|4) cat <<EOF ;; esac +. +. +.Sh ERRORS +. +EOF +cat <<EOF +. +. +.Sh SEE ALSO +. +.Xr foobar 1 +. +. +.Sh STANDARDS +. +. +. +.Sh HISTORY +. +. +. +.Sh AUTHORS +. +.An $author +.Aq Mt $mail +. +. +.Sh CAVEATS +. +. +. +.Sh BUGS +. +EOF diff --git a/make-mk b/make-mk @@ -0,0 +1,11 @@ +#!/bin/sh +# usage: ./make-mk libprefix + +for file in "$@" +do + printf '%-16s %-16s ' "${file%.c}.o:" "$file" | tr -d '\n' + sed -rn 's/^#include "([^"]+.h)".*$/\1/p' "$file" | + xargs | + fold -w 80 -s | + sed -r 's/$/ \\/; $ s/ \\//' +done diff --git a/make-o b/make-o @@ -0,0 +1,2 @@ +#!/bin/sh +exec cc -Wno-unknown-warning-option -Wall -Wextra -Wno-misleading-indentation -std=c99 -pedantic -c "$@" diff --git a/mem.c b/mem.c @@ -0,0 +1,15 @@ +#include "mem.h" + +int +mem_chr(char const *buf, size_t n, char c) +{ + char *p = memchr(buf, c, n); + return p ? p - buf : c; +} + +int +mem_rchr(const char *buf, size_t n, char c) +{ + char *p = memchr(buf, c, n); + return p ? p - buf : c; +} diff --git a/mem.h b/mem.h @@ -0,0 +1,17 @@ +#ifndef BYTE_H +#define BYTE_H + +#include <stddef.h> +#include <string.h> + +#define mem_copy(to, from, n) memcpy(to, from, n) +#define mem_move(to, from, n) memmove(to, from, n) +#define mem_diff(buf1, buf2, n) memcmp(buf1, buf2, n) +#define mem_equal(buf1, buf2, n) (!memcmp(buf1, buf2, n)) +#define mem_set(buf, n, c) memset(buf, c, n) +#define mem_zero(buf, n) memset(buf, 0, n) + +int mem_chr(char const *, size_t, char); +int mem_rchr(const char *, size_t, char); + +#endif diff --git a/open.h b/open.h @@ -0,0 +1,12 @@ +#ifndef OPEN_H +#define OPEN_H + +#include <fcntl.h> + +#define open_append(path) open(path, O_WRONLY | O_NONBLOCK | O_APPEND | O_CREAT, 0600) +#define open_excl(path) open(path, O_WRONLY | O_EXCL | O_CREAT, 0600) +#define open_read(path) open(path, O_RDONLY | O_NONBLOCK) +#define open_trunc(path) open(path, O_WRONLY | O_NONBLOCK | O_TRUNC | O_CREAT, 0600) +#define open_write(path) open(path, O_WRONLY | O_NDELAY) + +#endif diff --git a/openreadclose.c b/openreadclose.c @@ -0,0 +1,29 @@ +#include <errno.h> +#include <unistd.h> +#include "stralloc.h" +#include "open.h" + +int +openreadclose(char const *path, stralloc *sa, size_t bufsize) +{ + ssize_t r; + int fd; + + fd = open_read(path); if (fd == -1) return 0; + + do { + if (!stralloc_readyplus(sa, bufsize)) { close(fd); return 0; } + r = read(fd, sa->x + sa->n, bufsize); + if (r == -1) { + if (errno == EINTR) continue; + if (errno == EAGAIN) continue; + if (errno == EWOULDBLOCK) continue; + close(fd); + return 0; + } + sa->n += r; + } while (r != 0); + + close(fd); + return 0; +} diff --git a/openreadclose.h b/openreadclose.h @@ -0,0 +1,8 @@ +#ifndef OPENREADCLOSE_H +#define OPENREADCLOSE_H + +#include "stralloc.h" + +int openreadclose(char const *, stralloc *, size_t); + +#endif diff --git a/pack-build b/pack-build Binary files differ. diff --git a/pack-build.c b/pack-build.c @@ -0,0 +1,34 @@ +#include <sys/stat.h> +#include <errno.h> + +#include "env.h" +#include "log.h" +#include "pack.h" +#include "str.h" + +int +main(int argc, char **argv) +{ + (void)argc; + (void)argv; + char *def; + char *out; + pack p; + struct stat st; + + str_copy(p.name, "dwm", sizeof p.name); + str_copy(p.ver, "git", sizeof p.ver); + + def = env_get("PACK_DEF"); if (!def) def = "/etc/pack"; + out = env_get("PACK_OUT"); if (!out) out = "/var/pack"; + + if (stat(def, &st) == -1) log_diesys1(101, def); + if (!S_ISDIR(st.st_mode)) errno = ENOTDIR, log_diesys1(101, def); + if (stat(out, &st) == -1) log_diesys1(101, out); + if (!S_ISDIR(st.st_mode)) errno = ENOTDIR, log_diesys1(101, out); + + if (!pack_data(&p, def, out)) + log_diesys6(1, "copying ", p.name, "'s data directory from ", def, " to ", out); + + return 0; +} diff --git a/pack.c b/pack.c @@ -0,0 +1,96 @@ +#include <sys/stat.h> +#include <ctype.h> + +#include "pack.h" +#include "stralloc.h" +#include "fs.h" +#include "mem.h" + +size_t +pack_scan(pack *p, char const *s) +{ + size_t i; + size_t j; + + if (s[0] == '/') return 0; + + for (i = 0 ;; ++i) { + if (!isprint(s[i])) return 0; + if (s[i] == ' ') return 0; + if (s[i] == '/') break; + if (i >= sizeof p->name) return 0; + } + + for (j = i ;; ++j) { + if (!isprint(s[j])) break; + if (s[j] == ' ') break; + if (s[j] == '/') break; + if (j > sizeof p->name) return 0; + } + + mem_copy(p->name, s, i); + mem_copy(p->ver, s + i + 1, j - i - 1); + + return j; +} + +int +pack_dep(genalloc *packs, char const *def) +{ + (void)packs; + (void)def; + + return 1; +} + +int +pack_version(pack *p) +{ + (void)p; + + return 1; +} + +int +pack_data(pack *p, char const *def, char const *out) +{ + stralloc sa_def = STRALLOC_ZERO; + stralloc sa_out = STRALLOC_ZERO; + int ret = 0; + struct stat sb; + + stralloc_init(&sa_out); + if (!stralloc_copys(&sa_out, out)) goto err; + if (!stralloc_append(&sa_out, '/')) goto err; + if (!stralloc_cats(&sa_out, p->name)) goto err; + if (!stralloc_append(&sa_out, '/')) goto err; + if (!stralloc_cats(&sa_out, p->ver)) goto err; + if (!stralloc_append(&sa_out, '\0')) goto err; + + stralloc_init(&sa_def); + if (!stralloc_copys(&sa_def, def)) goto err; + if (!stralloc_append(&sa_def, '/')) goto err; + if (!stralloc_cats(&sa_def, p->name)) goto err; + if (!stralloc_append(&sa_def, '/')) goto err; + if (!stralloc_cats(&sa_def, "default")) goto err; + if (!stralloc_cats(&sa_def, "/data")) goto err; + if (!stralloc_append(&sa_def, '\0')) goto err; + + if (stat(sa_def.x, &sb) == 0) + if (!fs_copyr(sa_def.x, sa_out.x)) goto err; + + sa_def.n = mem_rchr(sa_def.x, sa_def.n, '/') - 1; + sa_def.n = mem_rchr(sa_def.x, sa_def.n, '/'); + if (!stralloc_cats(&sa_def, p->ver)) goto err; + if (!stralloc_cats(&sa_def, "/data")) goto err; + if (!stralloc_append(&sa_def, '\0')) goto err; + + if (stat(sa_def.x, &sb) == 0) + if (!fs_copyr(sa_def.x, sa_out.x)) goto err; + + ret = 1; + +err: stralloc_free(&sa_def); + stralloc_free(&sa_out); + return ret; +} diff --git a/pack.h b/pack.h @@ -0,0 +1,18 @@ +#ifndef PACK_H +#define PACK_H + +#include <limits.h> + +#include "genalloc.h" + +typedef struct { + char name[NAME_MAX]; + char ver[NAME_MAX]; +} pack; + +int pack_data(pack *, char const *, char const *); +int pack_dep(genalloc *, char const *); +int pack_version(pack *); +size_t pack_scan(pack *, char const *); + +#endif diff --git a/str.c b/str.c @@ -0,0 +1,15 @@ +#include "str.h" + +size_t +str_chr(char const *buf, char c) +{ + char *s = strchr(buf, c); + return s ? buf - s : strlen(buf); +} + +size_t +str_rchr(char const *buf, char c) +{ + char *s = strrchr(buf, c); + return s ? buf - s : strlen(buf); +} diff --git a/str.h b/str.h @@ -0,0 +1,18 @@ +#ifndef STR_H +#define STR_H + +#include <stddef.h> +#include <string.h> + +#define str_copy(to, from, n) strlen(strncpy(to, from, n)) +#define str_diff(buf1, buf2) strcmp(buf1, buf2) +#define str_diffn(buf1, buf2, n) strncmp(buf1, buf2, n) +#define str_equal(buf1, buf2) (!strcmp(buf1, buf2)) +#define str_equaln(buf1, buf2, n) (!strncmp(buf1, buf2, n)) +#define str_len(buf) strlen(buf) +#define str_start(buf1, buf2) (!strncmp(buf1, buf2, strlen(buf1))) + +size_t str_chr(char const *, char); +size_t str_rchr(char const *, char); + +#endif diff --git a/stralloc.c b/stralloc.c @@ -0,0 +1,95 @@ +#include <stdlib.h> +#include "mem.h" +#include "fmt.h" +#include "str.h" +#include "stralloc.h" + +int +stralloc_catb(stralloc *sa, const char *x, size_t n) +{ + if (!stralloc_readyplus(sa, n)) return 0; + mem_copy(sa->x + sa->n, x, n); + sa->n += n; + return 1; +} + +int +stralloc_catlong0(stralloc *sa, signed long int in, size_t n) +{ + int neg = neg = -(in < 0); + size_t f; + + if (neg) in = -in; + f = fmt_minus(0, neg) + fmt_ulong0(0, (unsigned long)in, n); + if (!stralloc_readyplus(sa, f)) return 0; + sa->n += fmt_minus(sa->x + sa->n, neg); + sa->n += fmt_ulong0(sa->x + sa->n, (unsigned long)in, n); + return 1; +} + +int +stralloc_catulong0(stralloc *sa, unsigned long int in, size_t n) +{ + if (!stralloc_readyplus(sa, fmt_ulong0(0, in, n))) return 0; + sa->n += fmt_ulong0(sa->x + sa->n, in, n); + return 1; +} + +int +stralloc_copyb(stralloc *sa, const char *buf, size_t n) +{ + if (!stralloc_ready(sa, n)) return 0; + sa->n = n; + mem_copy(sa->x, buf, n); + return 1; +} + +int +stralloc_append(stralloc *sa, char c) +{ + return stralloc_catb(sa, &c, 1); +} + +void +stralloc_zero(stralloc *sa) +{ + sa->n = 0; +} + +void +stralloc_init(stralloc *sa) +{ + sa->x = 0; + sa->a = 0; + sa->n = 0; +} + +void +stralloc_free(stralloc *sa) +{ + free(sa->x); + sa->x = 0; + sa->a = 0; + sa->n = 0; +} + +int +stralloc_ready(stralloc *sa, size_t n) +{ + size_t wanted = n + (n >> 3) + 30; /* heuristic from djb */ + + if (wanted < n) wanted = n; + if (!sa->x || sa->a < n) { + char *x = realloc(sa->x, wanted); if (!x) return 0; + sa->a = wanted; + sa->x = x; + } + return 1; +} + +int +stralloc_starts(stralloc *sa, const char *in) +{ + size_t n = str_len(in); + return (n <= sa->n && mem_equal(sa->x, in, n)); +} diff --git a/stralloc.h b/stralloc.h @@ -0,0 +1,38 @@ +#ifndef STRALLOC_H +#define STRALLOC_H + +#include <stddef.h> +#include "str.h" + +typedef struct stralloc { + char* x; + size_t n; + size_t a; +} stralloc; + +#define STRALLOC_ZERO { 0, 0, 0 } + +#define stralloc_cat(sa1, sa2) stralloc_catb((sa1), (sa2)->x, (sa2)->n) +#define stralloc_catint(sa, i) stralloc_catlong0((sa), (i), 0) +#define stralloc_catint0(sa, i, n) stralloc_catlong0((sa), (i), (n)) +#define stralloc_catlong(sa, l) stralloc_catlong0((sa), (l), 0) +#define stralloc_cats(sa, buf) stralloc_catb((sa), (buf), str_len(buf)) +#define stralloc_catuint(sa, i) stralloc_catulong0((sa), (i), 0) +#define stralloc_catuint0(sa, i, n) stralloc_catulong0((sa), (i), (n)) +#define stralloc_catulong(sa, l) stralloc_catulong0((sa), (l), 0) +#define stralloc_copys(sa, buf) stralloc_copyb((sa), (buf), str_len(buf)) +#define stralloc_copy(sa1, sa2) stralloc_copyb((sa1), (sa2)->x, (sa2)->n) +#define stralloc_readyplus(sa, len) stralloc_ready((sa), (sa)->n + (len)) + +int stralloc_append(stralloc *, char); +int stralloc_catb(stralloc *, const char *, size_t); +int stralloc_catlong0(stralloc *, signed long int, size_t); +int stralloc_catulong0(stralloc *, unsigned long int, size_t); +int stralloc_copyb(stralloc *, const char *, size_t); +int stralloc_ready(stralloc *, size_t); +int stralloc_starts(stralloc *, const char *); +void stralloc_free(stralloc *); +void stralloc_init(stralloc *); +void stralloc_zero(stralloc *); + +#endif