summary refs log tree commit diff
path: root/bin
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2018-05-13 00:41:58 -0400
committerJune McEnroe <june@causal.agency>2018-05-13 00:42:28 -0400
commit869f6622bbb883257a0eb96742752b9969cfb0be (patch)
tree7d2b2ff7b0c4dd5395bfc23585d27fe9052802a9 /bin
parentTabify shell scripts (diff)
downloadsrc-869f6622bbb883257a0eb96742752b9969cfb0be.tar.gz
src-869f6622bbb883257a0eb96742752b9969cfb0be.zip
Tabify bin
Diffstat (limited to '')
-rw-r--r--bin/bri.c84
-rw-r--r--bin/brot.c152
-rw-r--r--bin/dtch.c320
-rw-r--r--bin/fbatt.c168
-rw-r--r--bin/fbclock.c184
-rw-r--r--bin/gfx/cocoa.m196
-rw-r--r--bin/gfx/fb.c76
-rw-r--r--bin/gfx/none.c2
-rw-r--r--bin/gfx/x11.c158
-rw-r--r--bin/gfxx.c692
-rw-r--r--bin/glitch.c674
-rw-r--r--bin/hnel.c154
-rw-r--r--bin/klon.c484
-rw-r--r--bin/pbd.c152
-rw-r--r--bin/pngo.c1056
-rw-r--r--bin/scheme.c290
-rw-r--r--bin/wake.c38
-rw-r--r--bin/watch.c100
-rw-r--r--bin/xx.c170
19 files changed, 2575 insertions, 2575 deletions
diff --git a/bin/bri.c b/bin/bri.c
index 413958c5..561b22df 100644
--- a/bin/bri.c
+++ b/bin/bri.c
@@ -26,58 +26,58 @@
 static const char *CLASS = "/sys/class/backlight";
 
 int main(int argc, char *argv[]) {
-    int error;
+	int error;
 
-    const char *input = (argc > 1) ? argv[1] : NULL;
+	const char *input = (argc > 1) ? argv[1] : NULL;
 
-    error = chdir(CLASS);
-    if (error) err(EX_OSFILE, "%s", CLASS);
+	error = chdir(CLASS);
+	if (error) err(EX_OSFILE, "%s", CLASS);
 
-    DIR *dir = opendir(".");
-    if (!dir) err(EX_OSFILE, "%s", CLASS);
+	DIR *dir = opendir(".");
+	if (!dir) err(EX_OSFILE, "%s", CLASS);
 
-    struct dirent *entry;
-    while (NULL != (errno = 0, entry = readdir(dir))) {
-        if (entry->d_name[0] == '.') continue;
+	struct dirent *entry;
+	while (NULL != (errno = 0, entry = readdir(dir))) {
+		if (entry->d_name[0] == '.') continue;
 
-        error = chdir(entry->d_name);
-        if (error) err(EX_OSFILE, "%s/%s", CLASS, entry->d_name);
-        break;
-    }
-    if (!entry) {
-        if (errno) err(EX_IOERR, "%s", CLASS);
-        errx(EX_CONFIG, "%s: empty", CLASS);
-    }
+		error = chdir(entry->d_name);
+		if (error) err(EX_OSFILE, "%s/%s", CLASS, entry->d_name);
+		break;
+	}
+	if (!entry) {
+		if (errno) err(EX_IOERR, "%s", CLASS);
+		errx(EX_CONFIG, "%s: empty", CLASS);
+	}
 
-    FILE *actual = fopen("actual_brightness", "r");
-    if (!actual) err(EX_OSFILE, "%s/actual_brightness", CLASS);
+	FILE *actual = fopen("actual_brightness", "r");
+	if (!actual) err(EX_OSFILE, "%s/actual_brightness", CLASS);
 
-    unsigned value;
-    int match = fscanf(actual, "%u", &value);
-    if (match == EOF) err(EX_IOERR, "%s/actual_brightness", CLASS);
-    if (match < 1) errx(EX_DATAERR, "%s/actual_brightness", CLASS);
+	unsigned value;
+	int match = fscanf(actual, "%u", &value);
+	if (match == EOF) err(EX_IOERR, "%s/actual_brightness", CLASS);
+	if (match < 1) errx(EX_DATAERR, "%s/actual_brightness", CLASS);
 
-    if (!input) {
-        printf("%u\n", value);
-        return EX_OK;
-    }
+	if (!input) {
+		printf("%u\n", value);
+		return EX_OK;
+	}
 
-    if (input[0] == '+' || input[0] == '-') {
-        size_t count = strnlen(input, 16);
-        if (input[0] == '+') {
-            value += 16 * count;
-        } else {
-            value -= 16 * count;
-        }
-    } else {
-        value = strtoul(input, NULL, 0);
-    }
+	if (input[0] == '+' || input[0] == '-') {
+		size_t count = strnlen(input, 16);
+		if (input[0] == '+') {
+			value += 16 * count;
+		} else {
+			value -= 16 * count;
+		}
+	} else {
+		value = strtoul(input, NULL, 0);
+	}
 
-    FILE *brightness = fopen("brightness", "w");
-    if (!brightness) err(EX_OSFILE, "%s/brightness", CLASS);
+	FILE *brightness = fopen("brightness", "w");
+	if (!brightness) err(EX_OSFILE, "%s/brightness", CLASS);
 
-    int size = fprintf(brightness, "%u", value);
-    if (size < 0) err(EX_IOERR, "brightness");
+	int size = fprintf(brightness, "%u", value);
+	if (size < 0) err(EX_IOERR, "brightness");
 
-    return EX_OK;
+	return EX_OK;
 }
diff --git a/bin/brot.c b/bin/brot.c
index 09ca9c4b..f487c236 100644
--- a/bin/brot.c
+++ b/bin/brot.c
@@ -32,18 +32,18 @@
 #define GRAY(n) RGB(n, n, n)
 
 static double absSq(double complex z) {
-    return creal(z) * creal(z) + cimag(z) * cimag(z);
+	return creal(z) * creal(z) + cimag(z) * cimag(z);
 }
 
 static uint32_t depth = 50;
 
 static uint32_t mandelbrot(double complex c) {
-    double complex z = 0;
-    for (uint32_t i = 0; i < depth; ++i) {
-        if (absSq(z) > 4.0) return i;
-        z = z * z + c;
-    }
-    return 0;
+	double complex z = 0;
+	for (uint32_t i = 0; i < depth; ++i) {
+		if (absSq(z) > 4.0) return i;
+		z = z * z + c;
+	}
+	return 0;
 }
 
 static double complex translate = -0.75;
@@ -52,34 +52,34 @@ static double complex transform = 2.5;
 static uint32_t samples = 1;
 
 static void sample(uint32_t *buf, size_t width, size_t height) {
-    double yRatio = (height > width) ? (double)height / (double)width : 1.0;
-    double xRatio = (width > height) ? (double)width / (double)height : 1.0;
-
-    memset(buf, 0, 4 * width * height);
-    size_t superWidth = width * samples;
-    size_t superHeight = height * samples;
-    for (size_t y = 0; y < superHeight; ++y) {
-        for (size_t x = 0; x < superWidth; ++x) {
-            double zx = (((double)x + 0.5) / (double)superWidth - 0.5) * xRatio;
-            double zy = (((double)y + 0.5) / (double)superHeight - 0.5) * yRatio;
-            uint32_t n = mandelbrot((zx + zy * I) * transform + translate);
-            buf[(y / samples) * width + (x / samples)] += n;
-        }
-    }
+	double yRatio = (height > width) ? (double)height / (double)width : 1.0;
+	double xRatio = (width > height) ? (double)width / (double)height : 1.0;
+
+	memset(buf, 0, 4 * width * height);
+	size_t superWidth = width * samples;
+	size_t superHeight = height * samples;
+	for (size_t y = 0; y < superHeight; ++y) {
+		for (size_t x = 0; x < superWidth; ++x) {
+			double zx = (((double)x + 0.5) / (double)superWidth - 0.5) * xRatio;
+			double zy = (((double)y + 0.5) / (double)superHeight - 0.5) * yRatio;
+			uint32_t n = mandelbrot((zx + zy * I) * transform + translate);
+			buf[(y / samples) * width + (x / samples)] += n;
+		}
+	}
 }
 
 static void color(uint32_t *buf, size_t width, size_t height) {
-    for (size_t i = 0; i < width * height; ++i) {
-        buf[i] = GRAY(255 * buf[i] / samples / samples / depth);
-    }
+	for (size_t i = 0; i < width * height; ++i) {
+		buf[i] = GRAY(255 * buf[i] / samples / samples / depth);
+	}
 }
 
 static double frameTime;
 void draw(uint32_t *buf, size_t width, size_t height) {
-    clock_t t0 = clock();
-    sample(buf, width, height);
-    color(buf, width, height);
-    frameTime = (double)(clock() - t0) / (double)CLOCKS_PER_SEC;
+	clock_t t0 = clock();
+	sample(buf, width, height);
+	color(buf, width, height);
+	frameTime = (double)(clock() - t0) / (double)CLOCKS_PER_SEC;
 }
 
 static double translateStep = 1.0 / 128.0;
@@ -87,61 +87,61 @@ static double rotateStep = 1.0 / 128.0;
 static double scaleStep = 1.0 / 32.0;
 
 bool input(char in) {
-    const double PI = acos(-1.0);
-    switch (in) {
-        case 'q': return false;
-        break; case '.': depth++;
-        break; case ',': if (depth > 1) depth--;
-        break; case 'l': translate += translateStep * transform;
-        break; case 'h': translate -= translateStep * transform;
-        break; case 'j': translate += translateStep * I * transform;
-        break; case 'k': translate -= translateStep * I * transform;
-        break; case 'u': transform *= cexp(rotateStep * PI * I);
-        break; case 'i': transform /= cexp(rotateStep * PI * I);
-        break; case '+': transform *= 1.0 - scaleStep;
-        break; case '-': transform /= 1.0 - scaleStep;
-        break; case '0': translate = -0.75; transform = 2.5;
-        break; case ']': samples++;
-        break; case '[': if (samples > 1) samples--;
-    }
-    return true;
+	const double PI = acos(-1.0);
+	switch (in) {
+		case 'q': return false;
+				  break; case '.': depth++;
+				  break; case ',': if (depth > 1) depth--;
+				  break; case 'l': translate += translateStep * transform;
+				  break; case 'h': translate -= translateStep * transform;
+				  break; case 'j': translate += translateStep * I * transform;
+				  break; case 'k': translate -= translateStep * I * transform;
+				  break; case 'u': transform *= cexp(rotateStep * PI * I);
+				  break; case 'i': transform /= cexp(rotateStep * PI * I);
+				  break; case '+': transform *= 1.0 - scaleStep;
+				  break; case '-': transform /= 1.0 - scaleStep;
+				  break; case '0': translate = -0.75; transform = 2.5;
+				  break; case ']': samples++;
+				  break; case '[': if (samples > 1) samples--;
+	}
+	return true;
 }
 
 const char *status(void) {
-    static char buf[256];
-    snprintf(
-        buf, sizeof(buf),
-        "brot -s %u -i %u -t %g%+gi -f %g%+gi # %.6f",
-        samples, depth,
-        creal(translate), cimag(translate),
-        creal(transform), cimag(transform),
-        frameTime
-    );
-    return buf;
+	static char buf[256];
+	snprintf(
+		buf, sizeof(buf),
+		"brot -s %u -i %u -t %g%+gi -f %g%+gi # %.6f",
+		samples, depth,
+		creal(translate), cimag(translate),
+		creal(transform), cimag(transform),
+		frameTime
+	);
+	return buf;
 }
 
 static double complex parseComplex(const char *str) {
-    double real = 0.0, imag = 0.0;
-    real = strtod(str, (char **)&str);
-    if (str[0] == 'i') {
-        imag = real;
-        real = 0.0;
-    } else if (str[0]) {
-        imag = strtod(str, NULL);
-    }
-    return real + imag * I;
+	double real = 0.0, imag = 0.0;
+	real = strtod(str, (char **)&str);
+	if (str[0] == 'i') {
+		imag = real;
+		real = 0.0;
+	} else if (str[0]) {
+		imag = strtod(str, NULL);
+	}
+	return real + imag * I;
 }
 
 int init(int argc, char *argv[]) {
-    int opt;
-    while (0 < (opt = getopt(argc, argv, "f:i:s:t:"))) {
-        switch (opt) {
-            case 'f': transform = parseComplex(optarg); break;
-            case 'i': depth = strtoul(optarg, NULL, 0); break;
-            case 's': samples = strtoul(optarg, NULL, 0); break;
-            case 't': translate = parseComplex(optarg); break;
-            default: return EX_USAGE;
-        }
-    }
-    return EX_OK;
+	int opt;
+	while (0 < (opt = getopt(argc, argv, "f:i:s:t:"))) {
+		switch (opt) {
+			case 'f': transform = parseComplex(optarg); break;
+			case 'i': depth = strtoul(optarg, NULL, 0); break;
+			case 's': samples = strtoul(optarg, NULL, 0); break;
+			case 't': translate = parseComplex(optarg); break;
+			default: return EX_USAGE;
+		}
+	}
+	return EX_OK;
 }
diff --git a/bin/dtch.c b/bin/dtch.c
index 7ec71801..fa97fdcc 100644
--- a/bin/dtch.c
+++ b/bin/dtch.c
@@ -40,208 +40,208 @@
 #endif
 
 static struct passwd *getUser(void) {
-    uid_t uid = getuid();
-    struct passwd *user = getpwuid(uid);
-    if (!user) err(EX_OSFILE, "/etc/passwd");
-    return user;
+	uid_t uid = getuid();
+	struct passwd *user = getpwuid(uid);
+	if (!user) err(EX_OSFILE, "/etc/passwd");
+	return user;
 }
 
 static struct sockaddr_un sockAddr(const char *home, const char *name) {
-    struct sockaddr_un addr = { .sun_family = AF_LOCAL };
-    snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/.dtch/%s", home, name);
-    return addr;
+	struct sockaddr_un addr = { .sun_family = AF_LOCAL };
+	snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/.dtch/%s", home, name);
+	return addr;
 }
 
 static char z;
 static struct iovec iov = { .iov_base = &z, .iov_len = 1 };
 
 static ssize_t sendFd(int sock, int fd) {
-    size_t size = CMSG_LEN(sizeof(int));
-    char buf[size];
-    struct msghdr msg = {
-        .msg_iov = &iov,
-        .msg_iovlen = 1,
-        .msg_control = buf,
-        .msg_controllen = size,
-    };
-
-    struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
-    cmsg->cmsg_len = size;
-    cmsg->cmsg_level = SOL_SOCKET;
-    cmsg->cmsg_type = SCM_RIGHTS;
-    *(int *)CMSG_DATA(cmsg) = fd;
-
-    return sendmsg(sock, &msg, 0);
+	size_t size = CMSG_LEN(sizeof(int));
+	char buf[size];
+	struct msghdr msg = {
+		.msg_iov = &iov,
+		.msg_iovlen = 1,
+		.msg_control = buf,
+		.msg_controllen = size,
+	};
+
+	struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
+	cmsg->cmsg_len = size;
+	cmsg->cmsg_level = SOL_SOCKET;
+	cmsg->cmsg_type = SCM_RIGHTS;
+	*(int *)CMSG_DATA(cmsg) = fd;
+
+	return sendmsg(sock, &msg, 0);
 }
 
 static int recvFd(int sock) {
-    size_t size = CMSG_LEN(sizeof(int));
-    char buf[size];
-    struct msghdr msg = {
-        .msg_iov = &iov,
-        .msg_iovlen = 1,
-        .msg_control = buf,
-        .msg_controllen = size,
-    };
-
-    ssize_t n = recvmsg(sock, &msg, 0);
-    if (n < 0) return -1;
-
-    struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
-    if (!cmsg || cmsg->cmsg_type != SCM_RIGHTS) {
-        errno = ENOMSG;
-        return -1;
-    }
-
-    return *(int *)CMSG_DATA(cmsg);
+	size_t size = CMSG_LEN(sizeof(int));
+	char buf[size];
+	struct msghdr msg = {
+		.msg_iov = &iov,
+		.msg_iovlen = 1,
+		.msg_control = buf,
+		.msg_controllen = size,
+	};
+
+	ssize_t n = recvmsg(sock, &msg, 0);
+	if (n < 0) return -1;
+
+	struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
+	if (!cmsg || cmsg->cmsg_type != SCM_RIGHTS) {
+		errno = ENOMSG;
+		return -1;
+	}
+
+	return *(int *)CMSG_DATA(cmsg);
 }
 
 static struct sockaddr_un addr;
 static void unlinkAddr(void) {
-    unlink(addr.sun_path);
+	unlink(addr.sun_path);
 }
 
 static int dtch(int argc, char *argv[]) {
-    int error;
+	int error;
 
-    const struct passwd *user = getUser();
+	const struct passwd *user = getUser();
 
-    const char *name = user->pw_name;
-    if (argc > 1) {
-        name = argv[1];
-        argv++;
-        argc--;
-    }
-    if (argc > 1) {
-        argv++;
-    } else {
-        argv[0] = user->pw_shell;
-    }
+	const char *name = user->pw_name;
+	if (argc > 1) {
+		name = argv[1];
+		argv++;
+		argc--;
+	}
+	if (argc > 1) {
+		argv++;
+	} else {
+		argv[0] = user->pw_shell;
+	}
 
-    int home = open(user->pw_dir, 0);
-    if (home < 0) err(EX_CANTCREAT, "%s", user->pw_dir);
+	int home = open(user->pw_dir, 0);
+	if (home < 0) err(EX_CANTCREAT, "%s", user->pw_dir);
 
-    error = mkdirat(home, ".dtch", 0700);
-    if (error && errno != EEXIST) err(EX_CANTCREAT, "%s/.dtch", user->pw_dir);
+	error = mkdirat(home, ".dtch", 0700);
+	if (error && errno != EEXIST) err(EX_CANTCREAT, "%s/.dtch", user->pw_dir);
 
-    close(home);
+	close(home);
 
-    int server = socket(PF_LOCAL, SOCK_STREAM, 0);
-    if (server < 0) err(EX_OSERR, "socket");
+	int server = socket(PF_LOCAL, SOCK_STREAM, 0);
+	if (server < 0) err(EX_OSERR, "socket");
 
-    addr = sockAddr(user->pw_dir, name);
-    error = bind(server, (struct sockaddr *)&addr, sizeof(addr));
-    if (error) err(EX_CANTCREAT, "%s", addr.sun_path);
-    fcntl(server, F_SETFD, FD_CLOEXEC);
-    atexit(unlinkAddr);
+	addr = sockAddr(user->pw_dir, name);
+	error = bind(server, (struct sockaddr *)&addr, sizeof(addr));
+	if (error) err(EX_CANTCREAT, "%s", addr.sun_path);
+	fcntl(server, F_SETFD, FD_CLOEXEC);
+	atexit(unlinkAddr);
 
-    int pty;
-    pid_t pid = forkpty(&pty, NULL, NULL, NULL);
-    if (pid < 0) err(EX_OSERR, "forkpty");
+	int pty;
+	pid_t pid = forkpty(&pty, NULL, NULL, NULL);
+	if (pid < 0) err(EX_OSERR, "forkpty");
 
-    if (!pid) {
-        execvp(*argv, argv);
-        err(EX_NOINPUT, "%s", *argv);
-    }
+	if (!pid) {
+		execvp(*argv, argv);
+		err(EX_NOINPUT, "%s", *argv);
+	}
 
-    error = listen(server, 0);
-    if (error) err(EX_OSERR, "listen");
+	error = listen(server, 0);
+	if (error) err(EX_OSERR, "listen");
 
-    for (;;) {
-        int client = accept(server, NULL, NULL);
-        if (client < 0) err(EX_IOERR, "accept");
+	for (;;) {
+		int client = accept(server, NULL, NULL);
+		if (client < 0) err(EX_IOERR, "accept");
 
-        ssize_t size = sendFd(client, pty);
-        if (size < 0) warn("sendmsg");
+		ssize_t size = sendFd(client, pty);
+		if (size < 0) warn("sendmsg");
 
-        size = recv(client, &z, sizeof(z), 0);
-        if (size < 0) warn("recv");
+		size = recv(client, &z, sizeof(z), 0);
+		if (size < 0) warn("recv");
 
-        close(client);
+		close(client);
 
-        int status;
-        pid_t dead = waitpid(pid, &status, WNOHANG);
-        if (dead < 0) err(EX_OSERR, "waitpid(%d)", pid);
-        if (dead) return WIFEXITED(status) ? WEXITSTATUS(status) : EX_SOFTWARE;
-    }
+		int status;
+		pid_t dead = waitpid(pid, &status, WNOHANG);
+		if (dead < 0) err(EX_OSERR, "waitpid(%d)", pid);
+		if (dead) return WIFEXITED(status) ? WEXITSTATUS(status) : EX_SOFTWARE;
+	}
 }
 
 static struct termios saveTerm;
 static void restoreTerm(void) {
-    tcsetattr(STDIN_FILENO, TCSADRAIN, &saveTerm);
-    printf(
-        "\x1b[?1049l" // rmcup
-        "\x1b\x63\x1b[!p\x1b[?3;4l\x1b[4l\x1b>" // reset
-    );
+	tcsetattr(STDIN_FILENO, TCSADRAIN, &saveTerm);
+	printf(
+		"\x1b[?1049l" // rmcup
+		"\x1b\x63\x1b[!p\x1b[?3;4l\x1b[4l\x1b>" // reset
+	);
 }
 
 static int atch(int argc, char *argv[]) {
-    int error;
-
-    const struct passwd *user = getUser();
-    const char *name = (argc > 1) ? argv[1] : user->pw_name;
-
-    int client = socket(PF_LOCAL, SOCK_STREAM, 0);
-    if (client < 0) err(EX_OSERR, "socket");
-
-    struct sockaddr_un addr = sockAddr(user->pw_dir, name);
-    error = connect(client, (struct sockaddr *)&addr, sizeof(addr));
-    if (error) err(EX_NOINPUT, "%s", addr.sun_path);
-
-    int pty = recvFd(client);
-    if (pty < 0) err(EX_IOERR, "recvmsg");
-
-    struct winsize window;
-    error = ioctl(STDIN_FILENO, TIOCGWINSZ, &window);
-    if (error) err(EX_IOERR, "TIOCGWINSZ");
-
-    struct winsize redraw = { .ws_row = 1, .ws_col = 1 };
-    error = ioctl(pty, TIOCSWINSZ, &redraw);
-    if (error) err(EX_IOERR, "TIOCSWINSZ");
-
-    error = ioctl(pty, TIOCSWINSZ, &window);
-    if (error) err(EX_IOERR, "TIOCSWINSZ");
-
-    error = tcgetattr(STDIN_FILENO, &saveTerm);
-    if (error) err(EX_IOERR, "tcgetattr");
-    atexit(restoreTerm);
-
-    struct termios raw;
-    cfmakeraw(&raw);
-    error = tcsetattr(STDIN_FILENO, TCSADRAIN, &raw);
-    if (error) err(EX_IOERR, "tcsetattr");
-
-    char buf[4096];
-    struct pollfd fds[2] = {
-        { .fd = STDIN_FILENO, .events = POLLIN },
-        { .fd = pty, .events = POLLIN },
-    };
-    while (0 < poll(fds, 2, -1)) {
-        if (fds[0].revents) {
-            ssize_t size = read(STDIN_FILENO, buf, sizeof(buf));
-            if (size < 0) err(EX_IOERR, "read(%d)", STDIN_FILENO);
-
-            if (size == 1 && buf[0] == CTRL('Q')) return EX_OK;
-
-            size = write(pty, buf, size);
-            if (size < 0) err(EX_IOERR, "write(%d)", pty);
-        }
-
-        if (fds[1].revents) {
-            ssize_t size = read(pty, buf, sizeof(buf));
-            if (size < 0) err(EX_IOERR, "read(%d)", pty);
-
-            size = write(STDOUT_FILENO, buf, size);
-            if (size < 0) err(EX_IOERR, "write(%d)", STDOUT_FILENO);
-        }
-    }
-    err(EX_IOERR, "poll");
+	int error;
+
+	const struct passwd *user = getUser();
+	const char *name = (argc > 1) ? argv[1] : user->pw_name;
+
+	int client = socket(PF_LOCAL, SOCK_STREAM, 0);
+	if (client < 0) err(EX_OSERR, "socket");
+
+	struct sockaddr_un addr = sockAddr(user->pw_dir, name);
+	error = connect(client, (struct sockaddr *)&addr, sizeof(addr));
+	if (error) err(EX_NOINPUT, "%s", addr.sun_path);
+
+	int pty = recvFd(client);
+	if (pty < 0) err(EX_IOERR, "recvmsg");
+
+	struct winsize window;
+	error = ioctl(STDIN_FILENO, TIOCGWINSZ, &window);
+	if (error) err(EX_IOERR, "TIOCGWINSZ");
+
+	struct winsize redraw = { .ws_row = 1, .ws_col = 1 };
+	error = ioctl(pty, TIOCSWINSZ, &redraw);
+	if (error) err(EX_IOERR, "TIOCSWINSZ");
+
+	error = ioctl(pty, TIOCSWINSZ, &window);
+	if (error) err(EX_IOERR, "TIOCSWINSZ");
+
+	error = tcgetattr(STDIN_FILENO, &saveTerm);
+	if (error) err(EX_IOERR, "tcgetattr");
+	atexit(restoreTerm);
+
+	struct termios raw;
+	cfmakeraw(&raw);
+	error = tcsetattr(STDIN_FILENO, TCSADRAIN, &raw);
+	if (error) err(EX_IOERR, "tcsetattr");
+
+	char buf[4096];
+	struct pollfd fds[2] = {
+		{ .fd = STDIN_FILENO, .events = POLLIN },
+		{ .fd = pty, .events = POLLIN },
+	};
+	while (0 < poll(fds, 2, -1)) {
+		if (fds[0].revents) {
+			ssize_t size = read(STDIN_FILENO, buf, sizeof(buf));
+			if (size < 0) err(EX_IOERR, "read(%d)", STDIN_FILENO);
+
+			if (size == 1 && buf[0] == CTRL('Q')) return EX_OK;
+
+			size = write(pty, buf, size);
+			if (size < 0) err(EX_IOERR, "write(%d)", pty);
+		}
+
+		if (fds[1].revents) {
+			ssize_t size = read(pty, buf, sizeof(buf));
+			if (size < 0) err(EX_IOERR, "read(%d)", pty);
+
+			size = write(STDOUT_FILENO, buf, size);
+			if (size < 0) err(EX_IOERR, "write(%d)", STDOUT_FILENO);
+		}
+	}
+	err(EX_IOERR, "poll");
 }
 
 int main(int argc, char *argv[]) {
-    switch (argv[0][0]) {
-        case 'd': return dtch(argc, argv);
-        case 'a': return atch(argc, argv);
-        default:  return EX_USAGE;
-    }
+	switch (argv[0][0]) {
+		case 'd': return dtch(argc, argv);
+		case 'a': return atch(argc, argv);
+		default:  return EX_USAGE;
+	}
 }
diff --git a/bin/fbatt.c b/bin/fbatt.c
index 30714e2c..3486ba59 100644
--- a/bin/fbatt.c
+++ b/bin/fbatt.c
@@ -40,88 +40,88 @@ static const uint32_t YELLOW = 0xA37720;
 static const uint32_t RED    = 0xA32810;
 
 int main() {
-    int error;
-
-    DIR *dir = opendir(CLASS);
-    if (!dir) err(EX_OSFILE, "%s", CLASS);
-
-    FILE *chargeFull = NULL;
-    FILE *chargeNow = NULL;
-
-    const struct dirent *entry;
-    while (NULL != (errno = 0, entry = readdir(dir))) {
-        if (entry->d_name[0] == '.') continue;
-
-        error = chdir(CLASS);
-        if (error) err(EX_OSFILE, "%s", CLASS);
-
-        error = chdir(entry->d_name);
-        if (error) err(EX_OSFILE, "%s/%s", CLASS, entry->d_name);
-
-        chargeFull = fopen("charge_full", "r");
-        chargeNow = fopen("charge_now", "r");
-        if (chargeFull && chargeNow) break;
-    }
-    if (!chargeFull || !chargeNow) {
-        if (errno) err(EX_OSFILE, "%s", CLASS);
-        errx(EX_CONFIG, "%s: empty", CLASS);
-    }
-    closedir(dir);
-
-    const char *path = getenv("FRAMEBUFFER");
-    if (!path) path = "/dev/fb0";
-
-    int fb = open(path, O_RDWR);
-    if (fb < 0) err(EX_OSFILE, "%s", path);
-
-    struct fb_var_screeninfo info;
-    error = ioctl(fb, FBIOGET_VSCREENINFO, &info);
-    if (error) err(EX_IOERR, "%s", path);
-
-    size_t size = 4 * info.xres * info.yres;
-    uint32_t *buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
-    if (buf == MAP_FAILED) err(EX_IOERR, "%s", path);
-
-    for (;;) {
-        int match;
-
-        rewind(chargeFull);
-        fflush(chargeFull);
-        uint32_t full;
-        match = fscanf(chargeFull, "%u", &full);
-        if (match == EOF) err(EX_IOERR, "charge_full");
-        if (match < 1) errx(EX_DATAERR, "charge_full");
-
-        rewind(chargeNow);
-        fflush(chargeNow);
-        uint32_t now;
-        match = fscanf(chargeNow, "%u", &now);
-        if (match == EOF) err(EX_IOERR, "charge_now");
-        if (match < 1) errx(EX_DATAERR, "charge_now");
-
-        uint32_t percent = 100 * now / full;
-        uint32_t height = 16 * now / full;
-
-        for (int i = 0; i < 60; ++i, sleep(1)) {
-            uint32_t left = info.xres - RIGHT - WIDTH;
-
-            for (uint32_t y = 0; y <= HEIGHT; ++y) {
-                buf[y * info.xres + left - 1] = BORDER;
-                buf[y * info.xres + left + WIDTH] = BORDER;
-            }
-            for (uint32_t x = left; x < left + WIDTH; ++x) {
-                buf[HEIGHT * info.xres + x] = BORDER;
-            }
-
-            for (uint32_t y = 0; y < HEIGHT; ++y) {
-                for (uint32_t x = left; x < left + WIDTH; ++x) {
-                    buf[y * info.xres + x] =
-                        (HEIGHT - 1 - y > height) ? BG
-                        : (percent <= 10) ? RED
-                        : (percent <= 30) ? YELLOW
-                        : GRAY;
-                }
-            }
-        }
-    }
+	int error;
+
+	DIR *dir = opendir(CLASS);
+	if (!dir) err(EX_OSFILE, "%s", CLASS);
+
+	FILE *chargeFull = NULL;
+	FILE *chargeNow = NULL;
+
+	const struct dirent *entry;
+	while (NULL != (errno = 0, entry = readdir(dir))) {
+		if (entry->d_name[0] == '.') continue;
+
+		error = chdir(CLASS);
+		if (error) err(EX_OSFILE, "%s", CLASS);
+
+		error = chdir(entry->d_name);
+		if (error) err(EX_OSFILE, "%s/%s", CLASS, entry->d_name);
+
+		chargeFull = fopen("charge_full", "r");
+		chargeNow = fopen("charge_now", "r");
+		if (chargeFull && chargeNow) break;
+	}
+	if (!chargeFull || !chargeNow) {
+		if (errno) err(EX_OSFILE, "%s", CLASS);
+		errx(EX_CONFIG, "%s: empty", CLASS);
+	}
+	closedir(dir);
+
+	const char *path = getenv("FRAMEBUFFER");
+	if (!path) path = "/dev/fb0";
+
+	int fb = open(path, O_RDWR);
+	if (fb < 0) err(EX_OSFILE, "%s", path);
+
+	struct fb_var_screeninfo info;
+	error = ioctl(fb, FBIOGET_VSCREENINFO, &info);
+	if (error) err(EX_IOERR, "%s", path);
+
+	size_t size = 4 * info.xres * info.yres;
+	uint32_t *buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
+	if (buf == MAP_FAILED) err(EX_IOERR, "%s", path);
+
+	for (;;) {
+		int match;
+
+		rewind(chargeFull);
+		fflush(chargeFull);
+		uint32_t full;
+		match = fscanf(chargeFull, "%u", &full);
+		if (match == EOF) err(EX_IOERR, "charge_full");
+		if (match < 1) errx(EX_DATAERR, "charge_full");
+
+		rewind(chargeNow);
+		fflush(chargeNow);
+		uint32_t now;
+		match = fscanf(chargeNow, "%u", &now);
+		if (match == EOF) err(EX_IOERR, "charge_now");
+		if (match < 1) errx(EX_DATAERR, "charge_now");
+
+		uint32_t percent = 100 * now / full;
+		uint32_t height = 16 * now / full;
+
+		for (int i = 0; i < 60; ++i, sleep(1)) {
+			uint32_t left = info.xres - RIGHT - WIDTH;
+
+			for (uint32_t y = 0; y <= HEIGHT; ++y) {
+				buf[y * info.xres + left - 1] = BORDER;
+				buf[y * info.xres + left + WIDTH] = BORDER;
+			}
+			for (uint32_t x = left; x < left + WIDTH; ++x) {
+				buf[HEIGHT * info.xres + x] = BORDER;
+			}
+
+			for (uint32_t y = 0; y < HEIGHT; ++y) {
+				for (uint32_t x = left; x < left + WIDTH; ++x) {
+					buf[y * info.xres + x] =
+						(HEIGHT - 1 - y > height) ? BG
+						: (percent <= 10) ? RED
+						: (percent <= 30) ? YELLOW
+						: GRAY;
+				}
+			}
+		}
+	}
 }
diff --git a/bin/fbclock.c b/bin/fbclock.c
index bd967307..699ce969 100644
--- a/bin/fbclock.c
+++ b/bin/fbclock.c
@@ -30,102 +30,102 @@
 
 static const uint32_t PSF2_MAGIC = 0x864AB572;
 struct Psf2Header {
-    uint32_t magic;
-    uint32_t version;
-    uint32_t headerSize;
-    uint32_t flags;
-    uint32_t glyphCount;
-    uint32_t glyphSize;
-    uint32_t glyphHeight;
-    uint32_t glyphWidth;
+	uint32_t magic;
+	uint32_t version;
+	uint32_t headerSize;
+	uint32_t flags;
+	uint32_t glyphCount;
+	uint32_t glyphSize;
+	uint32_t glyphHeight;
+	uint32_t glyphWidth;
 };
 
 static const uint32_t BG = 0x161510;
 static const uint32_t FG = 0x7A7155;
 
 int main() {
-    size_t len;
-
-    const char *fontPath = getenv("FONT");
-    if (!fontPath) {
-        fontPath = "/usr/share/kbd/consolefonts/Lat2-Terminus16.psfu.gz";
-    }
-
-    gzFile font = gzopen(fontPath, "r");
-    if (!font) err(EX_NOINPUT, "%s", fontPath);
-
-    struct Psf2Header header;
-    len = gzfread(&header, sizeof(header), 1, font);
-    if (!len && gzeof(font)) errx(EX_DATAERR, "%s: missing header", fontPath);
-    if (!len) errx(EX_IOERR, "%s", gzerror(font, NULL));
-
-    if (header.magic != PSF2_MAGIC) {
-        errx(
-            EX_DATAERR, "%s: invalid header magic %08X",
-            fontPath, header.magic
-        );
-    }
-    if (header.headerSize != sizeof(struct Psf2Header)) {
-        errx(
-            EX_DATAERR, "%s: weird header size %d",
-            fontPath, header.headerSize
-        );
-    }
-
-    uint8_t glyphs[128][header.glyphSize];
-    len = gzfread(glyphs, header.glyphSize, 128, font);
-    if (!len && gzeof(font)) errx(EX_DATAERR, "%s: missing glyphs", fontPath);
-    if (!len) errx(EX_IOERR, "%s", gzerror(font, NULL));
-
-    gzclose(font);
-
-    const char *fbPath = getenv("FRAMEBUFFER");
-    if (!fbPath) fbPath = "/dev/fb0";
-
-    int fb = open(fbPath, O_RDWR);
-    if (fb < 0) err(EX_OSFILE, "%s", fbPath);
-
-    struct fb_var_screeninfo info;
-    int error = ioctl(fb, FBIOGET_VSCREENINFO, &info);
-    if (error) err(EX_IOERR, "%s", fbPath);
-
-    size_t size = 4 * info.xres * info.yres;
-    uint32_t *buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
-    if (buf == MAP_FAILED) err(EX_IOERR, "%s", fbPath);
-
-    for (;;) {
-        time_t t = time(NULL);
-        if (t < 0) err(EX_OSERR, "time");
-        const struct tm *local = localtime(&t);
-        if (!local) err(EX_OSERR, "localtime");
-
-        char str[64];
-        len = strftime(str, sizeof(str), "%H:%M", local);
-        assert(len);
-
-        for (int i = 0; i < (60 - local->tm_sec); ++i, sleep(1)) {
-            uint32_t left = info.xres - header.glyphWidth * len;
-            uint32_t bottom = header.glyphHeight;
-
-            for (uint32_t y = 0; y < bottom; ++y) {
-                buf[y * info.xres + left - 1] = FG;
-            }
-            for (uint32_t x = left - 1; x < info.xres; ++x) {
-                buf[bottom * info.xres + x] = FG;
-            }
-
-            for (const char *s = str; *s; ++s) {
-                const uint8_t *glyph = glyphs[(unsigned)*s];
-                uint32_t stride = header.glyphSize / header.glyphHeight;
-                for (uint32_t y = 0; y < header.glyphHeight; ++y) {
-                    for (uint32_t x = 0; x < header.glyphWidth; ++x) {
-                        uint8_t bits = glyph[y * stride + x / 8];
-                        uint8_t bit = bits >> (7 - x % 8) & 1;
-                        buf[y * info.xres + left + x] = bit ? FG : BG;
-                    }
-                }
-                left += header.glyphWidth;
-            }
-        }
-    }
+	size_t len;
+
+	const char *fontPath = getenv("FONT");
+	if (!fontPath) {
+		fontPath = "/usr/share/kbd/consolefonts/Lat2-Terminus16.psfu.gz";
+	}
+
+	gzFile font = gzopen(fontPath, "r");
+	if (!font) err(EX_NOINPUT, "%s", fontPath);
+
+	struct Psf2Header header;
+	len = gzfread(&header, sizeof(header), 1, font);
+	if (!len && gzeof(font)) errx(EX_DATAERR, "%s: missing header", fontPath);
+	if (!len) errx(EX_IOERR, "%s", gzerror(font, NULL));
+
+	if (header.magic != PSF2_MAGIC) {
+		errx(
+			EX_DATAERR, "%s: invalid header magic %08X",
+			fontPath, header.magic
+		);
+	}
+	if (header.headerSize != sizeof(struct Psf2Header)) {
+		errx(
+			EX_DATAERR, "%s: weird header size %d",
+			fontPath, header.headerSize
+		);
+	}
+
+	uint8_t glyphs[128][header.glyphSize];
+	len = gzfread(glyphs, header.glyphSize, 128, font);
+	if (!len && gzeof(font)) errx(EX_DATAERR, "%s: missing glyphs", fontPath);
+	if (!len) errx(EX_IOERR, "%s", gzerror(font, NULL));
+
+	gzclose(font);
+
+	const char *fbPath = getenv("FRAMEBUFFER");
+	if (!fbPath) fbPath = "/dev/fb0";
+
+	int fb = open(fbPath, O_RDWR);
+	if (fb < 0) err(EX_OSFILE, "%s", fbPath);
+
+	struct fb_var_screeninfo info;
+	int error = ioctl(fb, FBIOGET_VSCREENINFO, &info);
+	if (error) err(EX_IOERR, "%s", fbPath);
+
+	size_t size = 4 * info.xres * info.yres;
+	uint32_t *buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
+	if (buf == MAP_FAILED) err(EX_IOERR, "%s", fbPath);
+
+	for (;;) {
+		time_t t = time(NULL);
+		if (t < 0) err(EX_OSERR, "time");
+		const struct tm *local = localtime(&t);
+		if (!local) err(EX_OSERR, "localtime");
+
+		char str[64];
+		len = strftime(str, sizeof(str), "%H:%M", local);
+		assert(len);
+
+		for (int i = 0; i < (60 - local->tm_sec); ++i, sleep(1)) {
+			uint32_t left = info.xres - header.glyphWidth * len;
+			uint32_t bottom = header.glyphHeight;
+
+			for (uint32_t y = 0; y < bottom; ++y) {
+				buf[y * info.xres + left - 1] = FG;
+			}
+			for (uint32_t x = left - 1; x < info.xres; ++x) {
+				buf[bottom * info.xres + x] = FG;
+			}
+
+			for (const char *s = str; *s; ++s) {
+				const uint8_t *glyph = glyphs[(unsigned)*s];
+				uint32_t stride = header.glyphSize / header.glyphHeight;
+				for (uint32_t y = 0; y < header.glyphHeight; ++y) {
+					for (uint32_t x = 0; x < header.glyphWidth; ++x) {
+						uint8_t bits = glyph[y * stride + x / 8];
+						uint8_t bit = bits >> (7 - x % 8) & 1;
+						buf[y * info.xres + left + x] = bit ? FG : BG;
+					}
+				}
+				left += header.glyphWidth;
+			}
+		}
+	}
 }
diff --git a/bin/gfx/cocoa.m b/bin/gfx/cocoa.m
index 495b1f9f..3df6c62a 100644
--- a/bin/gfx/cocoa.m
+++ b/bin/gfx/cocoa.m
@@ -26,78 +26,78 @@
 #define UNUSED __attribute__((unused))
 
 @interface BufferView : NSView {
-    size_t bufSize;
-    uint32_t *buf;
-    CGColorSpaceRef colorSpace;
-    CGDataProviderRef dataProvider;
+	size_t bufSize;
+	uint32_t *buf;
+	CGColorSpaceRef colorSpace;
+	CGDataProviderRef dataProvider;
 }
 @end
 
 @implementation BufferView
 - (instancetype) initWithFrame: (NSRect) frameRect {
-    colorSpace = CGColorSpaceCreateDeviceRGB();
-    return [super initWithFrame: frameRect];
+	colorSpace = CGColorSpaceCreateDeviceRGB();
+	return [super initWithFrame: frameRect];
 }
 
 - (void) setWindowTitle {
-    [[self window] setTitle: [NSString stringWithUTF8String: status()]];
+	[[self window] setTitle: [NSString stringWithUTF8String: status()]];
 }
 
 - (void) draw {
-    draw(buf, [self frame].size.width, [self frame].size.height);
-    [self setNeedsDisplay: YES];
+	draw(buf, [self frame].size.width, [self frame].size.height);
+	[self setNeedsDisplay: YES];
 }
 
 - (void) setFrameSize: (NSSize) newSize {
-    [super setFrameSize: newSize];
-    size_t newBufSize = 4 * newSize.width * newSize.height;
-    if (newBufSize > bufSize) {
-        bufSize = newBufSize;
-        buf = malloc(bufSize);
-        if (!buf) err(EX_OSERR, "malloc(%zu)", bufSize);
-        CGDataProviderRelease(dataProvider);
-        dataProvider = CGDataProviderCreateWithData(NULL, buf, bufSize, NULL);
-    }
-    [self draw];
+	[super setFrameSize: newSize];
+	size_t newBufSize = 4 * newSize.width * newSize.height;
+	if (newBufSize > bufSize) {
+		bufSize = newBufSize;
+		buf = malloc(bufSize);
+		if (!buf) err(EX_OSERR, "malloc(%zu)", bufSize);
+		CGDataProviderRelease(dataProvider);
+		dataProvider = CGDataProviderCreateWithData(NULL, buf, bufSize, NULL);
+	}
+	[self draw];
 }
 
 - (void) drawRect: (NSRect) UNUSED dirtyRect {
-    NSSize size = [self frame].size;
-    CGContextRef ctx = [[NSGraphicsContext currentContext] CGContext];
-    CGImageRef image = CGImageCreate(
-        size.width, size.height,
-        8, 32, 4 * size.width,
-        colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
-        dataProvider,
-        NULL, false, kCGRenderingIntentDefault
-    );
-    CGContextDrawImage(ctx, [self frame], image);
-    CGImageRelease(image);
+	NSSize size = [self frame].size;
+	CGContextRef ctx = [[NSGraphicsContext currentContext] CGContext];
+	CGImageRef image = CGImageCreate(
+		size.width, size.height,
+		8, 32, 4 * size.width,
+		colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipFirst,
+		dataProvider,
+		NULL, false, kCGRenderingIntentDefault
+	);
+	CGContextDrawImage(ctx, [self frame], image);
+	CGImageRelease(image);
 }
 
 - (BOOL) acceptsFirstResponder {
-    return YES;
+	return YES;
 }
 
 - (void) keyDown: (NSEvent *) event {
-    char in;
-    BOOL converted = [
-        [event characters]
-        getBytes: &in
-        maxLength: 1
-        usedLength: NULL
-        encoding: NSASCIIStringEncoding
-        options: 0
-        range: NSMakeRange(0, 1)
-        remainingRange: NULL
-    ];
-    if (converted) {
-        if (!input(in)) {
-            [NSApp terminate: self];
-        }
-        [self draw];
-        [self setWindowTitle];
-    }
+	char in;
+	BOOL converted = [
+		[event characters]
+		getBytes: &in
+		maxLength: 1
+		usedLength: NULL
+		encoding: NSASCIIStringEncoding
+		options: 0
+		range: NSMakeRange(0, 1)
+		remainingRange: NULL
+	];
+	if (converted) {
+		if (!input(in)) {
+			[NSApp terminate: self];
+		}
+		[self draw];
+		[self setWindowTitle];
+	}
 }
 @end
 
@@ -106,57 +106,57 @@
 
 @implementation Delegate
 - (BOOL) applicationShouldTerminateAfterLastWindowClosed:
-    (NSApplication *) UNUSED sender {
-    return YES;
+	(NSApplication *) UNUSED sender {
+	return YES;
 }
 @end
 
 int main(int argc, char *argv[]) {
-    int error = init(argc, argv);
-    if (error) return error;
-
-    [NSApplication sharedApplication];
-    [NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
-    [NSApp setDelegate: [Delegate new]];
-
-    NSString *name = [[NSProcessInfo processInfo] processName];
-    NSMenu *menu = [NSMenu new];
-    [
-        menu
-        addItemWithTitle: @"Close Window"
-        action: @selector(performClose:)
-        keyEquivalent: @"w"
-    ];
-    [menu addItem: [NSMenuItem separatorItem]];
-    [
-        menu
-        addItemWithTitle: [@"Quit " stringByAppendingString: name]
-        action: @selector(terminate:)
-        keyEquivalent: @"q"
-    ];
-    NSMenuItem *menuItem = [NSMenuItem new];
-    [menuItem setSubmenu: menu];
-    [NSApp setMainMenu: [NSMenu new]];
-    [[NSApp mainMenu] addItem: menuItem];
-
-    NSUInteger style = NSTitledWindowMask
-        | NSClosableWindowMask
-        | NSMiniaturizableWindowMask
-        | NSResizableWindowMask;
-    NSWindow *window = [
-        [NSWindow alloc]
-        initWithContentRect: NSMakeRect(0, 0, 800, 600)
-        styleMask: style
-        backing: NSBackingStoreBuffered
-        defer: YES
-    ];
-    [window center];
-
-    BufferView *view = [[BufferView alloc] initWithFrame: [window frame]];
-    [window setContentView: view];
-    [view setWindowTitle];
-
-    [window makeKeyAndOrderFront: nil];
-    [NSApp activateIgnoringOtherApps: YES];
-    [NSApp run];
+	int error = init(argc, argv);
+	if (error) return error;
+
+	[NSApplication sharedApplication];
+	[NSApp setActivationPolicy: NSApplicationActivationPolicyRegular];
+	[NSApp setDelegate: [Delegate new]];
+
+	NSString *name = [[NSProcessInfo processInfo] processName];
+	NSMenu *menu = [NSMenu new];
+	[
+		menu
+		addItemWithTitle: @"Close Window"
+		action: @selector(performClose:)
+		keyEquivalent: @"w"
+	];
+	[menu addItem: [NSMenuItem separatorItem]];
+	[
+		menu
+		addItemWithTitle: [@"Quit " stringByAppendingString: name]
+		action: @selector(terminate:)
+		keyEquivalent: @"q"
+	];
+	NSMenuItem *menuItem = [NSMenuItem new];
+	[menuItem setSubmenu: menu];
+	[NSApp setMainMenu: [NSMenu new]];
+	[[NSApp mainMenu] addItem: menuItem];
+
+	NSUInteger style = NSTitledWindowMask
+		| NSClosableWindowMask
+		| NSMiniaturizableWindowMask
+		| NSResizableWindowMask;
+	NSWindow *window = [
+		[NSWindow alloc]
+		initWithContentRect: NSMakeRect(0, 0, 800, 600)
+		styleMask: style
+		backing: NSBackingStoreBuffered
+		defer: YES
+	];
+	[window center];
+
+	BufferView *view = [[BufferView alloc] initWithFrame: [window frame]];
+	[window setContentView: view];
+	[view setWindowTitle];
+
+	[window makeKeyAndOrderFront: nil];
+	[NSApp activateIgnoringOtherApps: YES];
+	[NSApp run];
 }
diff --git a/bin/gfx/fb.c b/bin/gfx/fb.c
index 651ed80c..e1ef5e82 100644
--- a/bin/gfx/fb.c
+++ b/bin/gfx/fb.c
@@ -32,56 +32,56 @@
 
 static struct termios saveTerm;
 static void restoreTerm(void) {
-    tcsetattr(STDERR_FILENO, TCSADRAIN, &saveTerm);
+	tcsetattr(STDERR_FILENO, TCSADRAIN, &saveTerm);
 }
 
 int main(int argc, char *argv[]) {
-    int error;
+	int error;
 
-    error = init(argc, argv);
-    if (error) return error;
+	error = init(argc, argv);
+	if (error) return error;
 
-    const char *path = getenv("FRAMEBUFFER");
-    if (!path) path = "/dev/fb0";
+	const char *path = getenv("FRAMEBUFFER");
+	if (!path) path = "/dev/fb0";
 
-    int fb = open(path, O_RDWR);
-    if (fb < 0) err(EX_OSFILE, "%s", path);
+	int fb = open(path, O_RDWR);
+	if (fb < 0) err(EX_OSFILE, "%s", path);
 
-    struct fb_var_screeninfo info;
-    error = ioctl(fb, FBIOGET_VSCREENINFO, &info);
-    if (error) err(EX_IOERR, "%s", path);
+	struct fb_var_screeninfo info;
+	error = ioctl(fb, FBIOGET_VSCREENINFO, &info);
+	if (error) err(EX_IOERR, "%s", path);
 
-    size_t size = 4 * info.xres * info.yres;
-    uint32_t *buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
-    if (buf == MAP_FAILED) err(EX_IOERR, "%s", path);
+	size_t size = 4 * info.xres * info.yres;
+	uint32_t *buf = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
+	if (buf == MAP_FAILED) err(EX_IOERR, "%s", path);
 
-    error = tcgetattr(STDERR_FILENO, &saveTerm);
-    if (error) err(EX_IOERR, "tcgetattr");
-    atexit(restoreTerm);
+	error = tcgetattr(STDERR_FILENO, &saveTerm);
+	if (error) err(EX_IOERR, "tcgetattr");
+	atexit(restoreTerm);
 
-    struct termios term = saveTerm;
-    term.c_lflag &= ~(ICANON | ECHO);
-    error = tcsetattr(STDERR_FILENO, TCSADRAIN, &term);
-    if (error) err(EX_IOERR, "tcsetattr");
+	struct termios term = saveTerm;
+	term.c_lflag &= ~(ICANON | ECHO);
+	error = tcsetattr(STDERR_FILENO, TCSADRAIN, &term);
+	if (error) err(EX_IOERR, "tcsetattr");
 
-    uint32_t saveBg = buf[0];
+	uint32_t saveBg = buf[0];
 
-    uint32_t back[info.xres * info.yres];
-    for (;;) {
-        draw(back, info.xres, info.yres);
-        memcpy(buf, back, size);
+	uint32_t back[info.xres * info.yres];
+	for (;;) {
+		draw(back, info.xres, info.yres);
+		memcpy(buf, back, size);
 
-        char in;
-        ssize_t len = read(STDERR_FILENO, &in, 1);
-        if (len < 0) err(EX_IOERR, "read");
-        if (!len) return EX_DATAERR;
+		char in;
+		ssize_t len = read(STDERR_FILENO, &in, 1);
+		if (len < 0) err(EX_IOERR, "read");
+		if (!len) return EX_DATAERR;
 
-        if (!input(in)) {
-            for (uint32_t i = 0; i < info.xres * info.yres; ++i) {
-                buf[i] = saveBg;
-            }
-            fprintf(stderr, "%s\n", status());
-            return EX_OK;
-        }
-    }
+		if (!input(in)) {
+			for (uint32_t i = 0; i < info.xres * info.yres; ++i) {
+				buf[i] = saveBg;
+			}
+			fprintf(stderr, "%s\n", status());
+			return EX_OK;
+		}
+	}
 }
diff --git a/bin/gfx/none.c b/bin/gfx/none.c
index e5d53a9b..31de2ff4 100644
--- a/bin/gfx/none.c
+++ b/bin/gfx/none.c
@@ -20,5 +20,5 @@
 #include "gfx.h"
 
 int main() {
-    errx(EX_CONFIG, "no gfx frontend");
+	errx(EX_CONFIG, "no gfx frontend");
 }
diff --git a/bin/gfx/x11.c b/bin/gfx/x11.c
index 82d5c833..eae926c2 100644
--- a/bin/gfx/x11.c
+++ b/bin/gfx/x11.c
@@ -40,96 +40,96 @@ static size_t pixmapHeight;
 static Pixmap pixmap;
 
 static void createWindow(void) {
-    display = XOpenDisplay(NULL);
-    if (!display) errx(EX_UNAVAILABLE, "XOpenDisplay: %s", XDisplayName(NULL));
+	display = XOpenDisplay(NULL);
+	if (!display) errx(EX_UNAVAILABLE, "XOpenDisplay: %s", XDisplayName(NULL));
 
-    Window root = DefaultRootWindow(display);
-    window = XCreateSimpleWindow(display, root, 0, 0, width, height, 0, 0, 0);
+	Window root = DefaultRootWindow(display);
+	window = XCreateSimpleWindow(display, root, 0, 0, width, height, 0, 0, 0);
 
-    WM_DELETE_WINDOW = XInternAtom(display, "WM_DELETE_WINDOW", false);
-    XSetWMProtocols(display, window, &WM_DELETE_WINDOW, 1);
+	WM_DELETE_WINDOW = XInternAtom(display, "WM_DELETE_WINDOW", false);
+	XSetWMProtocols(display, window, &WM_DELETE_WINDOW, 1);
 
-    windowGc = XCreateGC(display, window, 0, NULL);
+	windowGc = XCreateGC(display, window, 0, NULL);
 
-    image = XCreateImage(display, NULL, 24, ZPixmap, 0, NULL, width, height, 32, 0);
+	image = XCreateImage(display, NULL, 24, ZPixmap, 0, NULL, width, height, 32, 0);
 }
 
 static void resizePixmap(void) {
-    size_t newSize = 4 * width * height;
-    if (newSize > bufSize) {
-        bufSize = newSize;
-        free(buf);
-        buf = malloc(bufSize);
-        if (!buf) err(EX_OSERR, "malloc(%zu)", bufSize);
-    }
-
-    image->data = (char *)buf;
-    image->width = width;
-    image->height = height;
-    image->bytes_per_line = 4 * width;
-
-    if (width > pixmapWidth || height > pixmapHeight) {
-        pixmapWidth = width;
-        pixmapHeight = height;
-        if (pixmap) XFreePixmap(display, pixmap);
-        pixmap = XCreatePixmap(display, window, pixmapWidth, pixmapHeight, 24);
-    }
+	size_t newSize = 4 * width * height;
+	if (newSize > bufSize) {
+		bufSize = newSize;
+		free(buf);
+		buf = malloc(bufSize);
+		if (!buf) err(EX_OSERR, "malloc(%zu)", bufSize);
+	}
+
+	image->data = (char *)buf;
+	image->width = width;
+	image->height = height;
+	image->bytes_per_line = 4 * width;
+
+	if (width > pixmapWidth || height > pixmapHeight) {
+		pixmapWidth = width;
+		pixmapHeight = height;
+		if (pixmap) XFreePixmap(display, pixmap);
+		pixmap = XCreatePixmap(display, window, pixmapWidth, pixmapHeight, 24);
+	}
 }
 
 static void drawWindow(void) {
-    draw(buf, width, height);
-    XPutImage(display, pixmap, windowGc, image, 0, 0, 0, 0, width, height);
-    XCopyArea(display, pixmap, window, windowGc, 0, 0, width, height, 0, 0);
+	draw(buf, width, height);
+	XPutImage(display, pixmap, windowGc, image, 0, 0, 0, 0, width, height);
+	XCopyArea(display, pixmap, window, windowGc, 0, 0, width, height, 0, 0);
 }
 
 int main(int argc, char *argv[]) {
-    int error = init(argc, argv);
-    if (error) return error;
-
-    createWindow();
-    resizePixmap();
-    drawWindow();
-
-    XStoreName(display, window, status());
-    XMapWindow(display, window);
-
-    XEvent event;
-    XSelectInput(display, window, ExposureMask | StructureNotifyMask | KeyPressMask);
-    for (;;) {
-        XNextEvent(display, &event);
-
-        switch (event.type) {
-            case KeyPress: {
-                XKeyEvent key = event.xkey;
-                KeySym sym = XLookupKeysym(&key, key.state & ShiftMask);
-                if (sym > 0x80) break;
-                if (!input(sym)) return EX_OK;
-                drawWindow();
-                XStoreName(display, window, status());
-            } break;
-
-            case ConfigureNotify: {
-                XConfigureEvent configure = event.xconfigure;
-                width = configure.width;
-                height = configure.height;
-                resizePixmap();
-                drawWindow();
-            } break;
-
-            case Expose: {
-                XExposeEvent expose = event.xexpose;
-                XCopyArea(
-                    display, pixmap, window, windowGc,
-                    expose.x, expose.y,
-                    expose.width, expose.height,
-                    expose.x, expose.y
-                );
-            } break;
-
-            case ClientMessage: {
-                XClientMessageEvent client = event.xclient;
-                if ((Atom)client.data.l[0] == WM_DELETE_WINDOW) return EX_OK;
-            } break;
-        }
-    }
+	int error = init(argc, argv);
+	if (error) return error;
+
+	createWindow();
+	resizePixmap();
+	drawWindow();
+
+	XStoreName(display, window, status());
+	XMapWindow(display, window);
+
+	XEvent event;
+	XSelectInput(display, window, ExposureMask | StructureNotifyMask | KeyPressMask);
+	for (;;) {
+		XNextEvent(display, &event);
+
+		switch (event.type) {
+			case KeyPress: {
+				XKeyEvent key = event.xkey;
+				KeySym sym = XLookupKeysym(&key, key.state & ShiftMask);
+				if (sym > 0x80) break;
+				if (!input(sym)) return EX_OK;
+				drawWindow();
+				XStoreName(display, window, status());
+			} break;
+
+			case ConfigureNotify: {
+				XConfigureEvent configure = event.xconfigure;
+				width = configure.width;
+				height = configure.height;
+				resizePixmap();
+				drawWindow();
+			} break;
+
+			case Expose: {
+				XExposeEvent expose = event.xexpose;
+				XCopyArea(
+					display, pixmap, window, windowGc,
+					expose.x, expose.y,
+					expose.width, expose.height,
+					expose.x, expose.y
+				);
+			} break;
+
+			case ClientMessage: {
+				XClientMessageEvent client = event.xclient;
+				if ((Atom)client.data.l[0] == WM_DELETE_WINDOW) return EX_OK;
+			} break;
+		}
+	}
 }
diff --git a/bin/gfxx.c b/bin/gfxx.c
index ebd53738..2a7eb36e 100644
--- a/bin/gfxx.c
+++ b/bin/gfxx.c
@@ -38,17 +38,17 @@
 #define GRAY(n) RGB(n, n, n)
 
 static enum {
-    COLOR_INDEXED,
-    COLOR_GRAYSCALE,
-    COLOR_RGB,
-    COLOR__COUNT,
+	COLOR_INDEXED,
+	COLOR_GRAYSCALE,
+	COLOR_RGB,
+	COLOR__COUNT,
 } space = COLOR_RGB;
 static const char *COLOR__STR[COLOR__COUNT] = { "indexed", "grayscale", "rgb" };
 static uint32_t palette[256];
 
 static enum {
-    ENDIAN_LITTLE,
-    ENDIAN_BIG,
+	ENDIAN_LITTLE,
+	ENDIAN_BIG,
 } byteOrder, bitOrder;
 
 enum { PAD, R, G, B };
@@ -68,425 +68,425 @@ static size_t size;
 static uint8_t *data;
 
 int init(int argc, char *argv[]) {
-    const char *pal = NULL;
-    const char *path = NULL;
-
-    int opt;
-    while (0 < (opt = getopt(argc, argv, "c:p:b:e:E:n:fmw:z:o:"))) {
-        switch (opt) {
-            case 'c': switch (optarg[0]) {
-                case 'i': space = COLOR_INDEXED; break;
-                case 'g': space = COLOR_GRAYSCALE; break;
-                case 'r': space = COLOR_RGB; break;
-                default: return EX_USAGE;
-            } break;
-            case 'p': pal = optarg; break;
-            case 'e': switch (optarg[0]) {
-                case 'l': byteOrder = ENDIAN_LITTLE; break;
-                case 'b': byteOrder = ENDIAN_BIG; break;
-                default: return EX_USAGE;
-            } break;
-            case 'E': switch (optarg[0]) {
-                case 'l': bitOrder = ENDIAN_LITTLE; break;
-                case 'b': bitOrder = ENDIAN_BIG; break;
-                default: return EX_USAGE;
-            } break;
-            case 'b': {
-                if (strlen(optarg) < 4) return EX_USAGE;
-                for (int i = 0; i < 4; ++i) {
-                    bits[i] = optarg[i] - '0';
-                }
-            } break;
-            case 'n': offset  = strtoul(optarg, NULL, 0); break;
-            case 'f': flip   ^= true; break;
-            case 'm': mirror ^= true; break;
-            case 'w': width   = strtoul(optarg, NULL, 0); break;
-            case 'z': scale   = strtoul(optarg, NULL, 0); break;
-            case 'o': prefix  = optarg; break;
-            default: return EX_USAGE;
-        }
-    }
-    if (argc > optind) path = argv[optind];
-    if (!width || !scale) return EX_USAGE;
-
-    if (pal) {
-        FILE *file = fopen(pal, "r");
-        if (!file) err(EX_NOINPUT, "%s", pal);
-        fread(palette, 4, 256, file);
-        if (ferror(file)) err(EX_IOERR, "%s", pal);
-        fclose(file);
-    } else {
-        for (int i = 0; i < 256; ++i) {
-            double h = i / 256.0 * 6.0;
-            double x = 1.0 - fabs(fmod(h, 2.0) - 1.0);
-            double r = 255.0, g = 255.0, b = 255.0;
-            if      (h <= 1.0) { g *= x; b = 0.0; }
-            else if (h <= 2.0) { r *= x; b = 0.0; }
-            else if (h <= 3.0) { r = 0.0; b *= x; }
-            else if (h <= 4.0) { r = 0.0; g *= x; }
-            else if (h <= 5.0) { r *= x; g = 0.0; }
-            else if (h <= 6.0) { g = 0.0; b *= x; }
-            palette[i] = (uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b;
-        }
-    }
-
-    if (path) {
-        int fd = open(path, O_RDONLY);
-        if (fd < 0) err(EX_NOINPUT, "%s", path);
-
-        struct stat stat;
-        int error = fstat(fd, &stat);
-        if (error) err(EX_IOERR, "%s", path);
-        size = stat.st_size;
-
-        data = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
-        if (data == MAP_FAILED) err(EX_IOERR, "%s", path);
-
-    } else {
-        size = 1024 * 1024;
-        data = malloc(size);
-        if (!data) err(EX_OSERR, "malloc(%zu)", size);
-
-        size = fread(data, 1, size, stdin);
-        if (ferror(stdin)) err(EX_IOERR, "(stdin)");
-    }
-
-    return EX_OK;
+	const char *pal = NULL;
+	const char *path = NULL;
+
+	int opt;
+	while (0 < (opt = getopt(argc, argv, "c:p:b:e:E:n:fmw:z:o:"))) {
+		switch (opt) {
+			case 'c': switch (optarg[0]) {
+				case 'i': space = COLOR_INDEXED; break;
+				case 'g': space = COLOR_GRAYSCALE; break;
+				case 'r': space = COLOR_RGB; break;
+				default: return EX_USAGE;
+			} break;
+			case 'p': pal = optarg; break;
+			case 'e': switch (optarg[0]) {
+				case 'l': byteOrder = ENDIAN_LITTLE; break;
+				case 'b': byteOrder = ENDIAN_BIG; break;
+				default: return EX_USAGE;
+			} break;
+			case 'E': switch (optarg[0]) {
+				case 'l': bitOrder = ENDIAN_LITTLE; break;
+				case 'b': bitOrder = ENDIAN_BIG; break;
+				default: return EX_USAGE;
+			} break;
+			case 'b': {
+				if (strlen(optarg) < 4) return EX_USAGE;
+				for (int i = 0; i < 4; ++i) {
+					bits[i] = optarg[i] - '0';
+				}
+			} break;
+			case 'n': offset  = strtoul(optarg, NULL, 0); break;
+			case 'f': flip   ^= true; break;
+			case 'm': mirror ^= true; break;
+			case 'w': width   = strtoul(optarg, NULL, 0); break;
+			case 'z': scale   = strtoul(optarg, NULL, 0); break;
+			case 'o': prefix  = optarg; break;
+			default: return EX_USAGE;
+		}
+	}
+	if (argc > optind) path = argv[optind];
+	if (!width || !scale) return EX_USAGE;
+
+	if (pal) {
+		FILE *file = fopen(pal, "r");
+		if (!file) err(EX_NOINPUT, "%s", pal);
+		fread(palette, 4, 256, file);
+		if (ferror(file)) err(EX_IOERR, "%s", pal);
+		fclose(file);
+	} else {
+		for (int i = 0; i < 256; ++i) {
+			double h = i / 256.0 * 6.0;
+			double x = 1.0 - fabs(fmod(h, 2.0) - 1.0);
+			double r = 255.0, g = 255.0, b = 255.0;
+			if      (h <= 1.0) { g *= x; b = 0.0; }
+			else if (h <= 2.0) { r *= x; b = 0.0; }
+			else if (h <= 3.0) { r = 0.0; b *= x; }
+			else if (h <= 4.0) { r = 0.0; g *= x; }
+			else if (h <= 5.0) { r *= x; g = 0.0; }
+			else if (h <= 6.0) { g = 0.0; b *= x; }
+			palette[i] = (uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b;
+		}
+	}
+
+	if (path) {
+		int fd = open(path, O_RDONLY);
+		if (fd < 0) err(EX_NOINPUT, "%s", path);
+
+		struct stat stat;
+		int error = fstat(fd, &stat);
+		if (error) err(EX_IOERR, "%s", path);
+		size = stat.st_size;
+
+		data = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+		if (data == MAP_FAILED) err(EX_IOERR, "%s", path);
+
+	} else {
+		size = 1024 * 1024;
+		data = malloc(size);
+		if (!data) err(EX_OSERR, "malloc(%zu)", size);
+
+		size = fread(data, 1, size, stdin);
+		if (ferror(stdin)) err(EX_IOERR, "(stdin)");
+	}
+
+	return EX_OK;
 }
 
 static char options[128];
 static void formatOptions(void) {
-    snprintf(
-        options, sizeof(options),
-        "gfxx -c %s -e%c -E%c -b %hhu%hhu%hhu%hhu -n 0x%zX %s%s-w %zu -z %zu",
-        COLOR__STR[space],
-        "lb"[byteOrder],
-        "lb"[bitOrder],
-        bits[PAD], bits[R], bits[G], bits[B],
-        offset,
-        flip ? "-f " : "",
-        mirror ? "-m " : "",
-        width,
-        scale
-    );
+	snprintf(
+		options, sizeof(options),
+		"gfxx -c %s -e%c -E%c -b %hhu%hhu%hhu%hhu -n 0x%zX %s%s-w %zu -z %zu",
+		COLOR__STR[space],
+		"lb"[byteOrder],
+		"lb"[bitOrder],
+		bits[PAD], bits[R], bits[G], bits[B],
+		offset,
+		flip ? "-f " : "",
+		mirror ? "-m " : "",
+		width,
+		scale
+	);
 }
 
 const char *status(void) {
-    formatOptions();
-    return options;
+	formatOptions();
+	return options;
 }
 
 struct Iter {
-    uint32_t *buf;
-    size_t bufWidth;
-    size_t bufHeight;
-    size_t left;
-    size_t x;
-    size_t y;
+	uint32_t *buf;
+	size_t bufWidth;
+	size_t bufHeight;
+	size_t left;
+	size_t x;
+	size_t y;
 };
 
 static struct Iter iter(uint32_t *buf, size_t bufWidth, size_t bufHeight) {
-    struct Iter it = { .buf = buf, .bufWidth = bufWidth, .bufHeight = bufHeight };
-    if (mirror) it.x = width - 1;
-    if (flip) it.y = bufHeight / scale - 1;
-    return it;
+	struct Iter it = { .buf = buf, .bufWidth = bufWidth, .bufHeight = bufHeight };
+	if (mirror) it.x = width - 1;
+	if (flip) it.y = bufHeight / scale - 1;
+	return it;
 }
 
 static bool nextX(struct Iter *it) {
-    if (mirror) {
-        if (it->x == it->left) return false;
-        it->x--;
-    } else {
-        it->x++;
-        if (it->x == it->left + width) return false;
-    }
-    return true;
+	if (mirror) {
+		if (it->x == it->left) return false;
+		it->x--;
+	} else {
+		it->x++;
+		if (it->x == it->left + width) return false;
+	}
+	return true;
 }
 
 static bool nextY(struct Iter *it) {
-    if (flip) {
-        if (it->y == 0) {
-            it->left += width;
-            it->y = it->bufHeight / scale;
-        }
-        it->y--;
-    } else {
-        it->y++;
-        if (it->y == it->bufHeight / scale) {
-            it->left += width;
-            it->y = 0;
-        }
-    }
-    it->x = it->left;
-    if (mirror) it->x += width - 1;
-    return (it->left < it->bufWidth / scale);
+	if (flip) {
+		if (it->y == 0) {
+			it->left += width;
+			it->y = it->bufHeight / scale;
+		}
+		it->y--;
+	} else {
+		it->y++;
+		if (it->y == it->bufHeight / scale) {
+			it->left += width;
+			it->y = 0;
+		}
+	}
+	it->x = it->left;
+	if (mirror) it->x += width - 1;
+	return (it->left < it->bufWidth / scale);
 }
 
 static bool next(struct Iter *it) {
-    return nextX(it) || nextY(it);
+	return nextX(it) || nextY(it);
 }
 
 static void put(const struct Iter *it, uint32_t pixel) {
-    size_t scaledX = it->x * scale;
-    size_t scaledY = it->y * scale;
-    for (size_t fillY = scaledY; fillY < scaledY + scale; ++fillY) {
-        if (fillY >= it->bufHeight) break;
-        for (size_t fillX = scaledX; fillX < scaledX + scale; ++fillX) {
-            if (fillX >= it->bufWidth) break;
-            it->buf[fillY * it->bufWidth + fillX] = pixel;
-        }
-    }
+	size_t scaledX = it->x * scale;
+	size_t scaledY = it->y * scale;
+	for (size_t fillY = scaledY; fillY < scaledY + scale; ++fillY) {
+		if (fillY >= it->bufHeight) break;
+		for (size_t fillX = scaledX; fillX < scaledX + scale; ++fillX) {
+			if (fillX >= it->bufWidth) break;
+			it->buf[fillY * it->bufWidth + fillX] = pixel;
+		}
+	}
 }
 
 static uint8_t interp(uint8_t b, uint32_t n) {
-    if (b == 8) return n;
-    if (b == 0) return 0;
-    return n * MASK(8) / MASK(b);
+	if (b == 8) return n;
+	if (b == 0) return 0;
+	return n * MASK(8) / MASK(b);
 }
 
 static uint32_t interpolate(uint32_t rgb) {
-    uint32_t r, g, b;
-    if (bitOrder == ENDIAN_LITTLE) {
-        b = rgb & MASK(bits[B]);
-        g = (rgb >>= bits[B]) & MASK(bits[G]);
-        r = (rgb >>= bits[G]) & MASK(bits[R]);
-    } else {
-        r = rgb & MASK(bits[R]);
-        g = (rgb >>= bits[R]) & MASK(bits[G]);
-        b = (rgb >>= bits[G]) & MASK(bits[B]);
-    }
-    return RGB(interp(bits[R], r), interp(bits[G], g), interp(bits[B], b));
+	uint32_t r, g, b;
+	if (bitOrder == ENDIAN_LITTLE) {
+		b = rgb & MASK(bits[B]);
+		g = (rgb >>= bits[B]) & MASK(bits[G]);
+		r = (rgb >>= bits[G]) & MASK(bits[R]);
+	} else {
+		r = rgb & MASK(bits[R]);
+		g = (rgb >>= bits[R]) & MASK(bits[G]);
+		b = (rgb >>= bits[G]) & MASK(bits[B]);
+	}
+	return RGB(interp(bits[R], r), interp(bits[G], g), interp(bits[B], b));
 }
 
 static void drawBits(struct Iter *it) {
-    for (size_t i = offset; i < size; ++i) {
-        for (uint8_t b = 0; b < 8; b += BITS_TOTAL) {
-            uint8_t n;
-            if (byteOrder == ENDIAN_BIG) {
-                n = data[i] >> (8 - BITS_TOTAL - b) & MASK(BITS_TOTAL);
-            } else {
-                n = data[i] >> b & MASK(BITS_TOTAL);
-            }
-
-            if (space == COLOR_INDEXED) {
-                put(it, palette[n]);
-            } else if (space == COLOR_GRAYSCALE) {
-                put(it, GRAY(interp(BITS_COLOR, n & MASK(BITS_COLOR))));
-            } else if (space == COLOR_RGB) {
-                put(it, interpolate(n));
-            }
-
-            if (!next(it)) return;
-        }
-    }
+	for (size_t i = offset; i < size; ++i) {
+		for (uint8_t b = 0; b < 8; b += BITS_TOTAL) {
+			uint8_t n;
+			if (byteOrder == ENDIAN_BIG) {
+				n = data[i] >> (8 - BITS_TOTAL - b) & MASK(BITS_TOTAL);
+			} else {
+				n = data[i] >> b & MASK(BITS_TOTAL);
+			}
+
+			if (space == COLOR_INDEXED) {
+				put(it, palette[n]);
+			} else if (space == COLOR_GRAYSCALE) {
+				put(it, GRAY(interp(BITS_COLOR, n & MASK(BITS_COLOR))));
+			} else if (space == COLOR_RGB) {
+				put(it, interpolate(n));
+			}
+
+			if (!next(it)) return;
+		}
+	}
 }
 
 static void drawBytes(struct Iter *it) {
-    uint8_t bytes = (BITS_TOTAL + 7) / 8;
-    for (size_t i = offset; i + bytes <= size; i += bytes) {
-        uint32_t n = 0;
-        for (size_t b = 0; b < bytes; ++b) {
-            n <<= 8;
-            n |= (byteOrder == ENDIAN_BIG) ? data[i + b] : data[i + bytes - b - 1];
-        }
-
-        if (space == COLOR_INDEXED) {
-            put(it, palette[n & 0xFF]);
-        } else if (space == COLOR_GRAYSCALE) {
-            put(it, GRAY(interp(BITS_COLOR, n & MASK(BITS_COLOR))));
-        } else if (space == COLOR_RGB) {
-            put(it, interpolate(n));
-        }
-
-        if (!next(it)) return;
-    }
+	uint8_t bytes = (BITS_TOTAL + 7) / 8;
+	for (size_t i = offset; i + bytes <= size; i += bytes) {
+		uint32_t n = 0;
+		for (size_t b = 0; b < bytes; ++b) {
+			n <<= 8;
+			n |= (byteOrder == ENDIAN_BIG) ? data[i + b] : data[i + bytes - b - 1];
+		}
+
+		if (space == COLOR_INDEXED) {
+			put(it, palette[n & 0xFF]);
+		} else if (space == COLOR_GRAYSCALE) {
+			put(it, GRAY(interp(BITS_COLOR, n & MASK(BITS_COLOR))));
+		} else if (space == COLOR_RGB) {
+			put(it, interpolate(n));
+		}
+
+		if (!next(it)) return;
+	}
 }
 
 static struct {
-    unsigned counter;
-    char path[FILENAME_MAX];
-    FILE *file;
+	unsigned counter;
+	char path[FILENAME_MAX];
+	FILE *file;
 } out;
 static void outOpen(const char *ext) {
-    snprintf(out.path, sizeof(out.path), "%s%04u.%s", prefix, ++out.counter, ext);
-    out.file = fopen(out.path, "wx");
-    if (out.file) {
-        printf("%s\n", out.path);
-    } else {
-        warn("%s", out.path);
-    }
+	snprintf(out.path, sizeof(out.path), "%s%04u.%s", prefix, ++out.counter, ext);
+	out.file = fopen(out.path, "wx");
+	if (out.file) {
+		printf("%s\n", out.path);
+	} else {
+		warn("%s", out.path);
+	}
 }
 
 static uint32_t crc;
 static void pngWrite(const void *ptr, size_t size) {
-    fwrite(ptr, size, 1, out.file);
-    if (ferror(out.file)) err(EX_IOERR, "%s", out.path);
-    crc = crc32(crc, ptr, size);
+	fwrite(ptr, size, 1, out.file);
+	if (ferror(out.file)) err(EX_IOERR, "%s", out.path);
+	crc = crc32(crc, ptr, size);
 }
 static void pngUint(uint32_t host) {
-    uint32_t net = htonl(host);
-    pngWrite(&net, 4);
+	uint32_t net = htonl(host);
+	pngWrite(&net, 4);
 }
 static void pngChunk(const char *type, uint32_t size) {
-    pngUint(size);
-    crc = crc32(0, Z_NULL, 0);
-    pngWrite(type, 4);
+	pngUint(size);
+	crc = crc32(0, Z_NULL, 0);
+	pngWrite(type, 4);
 }
 
 static void pngDump(uint32_t *src, size_t srcWidth, size_t srcHeight) {
-    int error;
-
-    size_t stride = 1 + 3 * srcWidth;
-    uint8_t data[stride * srcHeight];
-    for (size_t y = 0; y < srcHeight; ++y) {
-        data[y * stride] = 0;
-        for (size_t x = 0; x < srcWidth; ++x) {
-            uint8_t *p = &data[y * stride + 1 + 3 * x];
-            p[0] = src[y * srcWidth + x] >> 16;
-            p[1] = src[y * srcWidth + x] >> 8;
-            p[2] = src[y * srcWidth + x];
-        }
-    }
-
-    uLong deflateSize = compressBound(sizeof(data));
-    uint8_t deflate[deflateSize];
-    error = compress(deflate, &deflateSize, data, sizeof(data));
-    if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error);
-
-    outOpen("png");
-    if (!out.file) return;
-
-    const uint8_t SIGNATURE[] = { 0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n' };
-    const uint8_t HEADER[] = { 8, 2, 0, 0, 0 }; // 8-bit truecolor
-    const char SOFTWARE[] = "Software";
-    formatOptions();
-    uint8_t sbit[3] = { MAX(bits[R], 1), MAX(bits[G], 1), MAX(bits[B], 1) };
-
-    pngWrite(SIGNATURE, sizeof(SIGNATURE));
-
-    pngChunk("IHDR", 4 + 4 + sizeof(HEADER));
-    pngUint(srcWidth);
-    pngUint(srcHeight);
-    pngWrite(HEADER, sizeof(HEADER));
-    pngUint(crc);
-
-    pngChunk("tEXt", sizeof(SOFTWARE) + strlen(options));
-    pngWrite(SOFTWARE, sizeof(SOFTWARE));
-    pngWrite(options, strlen(options));
-    pngUint(crc);
-
-    pngChunk("sBIT", sizeof(sbit));
-    pngWrite(sbit, sizeof(sbit));
-    pngUint(crc);
-
-    pngChunk("IDAT", deflateSize);
-    pngWrite(deflate, deflateSize);
-    pngUint(crc);
-
-    pngChunk("IEND", 0);
-    pngUint(crc);
-
-    error = fclose(out.file);
-    if (error) err(EX_IOERR, "%s", out.path);
+	int error;
+
+	size_t stride = 1 + 3 * srcWidth;
+	uint8_t data[stride * srcHeight];
+	for (size_t y = 0; y < srcHeight; ++y) {
+		data[y * stride] = 0;
+		for (size_t x = 0; x < srcWidth; ++x) {
+			uint8_t *p = &data[y * stride + 1 + 3 * x];
+			p[0] = src[y * srcWidth + x] >> 16;
+			p[1] = src[y * srcWidth + x] >> 8;
+			p[2] = src[y * srcWidth + x];
+		}
+	}
+
+	uLong deflateSize = compressBound(sizeof(data));
+	uint8_t deflate[deflateSize];
+	error = compress(deflate, &deflateSize, data, sizeof(data));
+	if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error);
+
+	outOpen("png");
+	if (!out.file) return;
+
+	const uint8_t SIGNATURE[] = { 0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n' };
+	const uint8_t HEADER[] = { 8, 2, 0, 0, 0 }; // 8-bit truecolor
+	const char SOFTWARE[] = "Software";
+	formatOptions();
+	uint8_t sbit[3] = { MAX(bits[R], 1), MAX(bits[G], 1), MAX(bits[B], 1) };
+
+	pngWrite(SIGNATURE, sizeof(SIGNATURE));
+
+	pngChunk("IHDR", 4 + 4 + sizeof(HEADER));
+	pngUint(srcWidth);
+	pngUint(srcHeight);
+	pngWrite(HEADER, sizeof(HEADER));
+	pngUint(crc);
+
+	pngChunk("tEXt", sizeof(SOFTWARE) + strlen(options));
+	pngWrite(SOFTWARE, sizeof(SOFTWARE));
+	pngWrite(options, strlen(options));
+	pngUint(crc);
+
+	pngChunk("sBIT", sizeof(sbit));
+	pngWrite(sbit, sizeof(sbit));
+	pngUint(crc);
+
+	pngChunk("IDAT", deflateSize);
+	pngWrite(deflate, deflateSize);
+	pngUint(crc);
+
+	pngChunk("IEND", 0);
+	pngUint(crc);
+
+	error = fclose(out.file);
+	if (error) err(EX_IOERR, "%s", out.path);
 }
 
 static enum {
-    DUMP_NONE,
-    DUMP_ONE,
-    DUMP_ALL,
+	DUMP_NONE,
+	DUMP_ONE,
+	DUMP_ALL,
 } dump;
 
 void draw(uint32_t *buf, size_t bufWidth, size_t bufHeight) {
-    memset(buf, 0, 4 * bufWidth * bufHeight);
-    struct Iter it = iter(buf, bufWidth, bufHeight);
-    if (BITS_TOTAL >= 8) {
-        drawBytes(&it);
-    } else {
-        drawBits(&it);
-    }
-    if (dump) pngDump(buf, bufWidth, bufHeight);
-    if (dump == DUMP_ONE) dump = DUMP_NONE;
+	memset(buf, 0, 4 * bufWidth * bufHeight);
+	struct Iter it = iter(buf, bufWidth, bufHeight);
+	if (BITS_TOTAL >= 8) {
+		drawBytes(&it);
+	} else {
+		drawBits(&it);
+	}
+	if (dump) pngDump(buf, bufWidth, bufHeight);
+	if (dump == DUMP_ONE) dump = DUMP_NONE;
 }
 
 static void palSample(void) {
-    size_t temp = scale;
-    scale = 1;
-    draw(palette, 256, 1);
-    scale = temp;
+	size_t temp = scale;
+	scale = 1;
+	draw(palette, 256, 1);
+	scale = temp;
 }
 
 static void palDump(void) {
-    outOpen("dat");
-    if (!out.file) return;
+	outOpen("dat");
+	if (!out.file) return;
 
-    fwrite(palette, 4, 256, out.file);
-    if (ferror(out.file)) err(EX_IOERR, "%s", out.path);
+	fwrite(palette, 4, 256, out.file);
+	if (ferror(out.file)) err(EX_IOERR, "%s", out.path);
 
-    int error = fclose(out.file);
-    if (error) err(EX_IOERR, "%s", out.path);
+	int error = fclose(out.file);
+	if (error) err(EX_IOERR, "%s", out.path);
 }
 
 static const uint8_t PRESETS[][4] = {
-    { 0, 0, 1, 0 },
-    { 0, 1, 1, 0 },
-    { 1, 1, 1, 1 },
-    { 2, 2, 2, 2 },
-    { 0, 3, 3, 2 },
-    { 4, 4, 4, 4 },
-    { 1, 5, 5, 5 },
-    { 0, 5, 6, 5 },
-    { 0, 8, 8, 8 },
-    { 8, 8, 8, 8 },
+	{ 0, 0, 1, 0 },
+	{ 0, 1, 1, 0 },
+	{ 1, 1, 1, 1 },
+	{ 2, 2, 2, 2 },
+	{ 0, 3, 3, 2 },
+	{ 4, 4, 4, 4 },
+	{ 1, 5, 5, 5 },
+	{ 0, 5, 6, 5 },
+	{ 0, 8, 8, 8 },
+	{ 8, 8, 8, 8 },
 };
 #define PRESETS_LEN (sizeof(PRESETS) / sizeof(PRESETS[0]))
 
 static uint8_t preset = PRESETS_LEN - 1;
 static void setPreset(void) {
-    bits[PAD] = PRESETS[preset][PAD];
-    bits[R] = PRESETS[preset][R];
-    bits[G] = PRESETS[preset][G];
-    bits[B] = PRESETS[preset][B];
+	bits[PAD] = PRESETS[preset][PAD];
+	bits[R] = PRESETS[preset][R];
+	bits[G] = PRESETS[preset][G];
+	bits[B] = PRESETS[preset][B];
 }
 
 static void setBit(char in) {
-    static uint8_t bit = 0;
-    bits[bit++] = in - '0';
-    bit &= 3;
+	static uint8_t bit = 0;
+	bits[bit++] = in - '0';
+	bit &= 3;
 }
 
 bool input(char in) {
-    size_t pixel = (BITS_TOTAL + 7) / 8;
-    size_t row = width * BITS_TOTAL / 8;
-    switch (in) {
-        case 'q': return false;
-        break; case 'x': dump = DUMP_ONE;
-        break; case 'X': dump ^= DUMP_ALL;
-        break; case 'o': formatOptions(); printf("%s\n", options);
-        break; case '[': if (!space--) space = COLOR__COUNT - 1;
-        break; case ']': if (++space == COLOR__COUNT) space = 0;
-        break; case 'p': palSample();
-        break; case 'P': palDump();
-        break; case '{': if (!preset--) preset = PRESETS_LEN - 1; setPreset();
-        break; case '}': if (++preset == PRESETS_LEN) preset = 0; setPreset();
-        break; case 'e': byteOrder ^= ENDIAN_BIG;
-        break; case 'E': bitOrder ^= ENDIAN_BIG;
-        break; case 'h': if (offset) offset--;
-        break; case 'j': offset += pixel;
-        break; case 'k': if (offset >= pixel) offset -= pixel;
-        break; case 'l': offset++;
-        break; case 'H': if (offset >= row) offset -= row;
-        break; case 'J': offset += width * row;
-        break; case 'K': if (offset >= width * row) offset -= width * row;
-        break; case 'L': offset += row;
-        break; case '.': width++;
-        break; case ',': if (width > 1) width--;
-        break; case '>': width *= 2;
-        break; case '<': if (width > 1) width /= 2;
-        break; case 'f': flip ^= true;
-        break; case 'm': mirror ^= true;
-        break; case '+': scale++;
-        break; case '-': if (scale > 1) scale--;
-        break; default: if (in >= '0' && in <= '9') setBit(in);
-    }
-    return true;
+	size_t pixel = (BITS_TOTAL + 7) / 8;
+	size_t row = width * BITS_TOTAL / 8;
+	switch (in) {
+		case 'q': return false;
+				  break; case 'x': dump = DUMP_ONE;
+				  break; case 'X': dump ^= DUMP_ALL;
+				  break; case 'o': formatOptions(); printf("%s\n", options);
+				  break; case '[': if (!space--) space = COLOR__COUNT - 1;
+				  break; case ']': if (++space == COLOR__COUNT) space = 0;
+				  break; case 'p': palSample();
+				  break; case 'P': palDump();
+				  break; case '{': if (!preset--) preset = PRESETS_LEN - 1; setPreset();
+				  break; case '}': if (++preset == PRESETS_LEN) preset = 0; setPreset();
+				  break; case 'e': byteOrder ^= ENDIAN_BIG;
+				  break; case 'E': bitOrder ^= ENDIAN_BIG;
+				  break; case 'h': if (offset) offset--;
+				  break; case 'j': offset += pixel;
+				  break; case 'k': if (offset >= pixel) offset -= pixel;
+				  break; case 'l': offset++;
+				  break; case 'H': if (offset >= row) offset -= row;
+				  break; case 'J': offset += width * row;
+				  break; case 'K': if (offset >= width * row) offset -= width * row;
+				  break; case 'L': offset += row;
+				  break; case '.': width++;
+				  break; case ',': if (width > 1) width--;
+				  break; case '>': width *= 2;
+				  break; case '<': if (width > 1) width /= 2;
+				  break; case 'f': flip ^= true;
+				  break; case 'm': mirror ^= true;
+				  break; case '+': scale++;
+				  break; case '-': if (scale > 1) scale--;
+				  break; default: if (in >= '0' && in <= '9') setBit(in);
+	}
+	return true;
 }
diff --git a/bin/glitch.c b/bin/glitch.c
index 5280d7e2..6732522d 100644
--- a/bin/glitch.c
+++ b/bin/glitch.c
@@ -35,455 +35,455 @@ static FILE *file;
 static uint32_t crc;
 
 static void readExpect(void *ptr, size_t size, const char *expect) {
-    fread(ptr, size, 1, file);
-    if (ferror(file)) err(EX_IOERR, "%s", path);
-    if (feof(file)) errx(EX_DATAERR, "%s: missing %s", path, expect);
-    crc = crc32(crc, ptr, size);
+	fread(ptr, size, 1, file);
+	if (ferror(file)) err(EX_IOERR, "%s", path);
+	if (feof(file)) errx(EX_DATAERR, "%s: missing %s", path, expect);
+	crc = crc32(crc, ptr, size);
 }
 
 static void writeExpect(const void *ptr, size_t size) {
-    fwrite(ptr, size, 1, file);
-    if (ferror(file)) err(EX_IOERR, "%s", path);
-    crc = crc32(crc, ptr, size);
+	fwrite(ptr, size, 1, file);
+	if (ferror(file)) err(EX_IOERR, "%s", path);
+	crc = crc32(crc, ptr, size);
 }
 
 static const uint8_t SIGNATURE[8] = {
-    0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n'
+	0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n'
 };
 
 static void readSignature(void) {
-    uint8_t signature[8];
-    readExpect(signature, 8, "signature");
-    if (0 != memcmp(signature, SIGNATURE, 8)) {
-        errx(EX_DATAERR, "%s: invalid signature", path);
-    }
+	uint8_t signature[8];
+	readExpect(signature, 8, "signature");
+	if (0 != memcmp(signature, SIGNATURE, 8)) {
+		errx(EX_DATAERR, "%s: invalid signature", path);
+	}
 }
 
 static void writeSignature(void) {
-    writeExpect(SIGNATURE, sizeof(SIGNATURE));
+	writeExpect(SIGNATURE, sizeof(SIGNATURE));
 }
 
 struct PACKED Chunk {
-    uint32_t size;
-    char type[4];
+	uint32_t size;
+	char type[4];
 };
 
 static const char *typeStr(struct Chunk chunk) {
-    static char buf[5];
-    memcpy(buf, chunk.type, 4);
-    return buf;
+	static char buf[5];
+	memcpy(buf, chunk.type, 4);
+	return buf;
 }
 
 static struct Chunk readChunk(void) {
-    struct Chunk chunk;
-    readExpect(&chunk, sizeof(chunk), "chunk");
-    chunk.size = ntohl(chunk.size);
-    crc = crc32(CRC_INIT, (Byte *)chunk.type, sizeof(chunk.type));
-    return chunk;
+	struct Chunk chunk;
+	readExpect(&chunk, sizeof(chunk), "chunk");
+	chunk.size = ntohl(chunk.size);
+	crc = crc32(CRC_INIT, (Byte *)chunk.type, sizeof(chunk.type));
+	return chunk;
 }
 
 static void writeChunk(struct Chunk chunk) {
-    chunk.size = htonl(chunk.size);
-    writeExpect(&chunk, sizeof(chunk));
-    crc = crc32(CRC_INIT, (Byte *)chunk.type, sizeof(chunk.type));
+	chunk.size = htonl(chunk.size);
+	writeExpect(&chunk, sizeof(chunk));
+	crc = crc32(CRC_INIT, (Byte *)chunk.type, sizeof(chunk.type));
 }
 
 static void readCrc(void) {
-    uint32_t expected = crc;
-    uint32_t found;
-    readExpect(&found, sizeof(found), "CRC32");
-    found = ntohl(found);
-    if (found != expected) {
-        errx(
-            EX_DATAERR, "%s: expected CRC32 %08X, found %08X",
-            path, expected, found
-        );
-    }
+	uint32_t expected = crc;
+	uint32_t found;
+	readExpect(&found, sizeof(found), "CRC32");
+	found = ntohl(found);
+	if (found != expected) {
+		errx(
+			EX_DATAERR, "%s: expected CRC32 %08X, found %08X",
+			path, expected, found
+		);
+	}
 }
 
 static void writeCrc(void) {
-    uint32_t net = htonl(crc);
-    writeExpect(&net, sizeof(net));
+	uint32_t net = htonl(crc);
+	writeExpect(&net, sizeof(net));
 }
 
 static void skipChunk(struct Chunk chunk) {
-    uint8_t discard[chunk.size];
-    readExpect(discard, sizeof(discard), "chunk data");
-    readCrc();
+	uint8_t discard[chunk.size];
+	readExpect(discard, sizeof(discard), "chunk data");
+	readCrc();
 }
 
 static struct PACKED {
-    uint32_t width;
-    uint32_t height;
-    uint8_t depth;
-    enum PACKED {
-        GRAYSCALE       = 0,
-        TRUECOLOR       = 2,
-        INDEXED         = 3,
-        GRAYSCALE_ALPHA = 4,
-        TRUECOLOR_ALPHA = 6,
-    } color;
-    uint8_t compression;
-    uint8_t filter;
-    uint8_t interlace;
+	uint32_t width;
+	uint32_t height;
+	uint8_t depth;
+	enum PACKED {
+		GRAYSCALE       = 0,
+		TRUECOLOR       = 2,
+		INDEXED         = 3,
+		GRAYSCALE_ALPHA = 4,
+		TRUECOLOR_ALPHA = 6,
+	} color;
+	uint8_t compression;
+	uint8_t filter;
+	uint8_t interlace;
 } header;
 static_assert(13 == sizeof(header), "header size");
 
 static size_t lineSize(void) {
-    switch (header.color) {
-        case GRAYSCALE:       return (header.width * 1 * header.depth + 7) / 8;
-        case TRUECOLOR:       return (header.width * 3 * header.depth + 7) / 8;
-        case INDEXED:         return (header.width * 1 * header.depth + 7) / 8;
-        case GRAYSCALE_ALPHA: return (header.width * 2 * header.depth + 7) / 8;
-        case TRUECOLOR_ALPHA: return (header.width * 4 * header.depth + 7) / 8;
-        default: abort();
-    }
+	switch (header.color) {
+		case GRAYSCALE:       return (header.width * 1 * header.depth + 7) / 8;
+		case TRUECOLOR:       return (header.width * 3 * header.depth + 7) / 8;
+		case INDEXED:         return (header.width * 1 * header.depth + 7) / 8;
+		case GRAYSCALE_ALPHA: return (header.width * 2 * header.depth + 7) / 8;
+		case TRUECOLOR_ALPHA: return (header.width * 4 * header.depth + 7) / 8;
+		default: abort();
+	}
 }
 
 static size_t dataSize(void) {
-    return (1 + lineSize()) * header.height;
+	return (1 + lineSize()) * header.height;
 }
 
 static void readHeader(void) {
-    struct Chunk ihdr = readChunk();
-    if (0 != memcmp(ihdr.type, "IHDR", 4)) {
-        errx(EX_DATAERR, "%s: expected IHDR, found %s", path, typeStr(ihdr));
-    }
-    if (ihdr.size != sizeof(header)) {
-        errx(
-            EX_DATAERR, "%s: expected IHDR size %zu, found %u",
-            path, sizeof(header), ihdr.size
-        );
-    }
-    readExpect(&header, sizeof(header), "header");
-    readCrc();
-    header.width = ntohl(header.width);
-    header.height = ntohl(header.height);
-    if (!header.width) errx(EX_DATAERR, "%s: invalid width 0", path);
-    if (!header.height) errx(EX_DATAERR, "%s: invalid height 0", path);
+	struct Chunk ihdr = readChunk();
+	if (0 != memcmp(ihdr.type, "IHDR", 4)) {
+		errx(EX_DATAERR, "%s: expected IHDR, found %s", path, typeStr(ihdr));
+	}
+	if (ihdr.size != sizeof(header)) {
+		errx(
+			EX_DATAERR, "%s: expected IHDR size %zu, found %u",
+			path, sizeof(header), ihdr.size
+		);
+	}
+	readExpect(&header, sizeof(header), "header");
+	readCrc();
+	header.width = ntohl(header.width);
+	header.height = ntohl(header.height);
+	if (!header.width) errx(EX_DATAERR, "%s: invalid width 0", path);
+	if (!header.height) errx(EX_DATAERR, "%s: invalid height 0", path);
 }
 
 static void writeHeader(void) {
-    struct Chunk ihdr = { .size = sizeof(header), .type = "IHDR" };
-    writeChunk(ihdr);
-    header.width = htonl(header.width);
-    header.height = htonl(header.height);
-    writeExpect(&header, sizeof(header));
-    writeCrc();
-    header.width = ntohl(header.width);
-    header.height = ntohl(header.height);
+	struct Chunk ihdr = { .size = sizeof(header), .type = "IHDR" };
+	writeChunk(ihdr);
+	header.width = htonl(header.width);
+	header.height = htonl(header.height);
+	writeExpect(&header, sizeof(header));
+	writeCrc();
+	header.width = ntohl(header.width);
+	header.height = ntohl(header.height);
 }
 
 static struct {
-    uint32_t len;
-    uint8_t entries[256][3];
+	uint32_t len;
+	uint8_t entries[256][3];
 } palette;
 
 static void readPalette(void) {
-    struct Chunk chunk;
-    for (;;) {
-        chunk = readChunk();
-        if (0 == memcmp(chunk.type, "PLTE", 4)) break;
-        skipChunk(chunk);
-    }
-    palette.len = chunk.size / 3;
-    readExpect(palette.entries, chunk.size, "palette data");
-    readCrc();
+	struct Chunk chunk;
+	for (;;) {
+		chunk = readChunk();
+		if (0 == memcmp(chunk.type, "PLTE", 4)) break;
+		skipChunk(chunk);
+	}
+	palette.len = chunk.size / 3;
+	readExpect(palette.entries, chunk.size, "palette data");
+	readCrc();
 }
 
 static void writePalette(void) {
-    struct Chunk plte = { .size = 3 * palette.len, .type = "PLTE" };
-    writeChunk(plte);
-    writeExpect(palette.entries, plte.size);
-    writeCrc();
+	struct Chunk plte = { .size = 3 * palette.len, .type = "PLTE" };
+	writeChunk(plte);
+	writeExpect(palette.entries, plte.size);
+	writeCrc();
 }
 
 static uint8_t *data;
 
 static void readData(void) {
-    data = malloc(dataSize());
-    if (!data) err(EX_OSERR, "malloc(%zu)", dataSize());
-
-    struct z_stream_s stream = { .next_out = data, .avail_out = dataSize() };
-    int error = inflateInit(&stream);
-    if (error != Z_OK) errx(EX_SOFTWARE, "%s: inflateInit: %s", path, stream.msg);
-
-    for (;;) {
-        struct Chunk chunk = readChunk();
-        if (0 == memcmp(chunk.type, "IDAT", 4)) {
-            uint8_t idat[chunk.size];
-            readExpect(idat, sizeof(idat), "image data");
-            readCrc();
-
-            stream.next_in = idat;
-            stream.avail_in = sizeof(idat);
-            int error = inflate(&stream, Z_SYNC_FLUSH);
-            if (error == Z_STREAM_END) break;
-            if (error != Z_OK) errx(EX_DATAERR, "%s: inflate: %s", path, stream.msg);
-
-        } else if (0 == memcmp(chunk.type, "IEND", 4)) {
-            errx(EX_DATAERR, "%s: missing IDAT chunk", path);
-        } else {
-            skipChunk(chunk);
-        }
-    }
-
-    inflateEnd(&stream);
-    if (stream.total_out != dataSize()) {
-        errx(
-            EX_DATAERR, "%s: expected data size %zu, found %lu",
-            path, dataSize(), stream.total_out
-        );
-    }
+	data = malloc(dataSize());
+	if (!data) err(EX_OSERR, "malloc(%zu)", dataSize());
+
+	struct z_stream_s stream = { .next_out = data, .avail_out = dataSize() };
+	int error = inflateInit(&stream);
+	if (error != Z_OK) errx(EX_SOFTWARE, "%s: inflateInit: %s", path, stream.msg);
+
+	for (;;) {
+		struct Chunk chunk = readChunk();
+		if (0 == memcmp(chunk.type, "IDAT", 4)) {
+			uint8_t idat[chunk.size];
+			readExpect(idat, sizeof(idat), "image data");
+			readCrc();
+
+			stream.next_in = idat;
+			stream.avail_in = sizeof(idat);
+			int error = inflate(&stream, Z_SYNC_FLUSH);
+			if (error == Z_STREAM_END) break;
+			if (error != Z_OK) errx(EX_DATAERR, "%s: inflate: %s", path, stream.msg);
+
+		} else if (0 == memcmp(chunk.type, "IEND", 4)) {
+			errx(EX_DATAERR, "%s: missing IDAT chunk", path);
+		} else {
+			skipChunk(chunk);
+		}
+	}
+
+	inflateEnd(&stream);
+	if (stream.total_out != dataSize()) {
+		errx(
+			EX_DATAERR, "%s: expected data size %zu, found %lu",
+			path, dataSize(), stream.total_out
+		);
+	}
 }
 
 static void writeData(void) {
-    uLong size = compressBound(dataSize());
-    uint8_t deflate[size];
-    int error = compress2(deflate, &size, data, dataSize(), Z_BEST_SPEED);
-    if (error != Z_OK) errx(EX_SOFTWARE, "%s: compress2: %d", path, error);
-
-    struct Chunk idat = { .size = size, .type = "IDAT" };
-    writeChunk(idat);
-    writeExpect(deflate, size);
-    writeCrc();
+	uLong size = compressBound(dataSize());
+	uint8_t deflate[size];
+	int error = compress2(deflate, &size, data, dataSize(), Z_BEST_SPEED);
+	if (error != Z_OK) errx(EX_SOFTWARE, "%s: compress2: %d", path, error);
+
+	struct Chunk idat = { .size = size, .type = "IDAT" };
+	writeChunk(idat);
+	writeExpect(deflate, size);
+	writeCrc();
 }
 
 static void writeEnd(void) {
-    struct Chunk iend = { .size = 0, .type = "IEND" };
-    writeChunk(iend);
-    writeCrc();
+	struct Chunk iend = { .size = 0, .type = "IEND" };
+	writeChunk(iend);
+	writeCrc();
 }
 
 enum PACKED Filter {
-    NONE,
-    SUB,
-    UP,
-    AVERAGE,
-    PAETH,
-    FILTER_COUNT,
+	NONE,
+	SUB,
+	UP,
+	AVERAGE,
+	PAETH,
+	FILTER_COUNT,
 };
 
 static struct {
-    bool brokenPaeth;
-    bool filt;
-    bool recon;
-    uint8_t declareFilter;
-    uint8_t applyFilter;
-    enum Filter declareFilters[255];
-    enum Filter applyFilters[255];
+	bool brokenPaeth;
+	bool filt;
+	bool recon;
+	uint8_t declareFilter;
+	uint8_t applyFilter;
+	enum Filter declareFilters[255];
+	enum Filter applyFilters[255];
 } options;
 
 struct Bytes {
-    uint8_t x;
-    uint8_t a;
-    uint8_t b;
-    uint8_t c;
+	uint8_t x;
+	uint8_t a;
+	uint8_t b;
+	uint8_t c;
 };
 
 static uint8_t paethPredictor(struct Bytes f) {
-    int32_t p = (int32_t)f.a + (int32_t)f.b - (int32_t)f.c;
-    int32_t pa = abs(p - (int32_t)f.a);
-    int32_t pb = abs(p - (int32_t)f.b);
-    int32_t pc = abs(p - (int32_t)f.c);
-    if (pa <= pb && pa <= pc) return f.a;
-    if (options.brokenPaeth) {
-        if (pb < pc) return f.b;
-    } else {
-        if (pb <= pc) return f.b;
-    }
-    return f.c;
+	int32_t p = (int32_t)f.a + (int32_t)f.b - (int32_t)f.c;
+	int32_t pa = abs(p - (int32_t)f.a);
+	int32_t pb = abs(p - (int32_t)f.b);
+	int32_t pc = abs(p - (int32_t)f.c);
+	if (pa <= pb && pa <= pc) return f.a;
+	if (options.brokenPaeth) {
+		if (pb < pc) return f.b;
+	} else {
+		if (pb <= pc) return f.b;
+	}
+	return f.c;
 }
 
 static uint8_t recon(enum Filter type, struct Bytes f) {
-    switch (type) {
-        case NONE:    return f.x;
-        case SUB:     return f.x + f.a;
-        case UP:      return f.x + f.b;
-        case AVERAGE: return f.x + ((uint32_t)f.a + (uint32_t)f.b) / 2;
-        case PAETH:   return f.x + paethPredictor(f);
-        default:      abort();
-    }
+	switch (type) {
+		case NONE:    return f.x;
+		case SUB:     return f.x + f.a;
+		case UP:      return f.x + f.b;
+		case AVERAGE: return f.x + ((uint32_t)f.a + (uint32_t)f.b) / 2;
+		case PAETH:   return f.x + paethPredictor(f);
+		default:      abort();
+	}
 }
 
 static uint8_t filt(enum Filter type, struct Bytes f) {
-    switch (type) {
-        case NONE:    return f.x;
-        case SUB:     return f.x - f.a;
-        case UP:      return f.x - f.b;
-        case AVERAGE: return f.x - ((uint32_t)f.a + (uint32_t)f.b) / 2;
-        case PAETH:   return f.x - paethPredictor(f);
-        default:      abort();
-    }
+	switch (type) {
+		case NONE:    return f.x;
+		case SUB:     return f.x - f.a;
+		case UP:      return f.x - f.b;
+		case AVERAGE: return f.x - ((uint32_t)f.a + (uint32_t)f.b) / 2;
+		case PAETH:   return f.x - paethPredictor(f);
+		default:      abort();
+	}
 }
 
 static struct Line {
-    enum Filter type;
-    uint8_t data[];
+	enum Filter type;
+	uint8_t data[];
 } **lines;
 
 static void scanlines(void) {
-    lines = calloc(header.height, sizeof(*lines));
-    if (!lines) err(EX_OSERR, "calloc(%u, %zu)", header.height, sizeof(*lines));
-
-    size_t stride = 1 + lineSize();
-    for (uint32_t y = 0; y < header.height; ++y) {
-        lines[y] = (struct Line *)&data[y * stride];
-        if (lines[y]->type >= FILTER_COUNT) {
-            errx(EX_DATAERR, "%s: invalid filter type %hhu", path, lines[y]->type);
-        }
-    }
+	lines = calloc(header.height, sizeof(*lines));
+	if (!lines) err(EX_OSERR, "calloc(%u, %zu)", header.height, sizeof(*lines));
+
+	size_t stride = 1 + lineSize();
+	for (uint32_t y = 0; y < header.height; ++y) {
+		lines[y] = (struct Line *)&data[y * stride];
+		if (lines[y]->type >= FILTER_COUNT) {
+			errx(EX_DATAERR, "%s: invalid filter type %hhu", path, lines[y]->type);
+		}
+	}
 }
 
 static struct Bytes origBytes(uint32_t y, size_t i) {
-    size_t pixelSize = lineSize() / header.width;
-    if (!pixelSize) pixelSize = 1;
-    bool a = (i >= pixelSize), b = (y > 0), c = (a && b);
-    return (struct Bytes) {
-        .x = lines[y]->data[i],
-        .a = a ? lines[y]->data[i - pixelSize] : 0,
-        .b = b ? lines[y - 1]->data[i] : 0,
-        .c = c ? lines[y - 1]->data[i - pixelSize] : 0,
-    };
+	size_t pixelSize = lineSize() / header.width;
+	if (!pixelSize) pixelSize = 1;
+	bool a = (i >= pixelSize), b = (y > 0), c = (a && b);
+	return (struct Bytes) {
+		.x = lines[y]->data[i],
+		.a = a ? lines[y]->data[i - pixelSize] : 0,
+		.b = b ? lines[y - 1]->data[i] : 0,
+		.c = c ? lines[y - 1]->data[i - pixelSize] : 0,
+	};
 }
 
 static void reconData(void) {
-    for (uint32_t y = 0; y < header.height; ++y) {
-        for (size_t i = 0; i < lineSize(); ++i) {
-            if (options.filt) {
-                lines[y]->data[i] = filt(lines[y]->type, origBytes(y, i));
-            } else {
-                lines[y]->data[i] = recon(lines[y]->type, origBytes(y, i));
-            }
-        }
-        lines[y]->type = NONE;
-    }
+	for (uint32_t y = 0; y < header.height; ++y) {
+		for (size_t i = 0; i < lineSize(); ++i) {
+			if (options.filt) {
+				lines[y]->data[i] = filt(lines[y]->type, origBytes(y, i));
+			} else {
+				lines[y]->data[i] = recon(lines[y]->type, origBytes(y, i));
+			}
+		}
+		lines[y]->type = NONE;
+	}
 }
 
 static void filterData(void) {
-    for (uint32_t y = header.height - 1; y < header.height; --y) {
-        uint8_t filter[FILTER_COUNT][lineSize()];
-        uint32_t heuristic[FILTER_COUNT] = {0};
-        enum Filter minType = NONE;
-        for (enum Filter type = NONE; type < FILTER_COUNT; ++type) {
-            for (size_t i = 0; i < lineSize(); ++i) {
-                if (options.recon) {
-                    filter[type][i] = recon(type, origBytes(y, i));
-                } else {
-                    filter[type][i] = filt(type, origBytes(y, i));
-                }
-                heuristic[type] += abs((int8_t)filter[type][i]);
-            }
-            if (heuristic[type] < heuristic[minType]) minType = type;
-        }
-
-        if (options.declareFilter) {
-            lines[y]->type = options.declareFilters[y % options.declareFilter];
-        } else {
-            lines[y]->type = minType;
-        }
-
-        if (options.applyFilter) {
-            enum Filter type = options.applyFilters[y % options.applyFilter];
-            memcpy(lines[y]->data, filter[type], lineSize());
-        } else {
-            memcpy(lines[y]->data, filter[minType], lineSize());
-        }
-    }
+	for (uint32_t y = header.height - 1; y < header.height; --y) {
+		uint8_t filter[FILTER_COUNT][lineSize()];
+		uint32_t heuristic[FILTER_COUNT] = {0};
+		enum Filter minType = NONE;
+		for (enum Filter type = NONE; type < FILTER_COUNT; ++type) {
+			for (size_t i = 0; i < lineSize(); ++i) {
+				if (options.recon) {
+					filter[type][i] = recon(type, origBytes(y, i));
+				} else {
+					filter[type][i] = filt(type, origBytes(y, i));
+				}
+				heuristic[type] += abs((int8_t)filter[type][i]);
+			}
+			if (heuristic[type] < heuristic[minType]) minType = type;
+		}
+
+		if (options.declareFilter) {
+			lines[y]->type = options.declareFilters[y % options.declareFilter];
+		} else {
+			lines[y]->type = minType;
+		}
+
+		if (options.applyFilter) {
+			enum Filter type = options.applyFilters[y % options.applyFilter];
+			memcpy(lines[y]->data, filter[type], lineSize());
+		} else {
+			memcpy(lines[y]->data, filter[minType], lineSize());
+		}
+	}
 }
 
 static void glitch(const char *inPath, const char *outPath) {
-    if (inPath) {
-        path = inPath;
-        file = fopen(path, "r");
-        if (!file) err(EX_NOINPUT, "%s", path);
-    } else {
-        path = "(stdin)";
-        file = stdin;
-    }
-
-    readSignature();
-    readHeader();
-    if (header.color == INDEXED) readPalette();
-    readData();
-    fclose(file);
-
-    scanlines();
-    reconData();
-    filterData();
-    free(lines);
-
-    if (outPath) {
-        path = outPath;
-        file = fopen(path, "w");
-        if (!file) err(EX_CANTCREAT, "%s", path);
-    } else {
-        path = "(stdout)";
-        file = stdout;
-    }
-
-    writeSignature();
-    writeHeader();
-    if (header.color == INDEXED) writePalette();
-    writeData();
-    writeEnd();
-    free(data);
-
-    int error = fclose(file);
-    if (error) err(EX_IOERR, "%s", path);
+	if (inPath) {
+		path = inPath;
+		file = fopen(path, "r");
+		if (!file) err(EX_NOINPUT, "%s", path);
+	} else {
+		path = "(stdin)";
+		file = stdin;
+	}
+
+	readSignature();
+	readHeader();
+	if (header.color == INDEXED) readPalette();
+	readData();
+	fclose(file);
+
+	scanlines();
+	reconData();
+	filterData();
+	free(lines);
+
+	if (outPath) {
+		path = outPath;
+		file = fopen(path, "w");
+		if (!file) err(EX_CANTCREAT, "%s", path);
+	} else {
+		path = "(stdout)";
+		file = stdout;
+	}
+
+	writeSignature();
+	writeHeader();
+	if (header.color == INDEXED) writePalette();
+	writeData();
+	writeEnd();
+	free(data);
+
+	int error = fclose(file);
+	if (error) err(EX_IOERR, "%s", path);
 }
 
 static enum Filter parseFilter(const char *s) {
-    switch (s[0]) {
-        case 'N': case 'n': return NONE;
-        case 'S': case 's': return SUB;
-        case 'U': case 'u': return UP;
-        case 'A': case 'a': return AVERAGE;
-        case 'P': case 'p': return PAETH;
-        default: errx(EX_USAGE, "invalid filter type %s", s);
-    }
+	switch (s[0]) {
+		case 'N': case 'n': return NONE;
+		case 'S': case 's': return SUB;
+		case 'U': case 'u': return UP;
+		case 'A': case 'a': return AVERAGE;
+		case 'P': case 'p': return PAETH;
+		default: errx(EX_USAGE, "invalid filter type %s", s);
+	}
 }
 
 static uint8_t parseFilters(enum Filter *filters, const char *s) {
-    uint8_t len = 0;
-    do {
-        filters[len++] = parseFilter(s);
-        s = strchr(s, ',');
-    } while (s++);
-    return len;
+	uint8_t len = 0;
+	do {
+		filters[len++] = parseFilter(s);
+		s = strchr(s, ',');
+	} while (s++);
+	return len;
 }
 
 int main(int argc, char *argv[]) {
-    bool stdio = false;
-    char *output = NULL;
-
-    int opt;
-    while (0 < (opt = getopt(argc, argv, "a:cd:fo:pr"))) {
-        switch (opt) {
-            case 'a': {
-                options.applyFilter = parseFilters(options.applyFilters, optarg);
-            } break;
-            case 'c': stdio = true; break;
-            case 'd': {
-                options.declareFilter = parseFilters(options.declareFilters, optarg);
-            } break;
-            case 'f': options.filt = true; break;
-            case 'o': output = optarg; break;
-            case 'p': options.brokenPaeth = true; break;
-            case 'r': options.recon = true; break;
-            default: return EX_USAGE;
-        }
-    }
-
-    if (argc - optind == 1 && (output || stdio)) {
-        glitch(argv[optind], output);
-    } else if (optind < argc) {
-        for (int i = optind; i < argc; ++i) {
-            glitch(argv[i], argv[i]);
-        }
-    } else {
-        glitch(NULL, output);
-    }
-
-    return EX_OK;
+	bool stdio = false;
+	char *output = NULL;
+
+	int opt;
+	while (0 < (opt = getopt(argc, argv, "a:cd:fo:pr"))) {
+		switch (opt) {
+			case 'a': {
+				options.applyFilter = parseFilters(options.applyFilters, optarg);
+			} break;
+			case 'c': stdio = true; break;
+			case 'd': {
+				options.declareFilter = parseFilters(options.declareFilters, optarg);
+			} break;
+			case 'f': options.filt = true; break;
+			case 'o': output = optarg; break;
+			case 'p': options.brokenPaeth = true; break;
+			case 'r': options.recon = true; break;
+			default: return EX_USAGE;
+		}
+	}
+
+	if (argc - optind == 1 && (output || stdio)) {
+		glitch(argv[optind], output);
+	} else if (optind < argc) {
+		for (int i = optind; i < argc; ++i) {
+			glitch(argv[i], argv[i]);
+		}
+	} else {
+		glitch(NULL, output);
+	}
+
+	return EX_OK;
 }
diff --git a/bin/hnel.c b/bin/hnel.c
index 82f990d4..20dbd2a7 100644
--- a/bin/hnel.c
+++ b/bin/hnel.c
@@ -35,84 +35,84 @@
 
 static struct termios saveTerm;
 static void restoreTerm(void) {
-    tcsetattr(STDIN_FILENO, TCSADRAIN, &saveTerm);
+	tcsetattr(STDIN_FILENO, TCSADRAIN, &saveTerm);
 }
 
 int main(int argc, char *argv[]) {
-    int error;
-
-    if (argc < 4) return EX_USAGE;
-
-    char table[256] = {0};
-    if (strlen(argv[1]) != strlen(argv[2])) return EX_USAGE;
-    for (const char *from = argv[1], *to = argv[2]; *from; ++from, ++to) {
-        table[(unsigned)*from] = *to;
-    }
-
-    error = tcgetattr(STDERR_FILENO, &saveTerm);
-    if (error) err(EX_IOERR, "tcgetattr");
-    atexit(restoreTerm);
-
-    struct termios raw;
-    cfmakeraw(&raw);
-    error = tcsetattr(STDERR_FILENO, TCSADRAIN, &raw);
-    if (error) err(EX_IOERR, "tcsetattr");
-
-    struct winsize window;
-    error = ioctl(STDERR_FILENO, TIOCGWINSZ, &window);
-    if (error) err(EX_IOERR, "TIOCGWINSZ");
-
-    int pty;
-    pid_t pid = forkpty(&pty, NULL, NULL, &window);
-    if (pid < 0) err(EX_OSERR, "forkpty");
-
-    if (!pid) {
-        execvp(argv[3], &argv[3]);
-        err(EX_NOINPUT, "%s", argv[3]);
-    }
-
-    bool enable = true;
-
-    char buf[4096];
-    struct pollfd fds[2] = {
-        { .fd = STDIN_FILENO, .events = POLLIN },
-        { .fd = pty, .events = POLLIN },
-    };
-    while (0 < poll(fds, 2, -1)) {
-        if (fds[0].revents & POLLIN) {
-            ssize_t readSize = read(STDIN_FILENO, buf, sizeof(buf));
-            if (readSize < 0) err(EX_IOERR, "read(%d)", STDIN_FILENO);
-
-            if (readSize == 1) {
-                if (buf[0] == CTRL('S')) {
-                    enable ^= true;
-                    continue;
-                }
-
-                unsigned char c = buf[0];
-                if (enable && table[c]) buf[0] = table[c];
-            }
-
-            ssize_t writeSize = write(pty, buf, readSize);
-            if (writeSize < 0) err(EX_IOERR, "write(%d)", pty);
-            if (writeSize < readSize) errx(EX_IOERR, "short write(%d)", pty);
-        }
-
-        if (fds[1].revents & POLLIN) {
-            ssize_t readSize = read(pty, buf, sizeof(buf));
-            if (readSize < 0) err(EX_IOERR, "read(%d)", pty);
-
-            ssize_t writeSize = write(STDOUT_FILENO, buf, readSize);
-            if (writeSize < 0) err(EX_IOERR, "write(%d)", STDOUT_FILENO);
-            if (writeSize < readSize) {
-                errx(EX_IOERR, "short write(%d)", STDOUT_FILENO);
-            }
-        }
-
-        int status;
-        pid_t dead = waitpid(pid, &status, WNOHANG);
-        if (dead < 0) err(EX_OSERR, "waitpid(%d)", pid);
-        if (dead) return WIFEXITED(status) ? WEXITSTATUS(status) : EX_SOFTWARE;
-    }
-    err(EX_IOERR, "poll");
+	int error;
+
+	if (argc < 4) return EX_USAGE;
+
+	char table[256] = {0};
+	if (strlen(argv[1]) != strlen(argv[2])) return EX_USAGE;
+	for (const char *from = argv[1], *to = argv[2]; *from; ++from, ++to) {
+		table[(unsigned)*from] = *to;
+	}
+
+	error = tcgetattr(STDERR_FILENO, &saveTerm);
+	if (error) err(EX_IOERR, "tcgetattr");
+	atexit(restoreTerm);
+
+	struct termios raw;
+	cfmakeraw(&raw);
+	error = tcsetattr(STDERR_FILENO, TCSADRAIN, &raw);
+	if (error) err(EX_IOERR, "tcsetattr");
+
+	struct winsize window;
+	error = ioctl(STDERR_FILENO, TIOCGWINSZ, &window);
+	if (error) err(EX_IOERR, "TIOCGWINSZ");
+
+	int pty;
+	pid_t pid = forkpty(&pty, NULL, NULL, &window);
+	if (pid < 0) err(EX_OSERR, "forkpty");
+
+	if (!pid) {
+		execvp(argv[3], &argv[3]);
+		err(EX_NOINPUT, "%s", argv[3]);
+	}
+
+	bool enable = true;
+
+	char buf[4096];
+	struct pollfd fds[2] = {
+		{ .fd = STDIN_FILENO, .events = POLLIN },
+		{ .fd = pty, .events = POLLIN },
+	};
+	while (0 < poll(fds, 2, -1)) {
+		if (fds[0].revents & POLLIN) {
+			ssize_t readSize = read(STDIN_FILENO, buf, sizeof(buf));
+			if (readSize < 0) err(EX_IOERR, "read(%d)", STDIN_FILENO);
+
+			if (readSize == 1) {
+				if (buf[0] == CTRL('S')) {
+					enable ^= true;
+					continue;
+				}
+
+				unsigned char c = buf[0];
+				if (enable && table[c]) buf[0] = table[c];
+			}
+
+			ssize_t writeSize = write(pty, buf, readSize);
+			if (writeSize < 0) err(EX_IOERR, "write(%d)", pty);
+			if (writeSize < readSize) errx(EX_IOERR, "short write(%d)", pty);
+		}
+
+		if (fds[1].revents & POLLIN) {
+			ssize_t readSize = read(pty, buf, sizeof(buf));
+			if (readSize < 0) err(EX_IOERR, "read(%d)", pty);
+
+			ssize_t writeSize = write(STDOUT_FILENO, buf, readSize);
+			if (writeSize < 0) err(EX_IOERR, "write(%d)", STDOUT_FILENO);
+			if (writeSize < readSize) {
+				errx(EX_IOERR, "short write(%d)", STDOUT_FILENO);
+			}
+		}
+
+		int status;
+		pid_t dead = waitpid(pid, &status, WNOHANG);
+		if (dead < 0) err(EX_OSERR, "waitpid(%d)", pid);
+		if (dead) return WIFEXITED(status) ? WEXITSTATUS(status) : EX_SOFTWARE;
+	}
+	err(EX_IOERR, "poll");
 }
diff --git a/bin/klon.c b/bin/klon.c
index 05adc278..2a5e1346 100644
--- a/bin/klon.c
+++ b/bin/klon.c
@@ -26,334 +26,334 @@
 typedef uint8_t Card;
 
 enum {
-    MASK_RANK   = 0x0F,
-    MASK_SUIT   = 0x30,
-    MASK_COLOR  = 0x10,
-    MASK_UP     = 0x40,
-    MASK_SELECT = 0x80,
+	MASK_RANK   = 0x0F,
+	MASK_SUIT   = 0x30,
+	MASK_COLOR  = 0x10,
+	MASK_UP     = 0x40,
+	MASK_SELECT = 0x80,
 };
 
 enum {
-    SUIT_CLUB    = 0x00,
-    SUIT_DIAMOND = 0x10,
-    SUIT_SPADE   = 0x20,
-    SUIT_HEART   = 0x30,
+	SUIT_CLUB    = 0x00,
+	SUIT_DIAMOND = 0x10,
+	SUIT_SPADE   = 0x20,
+	SUIT_HEART   = 0x30,
 };
 
 struct Stack {
-    Card data[52];
-    uint8_t index;
+	Card data[52];
+	uint8_t index;
 };
 #define EMPTY { .data = {0}, .index = 52 }
 
 static void push(struct Stack *stack, Card card) {
-    assert(stack->index > 0);
-    stack->data[--stack->index] = card;
+	assert(stack->index > 0);
+	stack->data[--stack->index] = card;
 }
 
 static Card pop(struct Stack *stack) {
-    assert(stack->index < 52);
-    return stack->data[stack->index++];
+	assert(stack->index < 52);
+	return stack->data[stack->index++];
 }
 
 static Card get(const struct Stack *stack, uint8_t i) {
-    if (stack->index + i > 51) return 0;
-    return stack->data[stack->index + i];
+	if (stack->index + i > 51) return 0;
+	return stack->data[stack->index + i];
 }
 
 static uint8_t len(const struct Stack *stack) {
-    return 52 - stack->index;
+	return 52 - stack->index;
 }
 
 struct State {
-    struct Stack stock;
-    struct Stack waste;
-    struct Stack found[4];
-    struct Stack table[7];
+	struct Stack stock;
+	struct Stack waste;
+	struct Stack found[4];
+	struct Stack table[7];
 };
 
 static struct State g = {
-    .stock = {
-        .data = {
-            0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-            0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
-            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-            0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
-            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-            0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
-            0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-            0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,
-        },
-        .index = 0,
-    },
-    .waste = EMPTY,
-    .found = { EMPTY, EMPTY, EMPTY, EMPTY },
-    .table = {
-        EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY
-    },
+	.stock = {
+		.data = {
+			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
+			0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+			0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
+			0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+			0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
+			0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+			0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,
+		},
+		.index = 0,
+	},
+	.waste = EMPTY,
+	.found = { EMPTY, EMPTY, EMPTY, EMPTY },
+	.table = {
+		EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY
+	},
 };
 
 static struct State save;
 
 static void checkpoint(void) {
-    memcpy(&save, &g, sizeof(struct State));
+	memcpy(&save, &g, sizeof(struct State));
 }
 
 static void undo(void) {
-    memcpy(&g, &save, sizeof(struct State));
+	memcpy(&g, &save, sizeof(struct State));
 }
 
 static void shuffle(void) {
-    for (int i = 51; i > 0; --i) {
-        int j = arc4random_uniform(i + 1);
-        uint8_t x = g.stock.data[i];
-        g.stock.data[i] = g.stock.data[j];
-        g.stock.data[j] = x;
-    }
+	for (int i = 51; i > 0; --i) {
+		int j = arc4random_uniform(i + 1);
+		uint8_t x = g.stock.data[i];
+		g.stock.data[i] = g.stock.data[j];
+		g.stock.data[j] = x;
+	}
 }
 
 static void deal(void) {
-    for (int i = 0; i < 7; ++i) {
-        for (int j = i; j < 7; ++j) {
-            push(&g.table[j], pop(&g.stock));
-        }
-    }
+	for (int i = 0; i < 7; ++i) {
+		for (int j = i; j < 7; ++j) {
+			push(&g.table[j], pop(&g.stock));
+		}
+	}
 }
 
 static void reveal(void) {
-    for (int i = 0; i < 7; ++i) {
-        if (get(&g.table[i], 0)) {
-            push(&g.table[i], pop(&g.table[i]) | MASK_UP);
-        }
-    }
+	for (int i = 0; i < 7; ++i) {
+		if (get(&g.table[i], 0)) {
+			push(&g.table[i], pop(&g.table[i]) | MASK_UP);
+		}
+	}
 }
 
 static void draw(void) {
-    if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
-    if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
-    if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
+	if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
+	if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
+	if (get(&g.stock, 0)) push(&g.waste, pop(&g.stock) | MASK_UP);
 }
 
 static void wasted(void) {
-    uint8_t n = len(&g.waste);
-    for (int i = 0; i < n; ++i) {
-        push(&g.stock, pop(&g.waste) & ~MASK_UP);
-    }
+	uint8_t n = len(&g.waste);
+	for (int i = 0; i < n; ++i) {
+		push(&g.stock, pop(&g.waste) & ~MASK_UP);
+	}
 }
 
 static void transfer(struct Stack *dest, struct Stack *src, uint8_t n) {
-    struct Stack temp = EMPTY;
-    for (int i = 0; i < n; ++i) {
-        push(&temp, pop(src));
-    }
-    for (int i = 0; i < n; ++i) {
-        push(dest, pop(&temp));
-    }
+	struct Stack temp = EMPTY;
+	for (int i = 0; i < n; ++i) {
+		push(&temp, pop(src));
+	}
+	for (int i = 0; i < n; ++i) {
+		push(dest, pop(&temp));
+	}
 }
 
 static bool canFound(const struct Stack *found, Card card) {
-    if (!get(found, 0)) return (card & MASK_RANK) == 1;
-    if ((card & MASK_SUIT) != (get(found, 0) & MASK_SUIT)) return false;
-    return (card & MASK_RANK) == (get(found, 0) & MASK_RANK) + 1;
+	if (!get(found, 0)) return (card & MASK_RANK) == 1;
+	if ((card & MASK_SUIT) != (get(found, 0) & MASK_SUIT)) return false;
+	return (card & MASK_RANK) == (get(found, 0) & MASK_RANK) + 1;
 }
 
 static bool canTable(const struct Stack *table, Card card) {
-    if (!get(table, 0)) return (card & MASK_RANK) == 13;
-    if ((card & MASK_COLOR) == (get(table, 0) & MASK_COLOR)) return false;
-    return (card & MASK_RANK) == (get(table, 0) & MASK_RANK) - 1;
+	if (!get(table, 0)) return (card & MASK_RANK) == 13;
+	if ((card & MASK_COLOR) == (get(table, 0) & MASK_COLOR)) return false;
+	return (card & MASK_RANK) == (get(table, 0) & MASK_RANK) - 1;
 }
 
 enum {
-    PAIR_EMPTY = 1,
-    PAIR_BACK,
-    PAIR_BLACK,
-    PAIR_RED,
+	PAIR_EMPTY = 1,
+	PAIR_BACK,
+	PAIR_BLACK,
+	PAIR_RED,
 };
 
 static void curse(void) {
-    setlocale(LC_CTYPE, "");
-
-    initscr();
-    cbreak();
-    noecho();
-    keypad(stdscr, true);
-    set_escdelay(100);
-    curs_set(0);
-
-    start_color();
-    assume_default_colors(-1, -1);
-    init_pair(PAIR_EMPTY, COLOR_WHITE, COLOR_BLACK);
-    init_pair(PAIR_BACK,  COLOR_WHITE, COLOR_BLUE);
-    init_pair(PAIR_BLACK, COLOR_BLACK, COLOR_WHITE);
-    init_pair(PAIR_RED,   COLOR_RED,   COLOR_WHITE);
+	setlocale(LC_CTYPE, "");
+
+	initscr();
+	cbreak();
+	noecho();
+	keypad(stdscr, true);
+	set_escdelay(100);
+	curs_set(0);
+
+	start_color();
+	assume_default_colors(-1, -1);
+	init_pair(PAIR_EMPTY, COLOR_WHITE, COLOR_BLACK);
+	init_pair(PAIR_BACK,  COLOR_WHITE, COLOR_BLUE);
+	init_pair(PAIR_BLACK, COLOR_BLACK, COLOR_WHITE);
+	init_pair(PAIR_RED,   COLOR_RED,   COLOR_WHITE);
 }
 
 static const char rank[] = "\0A23456789TJQK";
 static const char *suit[] = {
-    [SUIT_HEART]   = "♥",
-    [SUIT_CLUB]    = "♣",
-    [SUIT_DIAMOND] = "♦",
-    [SUIT_SPADE]   = "â™ ",
+	[SUIT_HEART]   = "♥",
+	[SUIT_CLUB]    = "♣",
+	[SUIT_DIAMOND] = "♦",
+	[SUIT_SPADE]   = "â™ ",
 };
 
 static void renderCard(int y, int x, Card card) {
-    if (card & MASK_UP) {
-        bkgdset(
-            COLOR_PAIR(card & MASK_COLOR ? PAIR_RED : PAIR_BLACK)
-            | (card & MASK_SELECT ? A_REVERSE : A_NORMAL)
-        );
-
-        move(y, x);
-        addch(rank[card & MASK_RANK]);
-        addstr(suit[card & MASK_SUIT]);
-        addch(' ');
-
-        move(y + 1, x);
-        addstr(suit[card & MASK_SUIT]);
-        addch(' ');
-        addstr(suit[card & MASK_SUIT]);
-
-        move(y + 2, x);
-        addch(' ');
-        addstr(suit[card & MASK_SUIT]);
-        addch(rank[card & MASK_RANK]);
-
-    } else {
-        bkgdset(COLOR_PAIR(card ? PAIR_BACK : PAIR_EMPTY));
-        mvaddstr(y, x, "   ");
-        mvaddstr(y + 1, x, "   ");
-        mvaddstr(y + 2, x, "   ");
-    }
+	if (card & MASK_UP) {
+		bkgdset(
+			COLOR_PAIR(card & MASK_COLOR ? PAIR_RED : PAIR_BLACK)
+			| (card & MASK_SELECT ? A_REVERSE : A_NORMAL)
+		);
+
+		move(y, x);
+		addch(rank[card & MASK_RANK]);
+		addstr(suit[card & MASK_SUIT]);
+		addch(' ');
+
+		move(y + 1, x);
+		addstr(suit[card & MASK_SUIT]);
+		addch(' ');
+		addstr(suit[card & MASK_SUIT]);
+
+		move(y + 2, x);
+		addch(' ');
+		addstr(suit[card & MASK_SUIT]);
+		addch(rank[card & MASK_RANK]);
+
+	} else {
+		bkgdset(COLOR_PAIR(card ? PAIR_BACK : PAIR_EMPTY));
+		mvaddstr(y, x, "   ");
+		mvaddstr(y + 1, x, "   ");
+		mvaddstr(y + 2, x, "   ");
+	}
 }
 
 static void render(void) {
-    bkgdset(COLOR_PAIR(0));
-    erase();
-
-    int x = 2;
-    int y = 1;
-
-    renderCard(y, x, get(&g.stock, 0));
-
-    x += 5;
-    renderCard(y, x++, get(&g.waste, 2));
-    renderCard(y, x++, get(&g.waste, 1));
-    renderCard(y, x, get(&g.waste, 0));
-
-    x += 5;
-    for (int i = 0; i < 4; ++i) {
-        renderCard(y, x, get(&g.found[i], 0));
-        x += 4;
-    }
-
-    x = 2;
-    for (int i = 0; i < 7; ++i) {
-        y = 5;
-        renderCard(y, x, 0);
-        for (int j = len(&g.table[i]); j > 0; --j) {
-            renderCard(y, x, get(&g.table[i], j - 1));
-            y++;
-        }
-        x += 4;
-    }
+	bkgdset(COLOR_PAIR(0));
+	erase();
+
+	int x = 2;
+	int y = 1;
+
+	renderCard(y, x, get(&g.stock, 0));
+
+	x += 5;
+	renderCard(y, x++, get(&g.waste, 2));
+	renderCard(y, x++, get(&g.waste, 1));
+	renderCard(y, x, get(&g.waste, 0));
+
+	x += 5;
+	for (int i = 0; i < 4; ++i) {
+		renderCard(y, x, get(&g.found[i], 0));
+		x += 4;
+	}
+
+	x = 2;
+	for (int i = 0; i < 7; ++i) {
+		y = 5;
+		renderCard(y, x, 0);
+		for (int j = len(&g.table[i]); j > 0; --j) {
+			renderCard(y, x, get(&g.table[i], j - 1));
+			y++;
+		}
+		x += 4;
+	}
 }
 
 static struct {
-    struct Stack *stack;
-    uint8_t depth;
+	struct Stack *stack;
+	uint8_t depth;
 } input;
 
 static void deepen(void) {
-    assert(input.stack);
-    if (input.depth == len(input.stack)) return;
-    if (!(get(input.stack, input.depth) & MASK_UP)) return;
-    input.stack->data[input.stack->index + input.depth] |= MASK_SELECT;
-    input.depth++;
+	assert(input.stack);
+	if (input.depth == len(input.stack)) return;
+	if (!(get(input.stack, input.depth) & MASK_UP)) return;
+	input.stack->data[input.stack->index + input.depth] |= MASK_SELECT;
+	input.depth++;
 }
 
 static void select(struct Stack *stack) {
-    if (!get(stack, 0)) return;
-    input.stack = stack;
-    input.depth = 0;
-    deepen();
+	if (!get(stack, 0)) return;
+	input.stack = stack;
+	input.depth = 0;
+	deepen();
 }
 
 static void commit(struct Stack *dest) {
-    assert(input.stack);
-    for (int i = 0; i < input.depth; ++i) {
-        input.stack->data[input.stack->index + i] &= ~MASK_SELECT;
-    }
-    if (dest) {
-        checkpoint();
-        transfer(dest, input.stack, input.depth);
-    }
-    input.stack = NULL;
-    input.depth = 0;
+	assert(input.stack);
+	for (int i = 0; i < input.depth; ++i) {
+		input.stack->data[input.stack->index + i] &= ~MASK_SELECT;
+	}
+	if (dest) {
+		checkpoint();
+		transfer(dest, input.stack, input.depth);
+	}
+	input.stack = NULL;
+	input.depth = 0;
 }
 
 int main() {
-    curse();
-
-    shuffle();
-    deal();
-    checkpoint();
-
-    for (;;) {
-        reveal();
-        render();
-
-        int c = getch();
-        if (!input.stack) {
-            if (c == 'q') {
-                break;
-            } else if (c == 'u') {
-                undo();
-            } else if (c == 's' || c == ' ') {
-                if (get(&g.stock, 0)) {
-                    checkpoint();
-                    draw();
-                } else {
-                    wasted();
-                }
-            } else if (c == 'w') {
-                select(&g.waste);
-            } else if (c >= 'a' && c <= 'd') {
-                select(&g.found[c - 'a']);
-            } else if (c >= '1' && c <= '7') {
-                select(&g.table[c - '1']);
-            }
-
-        } else {
-            if (c >= '1' && c <= '7') {
-                struct Stack *table = &g.table[c - '1'];
-                if (input.stack == table) {
-                    deepen();
-                } else if (canTable(table, get(input.stack, input.depth - 1))) {
-                    commit(table);
-                } else {
-                    commit(NULL);
-                }
-            } else if (input.depth == 1 && c >= 'a' && c <= 'd') {
-                struct Stack *found = &g.found[c - 'a'];
-                if (canFound(found, get(input.stack, 0))) {
-                    commit(found);
-                } else {
-                    commit(NULL);
-                }
-            } else if (input.depth == 1 && (c == 'f' || c == '\n')) {
-                struct Stack *found;
-                for (int i = 0; i < 4; ++i) {
-                    found = &g.found[i];
-                    if (canFound(found, get(input.stack, 0))) break;
-                    found = NULL;
-                }
-                commit(found);
-            } else {
-                commit(NULL);
-            }
-        }
-    }
-
-    endwin();
-    return 0;
+	curse();
+
+	shuffle();
+	deal();
+	checkpoint();
+
+	for (;;) {
+		reveal();
+		render();
+
+		int c = getch();
+		if (!input.stack) {
+			if (c == 'q') {
+				break;
+			} else if (c == 'u') {
+				undo();
+			} else if (c == 's' || c == ' ') {
+				if (get(&g.stock, 0)) {
+					checkpoint();
+					draw();
+				} else {
+					wasted();
+				}
+			} else if (c == 'w') {
+				select(&g.waste);
+			} else if (c >= 'a' && c <= 'd') {
+				select(&g.found[c - 'a']);
+			} else if (c >= '1' && c <= '7') {
+				select(&g.table[c - '1']);
+			}
+
+		} else {
+			if (c >= '1' && c <= '7') {
+				struct Stack *table = &g.table[c - '1'];
+				if (input.stack == table) {
+					deepen();
+				} else if (canTable(table, get(input.stack, input.depth - 1))) {
+					commit(table);
+				} else {
+					commit(NULL);
+				}
+			} else if (input.depth == 1 && c >= 'a' && c <= 'd') {
+				struct Stack *found = &g.found[c - 'a'];
+				if (canFound(found, get(input.stack, 0))) {
+					commit(found);
+				} else {
+					commit(NULL);
+				}
+			} else if (input.depth == 1 && (c == 'f' || c == '\n')) {
+				struct Stack *found;
+				for (int i = 0; i < 4; ++i) {
+					found = &g.found[i];
+					if (canFound(found, get(input.stack, 0))) break;
+					found = NULL;
+				}
+				commit(found);
+			} else {
+				commit(NULL);
+			}
+		}
+	}
+
+	endwin();
+	return 0;
 }
diff --git a/bin/pbd.c b/bin/pbd.c
index afe2a77e..77832433 100644
--- a/bin/pbd.c
+++ b/bin/pbd.c
@@ -29,108 +29,108 @@
 #define UNUSED __attribute__((unused))
 
 static void spawn(const char *cmd, int dest, int src) {
-    pid_t pid = fork();
-    if (pid < 0) err(EX_OSERR, "fork");
-
-    if (pid) {
-        int status;
-        pid_t dead = waitpid(pid, &status, 0);
-        if (dead < 0) err(EX_OSERR, "waitpid(%d)", pid);
-        if (status) warnx("%s: status %d", cmd, status);
-
-    } else {
-        int fd = dup2(src, dest);
-        if (fd < 0) err(EX_OSERR, "dup2");
-
-        execlp(cmd, cmd, NULL);
-        err(EX_UNAVAILABLE, "%s", cmd);
-    }
+	pid_t pid = fork();
+	if (pid < 0) err(EX_OSERR, "fork");
+
+	if (pid) {
+		int status;
+		pid_t dead = waitpid(pid, &status, 0);
+		if (dead < 0) err(EX_OSERR, "waitpid(%d)", pid);
+		if (status) warnx("%s: status %d", cmd, status);
+
+	} else {
+		int fd = dup2(src, dest);
+		if (fd < 0) err(EX_OSERR, "dup2");
+
+		execlp(cmd, cmd, NULL);
+		err(EX_UNAVAILABLE, "%s", cmd);
+	}
 }
 
 static int pbd(void) {
-    int error;
+	int error;
 
-    int server = socket(PF_INET, SOCK_STREAM, 0);
-    if (server < 0) err(EX_OSERR, "socket");
+	int server = socket(PF_INET, SOCK_STREAM, 0);
+	if (server < 0) err(EX_OSERR, "socket");
 
-    error = fcntl(server, F_SETFD, FD_CLOEXEC);
-    if (error) err(EX_IOERR, "fcntl");
+	error = fcntl(server, F_SETFD, FD_CLOEXEC);
+	if (error) err(EX_IOERR, "fcntl");
 
-    struct sockaddr_in addr = {
-        .sin_family = AF_INET,
-        .sin_port = htons(7062),
-        .sin_addr = { .s_addr = htonl(0x7F000001) },
-    };
-    error = bind(server, (struct sockaddr *)&addr, sizeof(addr));
-    if (error) err(EX_UNAVAILABLE, "bind");
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_port = htons(7062),
+		.sin_addr = { .s_addr = htonl(0x7F000001) },
+	};
+	error = bind(server, (struct sockaddr *)&addr, sizeof(addr));
+	if (error) err(EX_UNAVAILABLE, "bind");
 
-    error = listen(server, 0);
-    if (error) err(EX_UNAVAILABLE, "listen");
+	error = listen(server, 0);
+	if (error) err(EX_UNAVAILABLE, "listen");
 
-    for (;;) {
-        int client = accept(server, NULL, NULL);
-        if (client < 0) err(EX_IOERR, "accept");
+	for (;;) {
+		int client = accept(server, NULL, NULL);
+		if (client < 0) err(EX_IOERR, "accept");
 
-        error = fcntl(client, F_SETFD, FD_CLOEXEC);
-        if (error) err(EX_IOERR, "fcntl");
+		error = fcntl(client, F_SETFD, FD_CLOEXEC);
+		if (error) err(EX_IOERR, "fcntl");
 
-        spawn("pbpaste", STDOUT_FILENO, client);
+		spawn("pbpaste", STDOUT_FILENO, client);
 
-        char p;
-        ssize_t peek = recv(client, &p, 1, MSG_PEEK);
-        if (peek < 0) err(EX_IOERR, "recv");
+		char p;
+		ssize_t peek = recv(client, &p, 1, MSG_PEEK);
+		if (peek < 0) err(EX_IOERR, "recv");
 
-        if (peek) spawn("pbcopy", STDIN_FILENO, client);
+		if (peek) spawn("pbcopy", STDIN_FILENO, client);
 
-        close(client);
-    }
+		close(client);
+	}
 }
 
 static int pbdClient(void) {
-    int client = socket(PF_INET, SOCK_STREAM, 0);
-    if (client < 0) err(EX_OSERR, "socket");
-
-    struct sockaddr_in addr = {
-        .sin_family = AF_INET,
-        .sin_port = htons(7062),
-        .sin_addr = { .s_addr = htonl(0x7F000001) },
-    };
-    int error = connect(client, (struct sockaddr *)&addr, sizeof(addr));
-    if (error) err(EX_UNAVAILABLE, "connect");
-
-    return client;
+	int client = socket(PF_INET, SOCK_STREAM, 0);
+	if (client < 0) err(EX_OSERR, "socket");
+
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_port = htons(7062),
+		.sin_addr = { .s_addr = htonl(0x7F000001) },
+	};
+	int error = connect(client, (struct sockaddr *)&addr, sizeof(addr));
+	if (error) err(EX_UNAVAILABLE, "connect");
+
+	return client;
 }
 
 static void copy(int out, int in) {
-    char buf[4096];
-    ssize_t readSize;
-    while (0 < (readSize = read(in, buf, sizeof(buf)))) {
-        ssize_t writeSize = write(out, buf, readSize);
-        if (writeSize < 0) err(EX_IOERR, "write(%d)", out);
-        if (writeSize < readSize) errx(EX_IOERR, "short write(%d)", out);
-    }
-    if (readSize < 0) err(EX_IOERR, "read(%d)", in);
+	char buf[4096];
+	ssize_t readSize;
+	while (0 < (readSize = read(in, buf, sizeof(buf)))) {
+		ssize_t writeSize = write(out, buf, readSize);
+		if (writeSize < 0) err(EX_IOERR, "write(%d)", out);
+		if (writeSize < readSize) errx(EX_IOERR, "short write(%d)", out);
+	}
+	if (readSize < 0) err(EX_IOERR, "read(%d)", in);
 }
 
 static int pbcopy(void) {
-    int client = pbdClient();
-    copy(client, STDIN_FILENO);
-    return EX_OK;
+	int client = pbdClient();
+	copy(client, STDIN_FILENO);
+	return EX_OK;
 }
 
 static int pbpaste(void) {
-    int client = pbdClient();
-    shutdown(client, SHUT_WR);
-    copy(STDOUT_FILENO, client);
-    return EX_OK;
+	int client = pbdClient();
+	shutdown(client, SHUT_WR);
+	copy(STDOUT_FILENO, client);
+	return EX_OK;
 }
 
 int main(int argc UNUSED, char *argv[]) {
-    if (!argv[0][0] || !argv[0][1]) return EX_USAGE;
-    switch (argv[0][2]) {
-        case 'd': return pbd();
-        case 'c': return pbcopy();
-        case 'p': return pbpaste();
-        default:  return EX_USAGE;
-    }
+	if (!argv[0][0] || !argv[0][1]) return EX_USAGE;
+	switch (argv[0][2]) {
+		case 'd': return pbd();
+		case 'c': return pbcopy();
+		case 'p': return pbpaste();
+		default:  return EX_USAGE;
+	}
 }
diff --git a/bin/pngo.c b/bin/pngo.c
index 22837d76..e4afa082 100644
--- a/bin/pngo.c
+++ b/bin/pngo.c
@@ -37,682 +37,682 @@ static FILE *file;
 static uint32_t crc;
 
 static void readExpect(void *ptr, size_t size, const char *expect) {
-    fread(ptr, size, 1, file);
-    if (ferror(file)) err(EX_IOERR, "%s", path);
-    if (feof(file)) errx(EX_DATAERR, "%s: missing %s", path, expect);
-    crc = crc32(crc, ptr, size);
+	fread(ptr, size, 1, file);
+	if (ferror(file)) err(EX_IOERR, "%s", path);
+	if (feof(file)) errx(EX_DATAERR, "%s: missing %s", path, expect);
+	crc = crc32(crc, ptr, size);
 }
 
 static void writeExpect(const void *ptr, size_t size) {
-    fwrite(ptr, size, 1, file);
-    if (ferror(file)) err(EX_IOERR, "%s", path);
-    crc = crc32(crc, ptr, size);
+	fwrite(ptr, size, 1, file);
+	if (ferror(file)) err(EX_IOERR, "%s", path);
+	crc = crc32(crc, ptr, size);
 }
 
 static const uint8_t SIGNATURE[8] = {
-    0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n'
+	0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n'
 };
 
 static void readSignature(void) {
-    uint8_t signature[8];
-    readExpect(signature, 8, "signature");
-    if (0 != memcmp(signature, SIGNATURE, 8)) {
-        errx(EX_DATAERR, "%s: invalid signature", path);
-    }
+	uint8_t signature[8];
+	readExpect(signature, 8, "signature");
+	if (0 != memcmp(signature, SIGNATURE, 8)) {
+		errx(EX_DATAERR, "%s: invalid signature", path);
+	}
 }
 
 static void writeSignature(void) {
-    writeExpect(SIGNATURE, sizeof(SIGNATURE));
+	writeExpect(SIGNATURE, sizeof(SIGNATURE));
 }
 
 struct PACKED Chunk {
-    uint32_t size;
-    char type[4];
+	uint32_t size;
+	char type[4];
 };
 
 static const char *typeStr(struct Chunk chunk) {
-    static char buf[5];
-    memcpy(buf, chunk.type, 4);
-    return buf;
+	static char buf[5];
+	memcpy(buf, chunk.type, 4);
+	return buf;
 }
 
 static struct Chunk readChunk(void) {
-    struct Chunk chunk;
-    readExpect(&chunk, sizeof(chunk), "chunk");
-    chunk.size = ntohl(chunk.size);
-    crc = crc32(CRC_INIT, (Byte *)chunk.type, sizeof(chunk.type));
-    return chunk;
+	struct Chunk chunk;
+	readExpect(&chunk, sizeof(chunk), "chunk");
+	chunk.size = ntohl(chunk.size);
+	crc = crc32(CRC_INIT, (Byte *)chunk.type, sizeof(chunk.type));
+	return chunk;
 }
 
 static void writeChunk(struct Chunk chunk) {
-    chunk.size = htonl(chunk.size);
-    writeExpect(&chunk, sizeof(chunk));
-    crc = crc32(CRC_INIT, (Byte *)chunk.type, sizeof(chunk.type));
+	chunk.size = htonl(chunk.size);
+	writeExpect(&chunk, sizeof(chunk));
+	crc = crc32(CRC_INIT, (Byte *)chunk.type, sizeof(chunk.type));
 }
 
 static void readCrc(void) {
-    uint32_t expected = crc;
-    uint32_t found;
-    readExpect(&found, sizeof(found), "CRC32");
-    found = ntohl(found);
-    if (found != expected) {
-        errx(
-            EX_DATAERR, "%s: expected CRC32 %08X, found %08X",
-            path, expected, found
-        );
-    }
+	uint32_t expected = crc;
+	uint32_t found;
+	readExpect(&found, sizeof(found), "CRC32");
+	found = ntohl(found);
+	if (found != expected) {
+		errx(
+			EX_DATAERR, "%s: expected CRC32 %08X, found %08X",
+			path, expected, found
+		);
+	}
 }
 
 static void writeCrc(void) {
-    uint32_t net = htonl(crc);
-    writeExpect(&net, sizeof(net));
+	uint32_t net = htonl(crc);
+	writeExpect(&net, sizeof(net));
 }
 
 static void skipChunk(struct Chunk chunk) {
-    if (!(chunk.type[0] & 0x20)) {
-        errx(EX_CONFIG, "%s: unsupported critical chunk %s", path, typeStr(chunk));
-    }
-    uint8_t discard[chunk.size];
-    readExpect(discard, sizeof(discard), "chunk data");
-    readCrc();
+	if (!(chunk.type[0] & 0x20)) {
+		errx(EX_CONFIG, "%s: unsupported critical chunk %s", path, typeStr(chunk));
+	}
+	uint8_t discard[chunk.size];
+	readExpect(discard, sizeof(discard), "chunk data");
+	readCrc();
 }
 
 static struct PACKED {
-    uint32_t width;
-    uint32_t height;
-    uint8_t depth;
-    enum PACKED {
-        GRAYSCALE       = 0,
-        TRUECOLOR       = 2,
-        INDEXED         = 3,
-        GRAYSCALE_ALPHA = 4,
-        TRUECOLOR_ALPHA = 6,
-    } color;
-    enum PACKED { DEFLATE } compression;
-    enum PACKED { ADAPTIVE } filter;
-    enum PACKED { PROGRESSIVE, ADAM7 } interlace;
+	uint32_t width;
+	uint32_t height;
+	uint8_t depth;
+	enum PACKED {
+		GRAYSCALE       = 0,
+		TRUECOLOR       = 2,
+		INDEXED         = 3,
+		GRAYSCALE_ALPHA = 4,
+		TRUECOLOR_ALPHA = 6,
+	} color;
+	enum PACKED { DEFLATE } compression;
+	enum PACKED { ADAPTIVE } filter;
+	enum PACKED { PROGRESSIVE, ADAM7 } interlace;
 } header;
 static_assert(13 == sizeof(header), "header size");
 
 static size_t lineSize(void) {
-    switch (header.color) {
-        case GRAYSCALE:       return (header.width * 1 * header.depth + 7) / 8;
-        case TRUECOLOR:       return (header.width * 3 * header.depth + 7) / 8;
-        case INDEXED:         return (header.width * 1 * header.depth + 7) / 8;
-        case GRAYSCALE_ALPHA: return (header.width * 2 * header.depth + 7) / 8;
-        case TRUECOLOR_ALPHA: return (header.width * 4 * header.depth + 7) / 8;
-        default: abort();
-    }
+	switch (header.color) {
+		case GRAYSCALE:       return (header.width * 1 * header.depth + 7) / 8;
+		case TRUECOLOR:       return (header.width * 3 * header.depth + 7) / 8;
+		case INDEXED:         return (header.width * 1 * header.depth + 7) / 8;
+		case GRAYSCALE_ALPHA: return (header.width * 2 * header.depth + 7) / 8;
+		case TRUECOLOR_ALPHA: return (header.width * 4 * header.depth + 7) / 8;
+		default: abort();
+	}
 }
 
 static size_t dataSize(void) {
-    return (1 + lineSize()) * header.height;
+	return (1 + lineSize()) * header.height;
 }
 
 static const char *COLOR_STR[] = {
-    [GRAYSCALE] = "grayscale",
-    [TRUECOLOR] = "truecolor",
-    [INDEXED] = "indexed",
-    [GRAYSCALE_ALPHA] = "grayscale alpha",
-    [TRUECOLOR_ALPHA] = "truecolor alpha",
+	[GRAYSCALE] = "grayscale",
+	[TRUECOLOR] = "truecolor",
+	[INDEXED] = "indexed",
+	[GRAYSCALE_ALPHA] = "grayscale alpha",
+	[TRUECOLOR_ALPHA] = "truecolor alpha",
 };
 static void printHeader(void) {
-    fprintf(
-        stderr,
-        "%s: %ux%u %hhu-bit %s\n",
-        path,
-        header.width, header.height,
-        header.depth, COLOR_STR[header.color]
-    );
+	fprintf(
+		stderr,
+		"%s: %ux%u %hhu-bit %s\n",
+		path,
+		header.width, header.height,
+		header.depth, COLOR_STR[header.color]
+	);
 }
 
 static void readHeader(void) {
-    struct Chunk ihdr = readChunk();
-    if (0 != memcmp(ihdr.type, "IHDR", 4)) {
-        errx(EX_DATAERR, "%s: expected IHDR, found %s", path, typeStr(ihdr));
-    }
-    if (ihdr.size != sizeof(header)) {
-        errx(
-            EX_DATAERR, "%s: expected IHDR size %zu, found %u",
-            path, sizeof(header), ihdr.size
-        );
-    }
-    readExpect(&header, sizeof(header), "header");
-    readCrc();
-
-    header.width = ntohl(header.width);
-    header.height = ntohl(header.height);
-
-    if (!header.width) errx(EX_DATAERR, "%s: invalid width 0", path);
-    if (!header.height) errx(EX_DATAERR, "%s: invalid height 0", path);
-    switch (PAIR(header.color, header.depth)) {
-        case PAIR(GRAYSCALE, 1):
-        case PAIR(GRAYSCALE, 2):
-        case PAIR(GRAYSCALE, 4):
-        case PAIR(GRAYSCALE, 8):
-        case PAIR(GRAYSCALE, 16):
-        case PAIR(TRUECOLOR, 8):
-        case PAIR(TRUECOLOR, 16):
-        case PAIR(INDEXED, 1):
-        case PAIR(INDEXED, 2):
-        case PAIR(INDEXED, 4):
-        case PAIR(INDEXED, 8):
-        case PAIR(GRAYSCALE_ALPHA, 8):
-        case PAIR(GRAYSCALE_ALPHA, 16):
-        case PAIR(TRUECOLOR_ALPHA, 8):
-        case PAIR(TRUECOLOR_ALPHA, 16):
-            break;
-        default:
-            errx(
-                EX_DATAERR, "%s: invalid color type %hhu and bit depth %hhu",
-                path, header.color, header.depth
-            );
-    }
-    if (header.compression != DEFLATE) {
-        errx(
-            EX_DATAERR, "%s: invalid compression method %hhu",
-            path, header.compression
-        );
-    }
-    if (header.filter != ADAPTIVE) {
-        errx(EX_DATAERR, "%s: invalid filter method %hhu", path, header.filter);
-    }
-    if (header.interlace > ADAM7) {
-        errx(EX_DATAERR, "%s: invalid interlace method %hhu", path, header.interlace);
-    }
-
-    if (verbose) printHeader();
+	struct Chunk ihdr = readChunk();
+	if (0 != memcmp(ihdr.type, "IHDR", 4)) {
+		errx(EX_DATAERR, "%s: expected IHDR, found %s", path, typeStr(ihdr));
+	}
+	if (ihdr.size != sizeof(header)) {
+		errx(
+			EX_DATAERR, "%s: expected IHDR size %zu, found %u",
+			path, sizeof(header), ihdr.size
+		);
+	}
+	readExpect(&header, sizeof(header), "header");
+	readCrc();
+
+	header.width = ntohl(header.width);
+	header.height = ntohl(header.height);
+
+	if (!header.width) errx(EX_DATAERR, "%s: invalid width 0", path);
+	if (!header.height) errx(EX_DATAERR, "%s: invalid height 0", path);
+	switch (PAIR(header.color, header.depth)) {
+		case PAIR(GRAYSCALE, 1):
+		case PAIR(GRAYSCALE, 2):
+		case PAIR(GRAYSCALE, 4):
+		case PAIR(GRAYSCALE, 8):
+		case PAIR(GRAYSCALE, 16):
+		case PAIR(TRUECOLOR, 8):
+		case PAIR(TRUECOLOR, 16):
+		case PAIR(INDEXED, 1):
+		case PAIR(INDEXED, 2):
+		case PAIR(INDEXED, 4):
+		case PAIR(INDEXED, 8):
+		case PAIR(GRAYSCALE_ALPHA, 8):
+		case PAIR(GRAYSCALE_ALPHA, 16):
+		case PAIR(TRUECOLOR_ALPHA, 8):
+		case PAIR(TRUECOLOR_ALPHA, 16):
+			break;
+		default:
+			errx(
+				EX_DATAERR, "%s: invalid color type %hhu and bit depth %hhu",
+				path, header.color, header.depth
+			);
+	}
+	if (header.compression != DEFLATE) {
+		errx(
+			EX_DATAERR, "%s: invalid compression method %hhu",
+			path, header.compression
+		);
+	}
+	if (header.filter != ADAPTIVE) {
+		errx(EX_DATAERR, "%s: invalid filter method %hhu", path, header.filter);
+	}
+	if (header.interlace > ADAM7) {
+		errx(EX_DATAERR, "%s: invalid interlace method %hhu", path, header.interlace);
+	}
+
+	if (verbose) printHeader();
 }
 
 static void writeHeader(void) {
-    if (verbose) printHeader();
+	if (verbose) printHeader();
 
-    struct Chunk ihdr = { .size = sizeof(header), .type = "IHDR" };
-    writeChunk(ihdr);
-    header.width = htonl(header.width);
-    header.height = htonl(header.height);
-    writeExpect(&header, sizeof(header));
-    writeCrc();
+	struct Chunk ihdr = { .size = sizeof(header), .type = "IHDR" };
+	writeChunk(ihdr);
+	header.width = htonl(header.width);
+	header.height = htonl(header.height);
+	writeExpect(&header, sizeof(header));
+	writeCrc();
 
-    header.width = ntohl(header.width);
-    header.height = ntohl(header.height);
+	header.width = ntohl(header.width);
+	header.height = ntohl(header.height);
 }
 
 static struct {
-    uint32_t len;
-    uint8_t entries[256][3];
+	uint32_t len;
+	uint8_t entries[256][3];
 } palette;
 
 static uint16_t paletteIndex(const uint8_t *rgb) {
-    uint16_t i;
-    for (i = 0; i < palette.len; ++i) {
-        if (0 == memcmp(palette.entries[i], rgb, 3)) break;
-    }
-    return i;
+	uint16_t i;
+	for (i = 0; i < palette.len; ++i) {
+		if (0 == memcmp(palette.entries[i], rgb, 3)) break;
+	}
+	return i;
 }
 
 static bool paletteAdd(const uint8_t *rgb) {
-    uint16_t i = paletteIndex(rgb);
-    if (i < palette.len) return true;
-    if (i == 256) return false;
-    memcpy(palette.entries[palette.len++], rgb, 3);
-    return true;
+	uint16_t i = paletteIndex(rgb);
+	if (i < palette.len) return true;
+	if (i == 256) return false;
+	memcpy(palette.entries[palette.len++], rgb, 3);
+	return true;
 }
 
 static void readPalette(void) {
-    struct Chunk chunk;
-    for (;;) {
-        chunk = readChunk();
-        if (0 == memcmp(chunk.type, "PLTE", 4)) break;
-        skipChunk(chunk);
-    }
-    if (chunk.size % 3) {
-        errx(EX_DATAERR, "%s: PLTE size %u not divisible by 3", path, chunk.size);
-    }
+	struct Chunk chunk;
+	for (;;) {
+		chunk = readChunk();
+		if (0 == memcmp(chunk.type, "PLTE", 4)) break;
+		skipChunk(chunk);
+	}
+	if (chunk.size % 3) {
+		errx(EX_DATAERR, "%s: PLTE size %u not divisible by 3", path, chunk.size);
+	}
 
-    palette.len = chunk.size / 3;
-    readExpect(palette.entries, chunk.size, "palette data");
-    readCrc();
+	palette.len = chunk.size / 3;
+	readExpect(palette.entries, chunk.size, "palette data");
+	readCrc();
 
-    if (verbose) fprintf(stderr, "%s: palette length %u\n", path, palette.len);
+	if (verbose) fprintf(stderr, "%s: palette length %u\n", path, palette.len);
 }
 
 static void writePalette(void) {
-    if (verbose) fprintf(stderr, "%s: palette length %u\n", path, palette.len);
-    struct Chunk plte = { .size = 3 * palette.len, .type = "PLTE" };
-    writeChunk(plte);
-    writeExpect(palette.entries, plte.size);
-    writeCrc();
+	if (verbose) fprintf(stderr, "%s: palette length %u\n", path, palette.len);
+	struct Chunk plte = { .size = 3 * palette.len, .type = "PLTE" };
+	writeChunk(plte);
+	writeExpect(palette.entries, plte.size);
+	writeCrc();
 }
 
 static uint8_t *data;
 
 static void allocData(void) {
-    data = malloc(dataSize());
-    if (!data) err(EX_OSERR, "malloc(%zu)", dataSize());
+	data = malloc(dataSize());
+	if (!data) err(EX_OSERR, "malloc(%zu)", dataSize());
 }
 
 static void readData(void) {
-    if (verbose) fprintf(stderr, "%s: data size %zu\n", path, dataSize());
-
-    struct z_stream_s stream = { .next_out = data, .avail_out = dataSize() };
-    int error = inflateInit(&stream);
-    if (error != Z_OK) errx(EX_SOFTWARE, "%s: inflateInit: %s", path, stream.msg);
-
-    for (;;) {
-        struct Chunk chunk = readChunk();
-        if (0 == memcmp(chunk.type, "IDAT", 4)) {
-            uint8_t idat[chunk.size];
-            readExpect(idat, sizeof(idat), "image data");
-            readCrc();
-
-            stream.next_in = idat;
-            stream.avail_in = sizeof(idat);
-            int error = inflate(&stream, Z_SYNC_FLUSH);
-            if (error == Z_STREAM_END) break;
-            if (error != Z_OK) errx(EX_DATAERR, "%s: inflate: %s", path, stream.msg);
-
-        } else if (0 == memcmp(chunk.type, "IEND", 4)) {
-            errx(EX_DATAERR, "%s: missing IDAT chunk", path);
-        } else {
-            skipChunk(chunk);
-        }
-    }
-
-    inflateEnd(&stream);
-    if (stream.total_out != dataSize()) {
-        errx(
-            EX_DATAERR, "%s: expected data size %zu, found %lu",
-            path, dataSize(), stream.total_out
-        );
-    }
-
-    if (verbose) fprintf(stderr, "%s: deflate size %lu\n", path, stream.total_in);
+	if (verbose) fprintf(stderr, "%s: data size %zu\n", path, dataSize());
+
+	struct z_stream_s stream = { .next_out = data, .avail_out = dataSize() };
+	int error = inflateInit(&stream);
+	if (error != Z_OK) errx(EX_SOFTWARE, "%s: inflateInit: %s", path, stream.msg);
+
+	for (;;) {
+		struct Chunk chunk = readChunk();
+		if (0 == memcmp(chunk.type, "IDAT", 4)) {
+			uint8_t idat[chunk.size];
+			readExpect(idat, sizeof(idat), "image data");
+			readCrc();
+
+			stream.next_in = idat;
+			stream.avail_in = sizeof(idat);
+			int error = inflate(&stream, Z_SYNC_FLUSH);
+			if (error == Z_STREAM_END) break;
+			if (error != Z_OK) errx(EX_DATAERR, "%s: inflate: %s", path, stream.msg);
+
+		} else if (0 == memcmp(chunk.type, "IEND", 4)) {
+			errx(EX_DATAERR, "%s: missing IDAT chunk", path);
+		} else {
+			skipChunk(chunk);
+		}
+	}
+
+	inflateEnd(&stream);
+	if (stream.total_out != dataSize()) {
+		errx(
+			EX_DATAERR, "%s: expected data size %zu, found %lu",
+			path, dataSize(), stream.total_out
+		);
+	}
+
+	if (verbose) fprintf(stderr, "%s: deflate size %lu\n", path, stream.total_in);
 }
 
 static void writeData(void) {
-    if (verbose) fprintf(stderr, "%s: data size %zu\n", path, dataSize());
+	if (verbose) fprintf(stderr, "%s: data size %zu\n", path, dataSize());
 
-    uLong size = compressBound(dataSize());
-    uint8_t deflate[size];
-    int error = compress2(deflate, &size, data, dataSize(), Z_BEST_COMPRESSION);
-    if (error != Z_OK) errx(EX_SOFTWARE, "%s: compress2: %d", path, error);
+	uLong size = compressBound(dataSize());
+	uint8_t deflate[size];
+	int error = compress2(deflate, &size, data, dataSize(), Z_BEST_COMPRESSION);
+	if (error != Z_OK) errx(EX_SOFTWARE, "%s: compress2: %d", path, error);
 
-    struct Chunk idat = { .size = size, .type = "IDAT" };
-    writeChunk(idat);
-    writeExpect(deflate, size);
-    writeCrc();
+	struct Chunk idat = { .size = size, .type = "IDAT" };
+	writeChunk(idat);
+	writeExpect(deflate, size);
+	writeCrc();
 
-    if (verbose) fprintf(stderr, "%s: deflate size %lu\n", path, size);
+	if (verbose) fprintf(stderr, "%s: deflate size %lu\n", path, size);
 }
 
 static void writeEnd(void) {
-    struct Chunk iend = { .size = 0, .type = "IEND" };
-    writeChunk(iend);
-    writeCrc();
+	struct Chunk iend = { .size = 0, .type = "IEND" };
+	writeChunk(iend);
+	writeCrc();
 }
 
 enum PACKED Filter {
-    NONE,
-    SUB,
-    UP,
-    AVERAGE,
-    PAETH,
-    FILTER_COUNT,
+	NONE,
+	SUB,
+	UP,
+	AVERAGE,
+	PAETH,
+	FILTER_COUNT,
 };
 
 struct Bytes {
-    uint8_t x;
-    uint8_t a;
-    uint8_t b;
-    uint8_t c;
+	uint8_t x;
+	uint8_t a;
+	uint8_t b;
+	uint8_t c;
 };
 
 static uint8_t paethPredictor(struct Bytes f) {
-    int32_t p = (int32_t)f.a + (int32_t)f.b - (int32_t)f.c;
-    int32_t pa = abs(p - (int32_t)f.a);
-    int32_t pb = abs(p - (int32_t)f.b);
-    int32_t pc = abs(p - (int32_t)f.c);
-    if (pa <= pb && pa <= pc) return f.a;
-    if (pb <= pc) return f.b;
-    return f.c;
+	int32_t p = (int32_t)f.a + (int32_t)f.b - (int32_t)f.c;
+	int32_t pa = abs(p - (int32_t)f.a);
+	int32_t pb = abs(p - (int32_t)f.b);
+	int32_t pc = abs(p - (int32_t)f.c);
+	if (pa <= pb && pa <= pc) return f.a;
+	if (pb <= pc) return f.b;
+	return f.c;
 }
 
 static uint8_t recon(enum Filter type, struct Bytes f) {
-    switch (type) {
-        case NONE:    return f.x;
-        case SUB:     return f.x + f.a;
-        case UP:      return f.x + f.b;
-        case AVERAGE: return f.x + ((uint32_t)f.a + (uint32_t)f.b) / 2;
-        case PAETH:   return f.x + paethPredictor(f);
-        default:      abort();
-    }
+	switch (type) {
+		case NONE:    return f.x;
+		case SUB:     return f.x + f.a;
+		case UP:      return f.x + f.b;
+		case AVERAGE: return f.x + ((uint32_t)f.a + (uint32_t)f.b) / 2;
+		case PAETH:   return f.x + paethPredictor(f);
+		default:      abort();
+	}
 }
 
 static uint8_t filt(enum Filter type, struct Bytes f) {
-    switch (type) {
-        case NONE:    return f.x;
-        case SUB:     return f.x - f.a;
-        case UP:      return f.x - f.b;
-        case AVERAGE: return f.x - ((uint32_t)f.a + (uint32_t)f.b) / 2;
-        case PAETH:   return f.x - paethPredictor(f);
-        default:      abort();
-    }
+	switch (type) {
+		case NONE:    return f.x;
+		case SUB:     return f.x - f.a;
+		case UP:      return f.x - f.b;
+		case AVERAGE: return f.x - ((uint32_t)f.a + (uint32_t)f.b) / 2;
+		case PAETH:   return f.x - paethPredictor(f);
+		default:      abort();
+	}
 }
 
 static struct Line {
-    enum Filter type;
-    uint8_t data[];
+	enum Filter type;
+	uint8_t data[];
 } **lines;
 
 static void allocLines(void) {
-    lines = calloc(header.height, sizeof(*lines));
-    if (!lines) err(EX_OSERR, "calloc(%u, %zu)", header.height, sizeof(*lines));
+	lines = calloc(header.height, sizeof(*lines));
+	if (!lines) err(EX_OSERR, "calloc(%u, %zu)", header.height, sizeof(*lines));
 }
 
 static void scanlines(void) {
-    size_t stride = 1 + lineSize();
-    for (uint32_t y = 0; y < header.height; ++y) {
-        lines[y] = (struct Line *)&data[y * stride];
-        if (lines[y]->type >= FILTER_COUNT) {
-            errx(EX_DATAERR, "%s: invalid filter type %hhu", path, lines[y]->type);
-        }
-    }
+	size_t stride = 1 + lineSize();
+	for (uint32_t y = 0; y < header.height; ++y) {
+		lines[y] = (struct Line *)&data[y * stride];
+		if (lines[y]->type >= FILTER_COUNT) {
+			errx(EX_DATAERR, "%s: invalid filter type %hhu", path, lines[y]->type);
+		}
+	}
 }
 
 static struct Bytes origBytes(uint32_t y, size_t i) {
-    size_t pixelSize = lineSize() / header.width;
-    if (!pixelSize) pixelSize = 1;
-    bool a = (i >= pixelSize), b = (y > 0), c = (a && b);
-    return (struct Bytes) {
-        .x = lines[y]->data[i],
-        .a = a ? lines[y]->data[i - pixelSize] : 0,
-        .b = b ? lines[y - 1]->data[i] : 0,
-        .c = c ? lines[y - 1]->data[i - pixelSize] : 0,
-    };
+	size_t pixelSize = lineSize() / header.width;
+	if (!pixelSize) pixelSize = 1;
+	bool a = (i >= pixelSize), b = (y > 0), c = (a && b);
+	return (struct Bytes) {
+		.x = lines[y]->data[i],
+		.a = a ? lines[y]->data[i - pixelSize] : 0,
+		.b = b ? lines[y - 1]->data[i] : 0,
+		.c = c ? lines[y - 1]->data[i - pixelSize] : 0,
+	};
 }
 
 static void reconData(void) {
-    for (uint32_t y = 0; y < header.height; ++y) {
-        for (size_t i = 0; i < lineSize(); ++i) {
-            lines[y]->data[i] =
-                recon(lines[y]->type, origBytes(y, i));
-        }
-        lines[y]->type = NONE;
-    }
+	for (uint32_t y = 0; y < header.height; ++y) {
+		for (size_t i = 0; i < lineSize(); ++i) {
+			lines[y]->data[i] =
+				recon(lines[y]->type, origBytes(y, i));
+		}
+		lines[y]->type = NONE;
+	}
 }
 
 static void filterData(void) {
-    if (header.color == INDEXED || header.depth < 8) return;
-    for (uint32_t y = header.height - 1; y < header.height; --y) {
-        uint8_t filter[FILTER_COUNT][lineSize()];
-        uint32_t heuristic[FILTER_COUNT] = {0};
-        enum Filter minType = NONE;
-        for (enum Filter type = NONE; type < FILTER_COUNT; ++type) {
-            for (size_t i = 0; i < lineSize(); ++i) {
-                filter[type][i] = filt(type, origBytes(y, i));
-                heuristic[type] += abs((int8_t)filter[type][i]);
-            }
-            if (heuristic[type] < heuristic[minType]) minType = type;
-        }
-        lines[y]->type = minType;
-        memcpy(lines[y]->data, filter[minType], lineSize());
-    }
+	if (header.color == INDEXED || header.depth < 8) return;
+	for (uint32_t y = header.height - 1; y < header.height; --y) {
+		uint8_t filter[FILTER_COUNT][lineSize()];
+		uint32_t heuristic[FILTER_COUNT] = {0};
+		enum Filter minType = NONE;
+		for (enum Filter type = NONE; type < FILTER_COUNT; ++type) {
+			for (size_t i = 0; i < lineSize(); ++i) {
+				filter[type][i] = filt(type, origBytes(y, i));
+				heuristic[type] += abs((int8_t)filter[type][i]);
+			}
+			if (heuristic[type] < heuristic[minType]) minType = type;
+		}
+		lines[y]->type = minType;
+		memcpy(lines[y]->data, filter[minType], lineSize());
+	}
 }
 
 static void discardAlpha(void) {
-    if (header.color != GRAYSCALE_ALPHA && header.color != TRUECOLOR_ALPHA) return;
-    size_t sampleSize = header.depth / 8;
-    size_t pixelSize = sampleSize * (header.color == GRAYSCALE_ALPHA ? 2 : 4);
-    size_t colorSize = pixelSize - sampleSize;
-    for (uint32_t y = 0; y < header.height; ++y) {
-        for (uint32_t x = 0; x < header.width; ++x) {
-            for (size_t i = 0; i < sampleSize; ++i) {
-                if (lines[y]->data[x * pixelSize + colorSize + i] != 0xFF) return;
-            }
-        }
-    }
-
-    uint8_t *ptr = data;
-    for (uint32_t y = 0; y < header.height; ++y) {
-        *ptr++ = lines[y]->type;
-        for (uint32_t x = 0; x < header.width; ++x) {
-            memmove(ptr, &lines[y]->data[x * pixelSize], colorSize);
-            ptr += colorSize;
-        }
-    }
-    header.color = (header.color == GRAYSCALE_ALPHA) ? GRAYSCALE : TRUECOLOR;
-    scanlines();
+	if (header.color != GRAYSCALE_ALPHA && header.color != TRUECOLOR_ALPHA) return;
+	size_t sampleSize = header.depth / 8;
+	size_t pixelSize = sampleSize * (header.color == GRAYSCALE_ALPHA ? 2 : 4);
+	size_t colorSize = pixelSize - sampleSize;
+	for (uint32_t y = 0; y < header.height; ++y) {
+		for (uint32_t x = 0; x < header.width; ++x) {
+			for (size_t i = 0; i < sampleSize; ++i) {
+				if (lines[y]->data[x * pixelSize + colorSize + i] != 0xFF) return;
+			}
+		}
+	}
+
+	uint8_t *ptr = data;
+	for (uint32_t y = 0; y < header.height; ++y) {
+		*ptr++ = lines[y]->type;
+		for (uint32_t x = 0; x < header.width; ++x) {
+			memmove(ptr, &lines[y]->data[x * pixelSize], colorSize);
+			ptr += colorSize;
+		}
+	}
+	header.color = (header.color == GRAYSCALE_ALPHA) ? GRAYSCALE : TRUECOLOR;
+	scanlines();
 }
 
 static void discardColor(void) {
-    if (header.color != TRUECOLOR && header.color != TRUECOLOR_ALPHA) return;
-    size_t sampleSize = header.depth / 8;
-    size_t pixelSize = sampleSize * (header.color == TRUECOLOR ? 3 : 4);
-    for (uint32_t y = 0; y < header.height; ++y) {
-        for (uint32_t x = 0; x < header.width; ++x) {
-            uint8_t *r = &lines[y]->data[x * pixelSize];
-            uint8_t *g = r + sampleSize;
-            uint8_t *b = g + sampleSize;
-            if (0 != memcmp(r, g, sampleSize)) return;
-            if (0 != memcmp(g, b, sampleSize)) return;
-        }
-    }
-
-    uint8_t *ptr = data;
-    for (uint32_t y = 0; y < header.height; ++y) {
-        *ptr++ = lines[y]->type;
-        for (uint32_t x = 0; x < header.width; ++x) {
-            uint8_t *pixel = &lines[y]->data[x * pixelSize];
-            memmove(ptr, pixel, sampleSize);
-            ptr += sampleSize;
-            if (header.color == TRUECOLOR_ALPHA) {
-                memmove(ptr, pixel + 3 * sampleSize, sampleSize);
-                ptr += sampleSize;
-            }
-        }
-    }
-    header.color = (header.color == TRUECOLOR) ? GRAYSCALE : GRAYSCALE_ALPHA;
-    scanlines();
+	if (header.color != TRUECOLOR && header.color != TRUECOLOR_ALPHA) return;
+	size_t sampleSize = header.depth / 8;
+	size_t pixelSize = sampleSize * (header.color == TRUECOLOR ? 3 : 4);
+	for (uint32_t y = 0; y < header.height; ++y) {
+		for (uint32_t x = 0; x < header.width; ++x) {
+			uint8_t *r = &lines[y]->data[x * pixelSize];
+			uint8_t *g = r + sampleSize;
+			uint8_t *b = g + sampleSize;
+			if (0 != memcmp(r, g, sampleSize)) return;
+			if (0 != memcmp(g, b, sampleSize)) return;
+		}
+	}
+
+	uint8_t *ptr = data;
+	for (uint32_t y = 0; y < header.height; ++y) {
+		*ptr++ = lines[y]->type;
+		for (uint32_t x = 0; x < header.width; ++x) {
+			uint8_t *pixel = &lines[y]->data[x * pixelSize];
+			memmove(ptr, pixel, sampleSize);
+			ptr += sampleSize;
+			if (header.color == TRUECOLOR_ALPHA) {
+				memmove(ptr, pixel + 3 * sampleSize, sampleSize);
+				ptr += sampleSize;
+			}
+		}
+	}
+	header.color = (header.color == TRUECOLOR) ? GRAYSCALE : GRAYSCALE_ALPHA;
+	scanlines();
 }
 
 static void indexColor(void) {
-    if (header.color != TRUECOLOR || header.depth != 8) return;
-    for (uint32_t y = 0; y < header.height; ++y) {
-        for (uint32_t x = 0; x < header.width; ++x) {
-            if (!paletteAdd(&lines[y]->data[x * 3])) return;
-        }
-    }
-
-    uint8_t *ptr = data;
-    for (uint32_t y = 0; y < header.height; ++y) {
-        *ptr++ = lines[y]->type;
-        for (uint32_t x = 0; x < header.width; ++x) {
-            *ptr++ = paletteIndex(&lines[y]->data[x * 3]);
-        }
-    }
-    header.color = INDEXED;
-    scanlines();
+	if (header.color != TRUECOLOR || header.depth != 8) return;
+	for (uint32_t y = 0; y < header.height; ++y) {
+		for (uint32_t x = 0; x < header.width; ++x) {
+			if (!paletteAdd(&lines[y]->data[x * 3])) return;
+		}
+	}
+
+	uint8_t *ptr = data;
+	for (uint32_t y = 0; y < header.height; ++y) {
+		*ptr++ = lines[y]->type;
+		for (uint32_t x = 0; x < header.width; ++x) {
+			*ptr++ = paletteIndex(&lines[y]->data[x * 3]);
+		}
+	}
+	header.color = INDEXED;
+	scanlines();
 }
 
 static void reduceDepth8(void) {
-    if (header.color != GRAYSCALE && header.color != INDEXED) return;
-    if (header.depth != 8) return;
-    if (header.color == GRAYSCALE) {
-        for (uint32_t y = 0; y < header.height; ++y) {
-            for (size_t i = 0; i < lineSize(); ++i) {
-                uint8_t a = lines[y]->data[i];
-                if ((a >> 4) != (a & 0x0F)) return;
-            }
-        }
-    } else if (palette.len > 16) {
-        return;
-    }
-
-    uint8_t *ptr = data;
-    for (uint32_t y = 0; y < header.height; ++y) {
-        *ptr++ = lines[y]->type;
-        for (size_t i = 0; i < lineSize(); i += 2) {
-            uint8_t iByte = lines[y]->data[i];
-            uint8_t jByte = (i + 1 < lineSize()) ? lines[y]->data[i + 1] : 0;
-            uint8_t a = iByte & 0x0F;
-            uint8_t b = jByte & 0x0F;
-            *ptr++ = a << 4 | b;
-        }
-    }
-    header.depth = 4;
-    scanlines();
+	if (header.color != GRAYSCALE && header.color != INDEXED) return;
+	if (header.depth != 8) return;
+	if (header.color == GRAYSCALE) {
+		for (uint32_t y = 0; y < header.height; ++y) {
+			for (size_t i = 0; i < lineSize(); ++i) {
+				uint8_t a = lines[y]->data[i];
+				if ((a >> 4) != (a & 0x0F)) return;
+			}
+		}
+	} else if (palette.len > 16) {
+		return;
+	}
+
+	uint8_t *ptr = data;
+	for (uint32_t y = 0; y < header.height; ++y) {
+		*ptr++ = lines[y]->type;
+		for (size_t i = 0; i < lineSize(); i += 2) {
+			uint8_t iByte = lines[y]->data[i];
+			uint8_t jByte = (i + 1 < lineSize()) ? lines[y]->data[i + 1] : 0;
+			uint8_t a = iByte & 0x0F;
+			uint8_t b = jByte & 0x0F;
+			*ptr++ = a << 4 | b;
+		}
+	}
+	header.depth = 4;
+	scanlines();
 }
 
 static void reduceDepth4(void) {
-    if (header.depth != 4) return;
-    if (header.color == GRAYSCALE) {
-        for (uint32_t y = 0; y < header.height; ++y) {
-            for (size_t i = 0; i < lineSize(); ++i) {
-                uint8_t a = lines[y]->data[i] >> 4;
-                uint8_t b = lines[y]->data[i] & 0x0F;
-                if ((a >> 2) != (a & 0x03)) return;
-                if ((b >> 2) != (b & 0x03)) return;
-            }
-        }
-    } else if (palette.len > 4) {
-        return;
-    }
-
-    uint8_t *ptr = data;
-    for (uint32_t y = 0; y < header.height; ++y) {
-        *ptr++ = lines[y]->type;
-        for (size_t i = 0; i < lineSize(); i += 2) {
-            uint8_t iByte = lines[y]->data[i];
-            uint8_t jByte = (i + 1 < lineSize()) ? lines[y]->data[i + 1] : 0;
-            uint8_t a = iByte >> 4 & 0x03, b = iByte & 0x03;
-            uint8_t c = jByte >> 4 & 0x03, d = jByte & 0x03;
-            *ptr++ = a << 6 | b << 4 | c << 2 | d;
-        }
-    }
-    header.depth = 2;
-    scanlines();
+	if (header.depth != 4) return;
+	if (header.color == GRAYSCALE) {
+		for (uint32_t y = 0; y < header.height; ++y) {
+			for (size_t i = 0; i < lineSize(); ++i) {
+				uint8_t a = lines[y]->data[i] >> 4;
+				uint8_t b = lines[y]->data[i] & 0x0F;
+				if ((a >> 2) != (a & 0x03)) return;
+				if ((b >> 2) != (b & 0x03)) return;
+			}
+		}
+	} else if (palette.len > 4) {
+		return;
+	}
+
+	uint8_t *ptr = data;
+	for (uint32_t y = 0; y < header.height; ++y) {
+		*ptr++ = lines[y]->type;
+		for (size_t i = 0; i < lineSize(); i += 2) {
+			uint8_t iByte = lines[y]->data[i];
+			uint8_t jByte = (i + 1 < lineSize()) ? lines[y]->data[i + 1] : 0;
+			uint8_t a = iByte >> 4 & 0x03, b = iByte & 0x03;
+			uint8_t c = jByte >> 4 & 0x03, d = jByte & 0x03;
+			*ptr++ = a << 6 | b << 4 | c << 2 | d;
+		}
+	}
+	header.depth = 2;
+	scanlines();
 }
 
 static void reduceDepth2(void) {
-    if (header.depth != 2) return;
-    if (header.color == GRAYSCALE) {
-        for (uint32_t y = 0; y < header.height; ++y) {
-            for (size_t i = 0; i < lineSize(); ++i) {
-                uint8_t a = lines[y]->data[i] >> 6;
-                uint8_t b = lines[y]->data[i] >> 4 & 0x03;
-                uint8_t c = lines[y]->data[i] >> 2 & 0x03;
-                uint8_t d = lines[y]->data[i] & 0x03;
-                if ((a >> 1) != (a & 0x01)) return;
-                if ((b >> 1) != (b & 0x01)) return;
-                if ((c >> 1) != (c & 0x01)) return;
-                if ((d >> 1) != (d & 0x01)) return;
-            }
-        }
-    } else if (palette.len > 2) {
-        return;
-    }
-
-    uint8_t *ptr = data;
-    for (uint32_t y = 0; y < header.height; ++y) {
-        *ptr++ = lines[y]->type;
-        for (size_t i = 0; i < lineSize(); i += 2) {
-            uint8_t iByte = lines[y]->data[i];
-            uint8_t jByte = (i + 1 < lineSize()) ? lines[y]->data[i + 1] : 0;
-            uint8_t a = iByte >> 6 & 0x01, b = iByte >> 4 & 0x01;
-            uint8_t c = iByte >> 2 & 0x01, d = iByte & 0x01;
-            uint8_t e = jByte >> 6 & 0x01, f = jByte >> 4 & 0x01;
-            uint8_t g = jByte >> 2 & 0x01, h = jByte & 0x01;
-            *ptr++ = a << 7 | b << 6 | c << 5 | d << 4 | e << 3 | f << 2 | g << 1 | h;
-        }
-    }
-    header.depth = 1;
-    scanlines();
+	if (header.depth != 2) return;
+	if (header.color == GRAYSCALE) {
+		for (uint32_t y = 0; y < header.height; ++y) {
+			for (size_t i = 0; i < lineSize(); ++i) {
+				uint8_t a = lines[y]->data[i] >> 6;
+				uint8_t b = lines[y]->data[i] >> 4 & 0x03;
+				uint8_t c = lines[y]->data[i] >> 2 & 0x03;
+				uint8_t d = lines[y]->data[i] & 0x03;
+				if ((a >> 1) != (a & 0x01)) return;
+				if ((b >> 1) != (b & 0x01)) return;
+				if ((c >> 1) != (c & 0x01)) return;
+				if ((d >> 1) != (d & 0x01)) return;
+			}
+		}
+	} else if (palette.len > 2) {
+		return;
+	}
+
+	uint8_t *ptr = data;
+	for (uint32_t y = 0; y < header.height; ++y) {
+		*ptr++ = lines[y]->type;
+		for (size_t i = 0; i < lineSize(); i += 2) {
+			uint8_t iByte = lines[y]->data[i];
+			uint8_t jByte = (i + 1 < lineSize()) ? lines[y]->data[i + 1] : 0;
+			uint8_t a = iByte >> 6 & 0x01, b = iByte >> 4 & 0x01;
+			uint8_t c = iByte >> 2 & 0x01, d = iByte & 0x01;
+			uint8_t e = jByte >> 6 & 0x01, f = jByte >> 4 & 0x01;
+			uint8_t g = jByte >> 2 & 0x01, h = jByte & 0x01;
+			*ptr++ = a << 7 | b << 6 | c << 5 | d << 4 | e << 3 | f << 2 | g << 1 | h;
+		}
+	}
+	header.depth = 1;
+	scanlines();
 }
 
 static void reduceDepth(void) {
-    reduceDepth8();
-    reduceDepth4();
-    reduceDepth2();
+	reduceDepth8();
+	reduceDepth4();
+	reduceDepth2();
 }
 
 static void optimize(const char *inPath, const char *outPath) {
-    if (inPath) {
-        path = inPath;
-        file = fopen(path, "r");
-        if (!file) err(EX_NOINPUT, "%s", path);
-    } else {
-        path = "(stdin)";
-        file = stdin;
-    }
-
-    readSignature();
-    readHeader();
-    if (header.interlace != PROGRESSIVE) {
-        errx(
-            EX_CONFIG, "%s: unsupported interlace method %hhu",
-            path, header.interlace
-        );
-    }
-    if (header.color == INDEXED) readPalette();
-    allocData();
-    readData();
-    fclose(file);
-
-    allocLines();
-    scanlines();
-    reconData();
-
-    discardAlpha();
-    discardColor();
-    indexColor();
-    reduceDepth();
-    filterData();
-    free(lines);
-
-    if (outPath) {
-        path = outPath;
-        file = fopen(path, "w");
-        if (!file) err(EX_CANTCREAT, "%s", path);
-    } else {
-        path = "(stdout)";
-        file = stdout;
-    }
-
-    writeSignature();
-    writeHeader();
-    if (header.color == INDEXED) writePalette();
-    writeData();
-    writeEnd();
-    free(data);
-
-    int error = fclose(file);
-    if (error) err(EX_IOERR, "%s", path);
+	if (inPath) {
+		path = inPath;
+		file = fopen(path, "r");
+		if (!file) err(EX_NOINPUT, "%s", path);
+	} else {
+		path = "(stdin)";
+		file = stdin;
+	}
+
+	readSignature();
+	readHeader();
+	if (header.interlace != PROGRESSIVE) {
+		errx(
+			EX_CONFIG, "%s: unsupported interlace method %hhu",
+			path, header.interlace
+		);
+	}
+	if (header.color == INDEXED) readPalette();
+	allocData();
+	readData();
+	fclose(file);
+
+	allocLines();
+	scanlines();
+	reconData();
+
+	discardAlpha();
+	discardColor();
+	indexColor();
+	reduceDepth();
+	filterData();
+	free(lines);
+
+	if (outPath) {
+		path = outPath;
+		file = fopen(path, "w");
+		if (!file) err(EX_CANTCREAT, "%s", path);
+	} else {
+		path = "(stdout)";
+		file = stdout;
+	}
+
+	writeSignature();
+	writeHeader();
+	if (header.color == INDEXED) writePalette();
+	writeData();
+	writeEnd();
+	free(data);
+
+	int error = fclose(file);
+	if (error) err(EX_IOERR, "%s", path);
 }
 
 int main(int argc, char *argv[]) {
-    bool stdio = false;
-    char *output = NULL;
-
-    int opt;
-    while (0 < (opt = getopt(argc, argv, "co:v"))) {
-        switch (opt) {
-            case 'c': stdio = true; break;
-            case 'o': output = optarg; break;
-            case 'v': verbose = true; break;
-            default: return EX_USAGE;
-        }
-    }
-
-    if (argc - optind == 1 && (output || stdio)) {
-        optimize(argv[optind], output);
-    } else if (optind < argc) {
-        for (int i = optind; i < argc; ++i) {
-            optimize(argv[i], argv[i]);
-        }
-    } else {
-        optimize(NULL, output);
-    }
-
-    return EX_OK;
+	bool stdio = false;
+	char *output = NULL;
+
+	int opt;
+	while (0 < (opt = getopt(argc, argv, "co:v"))) {
+		switch (opt) {
+			case 'c': stdio = true; break;
+			case 'o': output = optarg; break;
+			case 'v': verbose = true; break;
+			default: return EX_USAGE;
+		}
+	}
+
+	if (argc - optind == 1 && (output || stdio)) {
+		optimize(argv[optind], output);
+	} else if (optind < argc) {
+		for (int i = optind; i < argc; ++i) {
+			optimize(argv[i], argv[i]);
+		}
+	} else {
+		optimize(NULL, output);
+	}
+
+	return EX_OK;
 }
diff --git a/bin/scheme.c b/bin/scheme.c
index f3a386a8..b43e4fec 100644
--- a/bin/scheme.c
+++ b/bin/scheme.c
@@ -26,194 +26,194 @@
 #include <zlib.h>
 
 static const struct Hsv { double h, s, v; }
-    R = {   0.0, 1.0, 1.0 },
-    Y = {  60.0, 1.0, 1.0 },
-    G = { 120.0, 1.0, 1.0 },
-    C = { 180.0, 1.0, 1.0 },
-    B = { 240.0, 1.0, 1.0 },
-    M = { 300.0, 1.0, 1.0 };
+R = {   0.0, 1.0, 1.0 },
+  Y = {  60.0, 1.0, 1.0 },
+  G = { 120.0, 1.0, 1.0 },
+  C = { 180.0, 1.0, 1.0 },
+  B = { 240.0, 1.0, 1.0 },
+  M = { 300.0, 1.0, 1.0 };
 
 static struct Hsv x(struct Hsv o, double hd, double sf, double vf) {
-    return (struct Hsv) {
-        fmod(o.h + hd, 360.0),
-        fmin(o.s * sf, 1.0),
-        fmin(o.v * vf, 1.0),
-    };
+	return (struct Hsv) {
+		fmod(o.h + hd, 360.0),
+			fmin(o.s * sf, 1.0),
+			fmin(o.v * vf, 1.0),
+	};
 }
 
 struct Ansi {
-    enum { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
-    struct Hsv dark[8];
-    struct Hsv light[8];
+	enum { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE };
+	struct Hsv dark[8];
+	struct Hsv light[8];
 };
 
 struct Terminal {
-    struct Ansi ansi;
-    struct Hsv background, text, bold, selection, cursor;
+	struct Ansi ansi;
+	struct Hsv background, text, bold, selection, cursor;
 };
 
 #define HSV_LEN(x) (sizeof(x) / sizeof(struct Hsv))
 struct Scheme {
-    size_t len;
-    union {
-        struct Hsv hsv;
-        struct Ansi ansi;
-        struct Terminal terminal;
-    };
+	size_t len;
+	union {
+		struct Hsv hsv;
+		struct Ansi ansi;
+		struct Terminal terminal;
+	};
 };
 
 static struct Scheme ansi(void) {
-    struct Ansi a = {
-        .light = {
-            [BLACK]   = x(R, +45.0, 0.3, 0.3),
-            [RED]     = x(R, +10.0, 0.9, 0.8),
-            [GREEN]   = x(G, -55.0, 0.8, 0.6),
-            [YELLOW]  = x(Y, -20.0, 0.8, 0.8),
-            [BLUE]    = x(B, -55.0, 0.4, 0.5),
-            [MAGENTA] = x(M, +45.0, 0.4, 0.6),
-            [CYAN]    = x(C, -60.0, 0.3, 0.6),
-            [WHITE]   = x(R, +45.0, 0.3, 0.8),
-        },
-    };
-    a.dark[BLACK] = x(a.light[BLACK], 0.0, 1.0, 0.3);
-    a.dark[WHITE] = x(a.light[WHITE], 0.0, 1.0, 0.6);
-    for (int i = RED; i < WHITE; ++i) {
-        a.dark[i] = x(a.light[i], 0.0, 1.0, 0.8);
-    }
-    return (struct Scheme) { .len = HSV_LEN(a), .ansi = a };
+	struct Ansi a = {
+		.light = {
+			[BLACK]   = x(R, +45.0, 0.3, 0.3),
+			[RED]     = x(R, +10.0, 0.9, 0.8),
+			[GREEN]   = x(G, -55.0, 0.8, 0.6),
+			[YELLOW]  = x(Y, -20.0, 0.8, 0.8),
+			[BLUE]    = x(B, -55.0, 0.4, 0.5),
+			[MAGENTA] = x(M, +45.0, 0.4, 0.6),
+			[CYAN]    = x(C, -60.0, 0.3, 0.6),
+			[WHITE]   = x(R, +45.0, 0.3, 0.8),
+		},
+	};
+	a.dark[BLACK] = x(a.light[BLACK], 0.0, 1.0, 0.3);
+	a.dark[WHITE] = x(a.light[WHITE], 0.0, 1.0, 0.6);
+	for (int i = RED; i < WHITE; ++i) {
+		a.dark[i] = x(a.light[i], 0.0, 1.0, 0.8);
+	}
+	return (struct Scheme) { .len = HSV_LEN(a), .ansi = a };
 }
 
 static struct Scheme terminal(void) {
-    struct Ansi a = ansi().ansi;
-    struct Terminal t = {
-        .ansi       = a,
-        .background = x(a.dark[BLACK],    0.0, 1.0, 0.9),
-        .text       = x(a.light[WHITE],   0.0, 1.0, 0.9),
-        .bold       = x(a.light[WHITE],   0.0, 1.0, 1.0),
-        .selection  = x(a.light[RED],   +10.0, 1.0, 0.8),
-        .cursor     = x(a.dark[WHITE],    0.0, 1.0, 0.8),
-    };
-    return (struct Scheme) { .len = HSV_LEN(t), .terminal = t };
+	struct Ansi a = ansi().ansi;
+	struct Terminal t = {
+		.ansi       = a,
+		.background = x(a.dark[BLACK],    0.0, 1.0, 0.9),
+		.text       = x(a.light[WHITE],   0.0, 1.0, 0.9),
+		.bold       = x(a.light[WHITE],   0.0, 1.0, 1.0),
+		.selection  = x(a.light[RED],   +10.0, 1.0, 0.8),
+		.cursor     = x(a.dark[WHITE],    0.0, 1.0, 0.8),
+	};
+	return (struct Scheme) { .len = HSV_LEN(t), .terminal = t };
 }
 
 static void hsv(const struct Hsv *hsv, size_t len) {
-    for (size_t i = 0; i < len; ++i) {
-        printf("%g,%g,%g\n", hsv[i].h, hsv[i].s, hsv[i].v);
-    }
+	for (size_t i = 0; i < len; ++i) {
+		printf("%g,%g,%g\n", hsv[i].h, hsv[i].s, hsv[i].v);
+	}
 }
 
 struct Rgb { uint8_t r, g, b; };
 static struct Rgb toRgb(struct Hsv hsv) {
-    double c = hsv.v * hsv.s;
-    double h = hsv.h / 60.0;
-    double x = c * (1.0 - fabs(fmod(h, 2.0) - 1.0));
-    double m = hsv.v - c;
-    double r = m, g = m, b = m;
-    if      (h <= 1.0) { r += c; g += x; }
-    else if (h <= 2.0) { r += x; g += c; }
-    else if (h <= 3.0) { g += c; b += x; }
-    else if (h <= 4.0) { g += x; b += c; }
-    else if (h <= 5.0) { r += x; b += c; }
-    else if (h <= 6.0) { r += c; b += x; }
-    return (struct Rgb) { r * 255.0, g * 255.0, b * 255.0 };
+	double c = hsv.v * hsv.s;
+	double h = hsv.h / 60.0;
+	double x = c * (1.0 - fabs(fmod(h, 2.0) - 1.0));
+	double m = hsv.v - c;
+	double r = m, g = m, b = m;
+	if      (h <= 1.0) { r += c; g += x; }
+	else if (h <= 2.0) { r += x; g += c; }
+	else if (h <= 3.0) { g += c; b += x; }
+	else if (h <= 4.0) { g += x; b += c; }
+	else if (h <= 5.0) { r += x; b += c; }
+	else if (h <= 6.0) { r += c; b += x; }
+	return (struct Rgb) { r * 255.0, g * 255.0, b * 255.0 };
 }
 
 static void hex(const struct Hsv *hsv, size_t len) {
-    for (size_t i = 0; i < len; ++i) {
-        struct Rgb rgb = toRgb(hsv[i]);
-        printf("%02X%02X%02X\n", rgb.r, rgb.g, rgb.b);
-    }
+	for (size_t i = 0; i < len; ++i) {
+		struct Rgb rgb = toRgb(hsv[i]);
+		printf("%02X%02X%02X\n", rgb.r, rgb.g, rgb.b);
+	}
 }
 
 static void linux(const struct Hsv *hsv, size_t len) {
-    if (len > 16) len = 16;
-    for (size_t i = 0; i < len; ++i) {
-        struct Rgb rgb = toRgb(hsv[i]);
-        printf("\x1B]P%zX%02X%02X%02X", i, rgb.r, rgb.g, rgb.b);
-    }
+	if (len > 16) len = 16;
+	for (size_t i = 0; i < len; ++i) {
+		struct Rgb rgb = toRgb(hsv[i]);
+		printf("\x1B]P%zX%02X%02X%02X", i, rgb.r, rgb.g, rgb.b);
+	}
 }
 
 static uint32_t crc;
 static void pngWrite(const void *ptr, size_t size) {
-    fwrite(ptr, size, 1, stdout);
-    if (ferror(stdout)) err(EX_IOERR, "(stdout)");
-    crc = crc32(crc, ptr, size);
+	fwrite(ptr, size, 1, stdout);
+	if (ferror(stdout)) err(EX_IOERR, "(stdout)");
+	crc = crc32(crc, ptr, size);
 }
 static void pngInt(uint32_t host) {
-    uint32_t net = htonl(host);
-    pngWrite(&net, 4);
+	uint32_t net = htonl(host);
+	pngWrite(&net, 4);
 }
 static void pngChunk(const char *type, uint32_t size) {
-    pngInt(size);
-    crc = crc32(0, Z_NULL, 0);
-    pngWrite(type, 4);
+	pngInt(size);
+	crc = crc32(0, Z_NULL, 0);
+	pngWrite(type, 4);
 }
 
 static void png(const struct Hsv *hsv, size_t len) {
-    if (len > 256) len = 256;
-    uint32_t swatchWidth = 64;
-    uint32_t swatchHeight = 64;
-    uint32_t columns = 8;
-    uint32_t rows = (len + columns - 1) / columns;
-    uint32_t width = swatchWidth * columns;
-    uint32_t height = swatchHeight * rows;
-
-    pngWrite("\x89PNG\r\n\x1A\n", 8);
-
-    pngChunk("IHDR", 13);
-    pngInt(width);
-    pngInt(height);
-    pngWrite("\x08\x03\0\0\0", 5);
-    pngInt(crc);
-
-    pngChunk("PLTE", 3 * len);
-    for (size_t i = 0; i < len; ++i) {
-        struct Rgb rgb = toRgb(hsv[i]);
-        pngWrite(&rgb, 3);
-    }
-    pngInt(crc);
-
-    uint8_t data[height][1 + width];
-    memset(data, 0, sizeof(data));
-    for (uint32_t y = 0; y < height; ++y) {
-        enum { NONE, SUB, UP, AVERAGE, PAETH };
-        data[y][0] = (y % swatchHeight) ? UP : SUB;
-    }
-    for (size_t i = 0; i < len; ++i) {
-        uint32_t y = swatchHeight * (i / columns);
-        uint32_t x = swatchWidth * (i % columns);
-        data[y][1 + x] = x ? 1 : i;
-    }
-
-    uLong size = compressBound(sizeof(data));
-    uint8_t deflate[size];
-    int error = compress(deflate, &size, (Byte *)data, sizeof(data));
-    if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error);
-
-    pngChunk("IDAT", size);
-    pngWrite(deflate, size);
-    pngInt(crc);
-
-    pngChunk("IEND", 0);
-    pngInt(crc);
+	if (len > 256) len = 256;
+	uint32_t swatchWidth = 64;
+	uint32_t swatchHeight = 64;
+	uint32_t columns = 8;
+	uint32_t rows = (len + columns - 1) / columns;
+	uint32_t width = swatchWidth * columns;
+	uint32_t height = swatchHeight * rows;
+
+	pngWrite("\x89PNG\r\n\x1A\n", 8);
+
+	pngChunk("IHDR", 13);
+	pngInt(width);
+	pngInt(height);
+	pngWrite("\x08\x03\0\0\0", 5);
+	pngInt(crc);
+
+	pngChunk("PLTE", 3 * len);
+	for (size_t i = 0; i < len; ++i) {
+		struct Rgb rgb = toRgb(hsv[i]);
+		pngWrite(&rgb, 3);
+	}
+	pngInt(crc);
+
+	uint8_t data[height][1 + width];
+	memset(data, 0, sizeof(data));
+	for (uint32_t y = 0; y < height; ++y) {
+		enum { NONE, SUB, UP, AVERAGE, PAETH };
+		data[y][0] = (y % swatchHeight) ? UP : SUB;
+	}
+	for (size_t i = 0; i < len; ++i) {
+		uint32_t y = swatchHeight * (i / columns);
+		uint32_t x = swatchWidth * (i % columns);
+		data[y][1 + x] = x ? 1 : i;
+	}
+
+	uLong size = compressBound(sizeof(data));
+	uint8_t deflate[size];
+	int error = compress(deflate, &size, (Byte *)data, sizeof(data));
+	if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error);
+
+	pngChunk("IDAT", size);
+	pngWrite(deflate, size);
+	pngInt(crc);
+
+	pngChunk("IEND", 0);
+	pngInt(crc);
 }
 
 int main(int argc, char *argv[]) {
-    struct Scheme (*gen)(void) = ansi;
-    void (*out)(const struct Hsv *, size_t len) = hex;
-    int opt;
-    while (0 < (opt = getopt(argc, argv, "aghltx"))) {
-        switch (opt) {
-            case 'a': gen = ansi; break;
-            case 'g': out = png; break;
-            case 'h': out = hsv; break;
-            case 'l': out = linux; break;
-            case 't': gen = terminal; break;
-            case 'x': out = hex; break;
-            default: return EX_USAGE;
-        }
-    }
-    struct Scheme scheme = gen();
-    out(&scheme.hsv, scheme.len);
-    return EX_OK;
+	struct Scheme (*gen)(void) = ansi;
+	void (*out)(const struct Hsv *, size_t len) = hex;
+	int opt;
+	while (0 < (opt = getopt(argc, argv, "aghltx"))) {
+		switch (opt) {
+			case 'a': gen = ansi; break;
+			case 'g': out = png; break;
+			case 'h': out = hsv; break;
+			case 'l': out = linux; break;
+			case 't': gen = terminal; break;
+			case 'x': out = hex; break;
+			default: return EX_USAGE;
+		}
+	}
+	struct Scheme scheme = gen();
+	out(&scheme.hsv, scheme.len);
+	return EX_OK;
 }
diff --git a/bin/wake.c b/bin/wake.c
index 3cfb5b38..205c202c 100644
--- a/bin/wake.c
+++ b/bin/wake.c
@@ -25,29 +25,29 @@
 
 #define MAC 0x04, 0x7D, 0x7B, 0xD5, 0x6A, 0x53
 static const uint8_t payload[102] = {
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
-    MAC, MAC, MAC, MAC, MAC, MAC, MAC, MAC,
-    MAC, MAC, MAC, MAC, MAC, MAC, MAC, MAC,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	MAC, MAC, MAC, MAC, MAC, MAC, MAC, MAC,
+	MAC, MAC, MAC, MAC, MAC, MAC, MAC, MAC,
 };
 
 int main() {
-    int sock = socket(PF_INET, SOCK_DGRAM, 0);
-    if (sock < 0) err(EX_OSERR, "socket");
+	int sock = socket(PF_INET, SOCK_DGRAM, 0);
+	if (sock < 0) err(EX_OSERR, "socket");
 
-    int on = 1;
-    int error = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
-    if (error) err(EX_OSERR, "setsockopt");
+	int on = 1;
+	int error = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+	if (error) err(EX_OSERR, "setsockopt");
 
-    struct sockaddr_in addr = {
-        .sin_family = AF_INET,
-        .sin_port = 9,
-        .sin_addr.s_addr = INADDR_BROADCAST,
-    };
-    ssize_t size = sendto(
-        sock, payload, sizeof(payload), 0,
-        (struct sockaddr *)&addr, sizeof(addr)
-    );
-    if (size < 0) err(EX_IOERR, "sendto");
+	struct sockaddr_in addr = {
+		.sin_family = AF_INET,
+		.sin_port = 9,
+		.sin_addr.s_addr = INADDR_BROADCAST,
+	};
+	ssize_t size = sendto(
+		sock, payload, sizeof(payload), 0,
+		(struct sockaddr *)&addr, sizeof(addr)
+	);
+	if (size < 0) err(EX_IOERR, "sendto");
 
-    return EX_OK;
+	return EX_OK;
 }
diff --git a/bin/watch.c b/bin/watch.c
index f33c9ee7..3308edc9 100644
--- a/bin/watch.c
+++ b/bin/watch.c
@@ -25,70 +25,70 @@
 #include <unistd.h>
 
 static void watch(int kq, char *path) {
-    int fd = open(path, O_CLOEXEC);
-    if (fd < 0) err(EX_NOINPUT, "%s", path);
+	int fd = open(path, O_CLOEXEC);
+	if (fd < 0) err(EX_NOINPUT, "%s", path);
 
-    struct kevent event = {
-        .ident = fd,
-        .filter = EVFILT_VNODE,
-        .flags = EV_ADD | EV_CLEAR,
-        .fflags = NOTE_WRITE | NOTE_DELETE,
-        .udata = path,
-    };
-    int nevents = kevent(kq, &event, 1, NULL, 0, NULL);
-    if (nevents < 0) err(EX_OSERR, "kevent");
+	struct kevent event = {
+		.ident = fd,
+		.filter = EVFILT_VNODE,
+		.flags = EV_ADD | EV_CLEAR,
+		.fflags = NOTE_WRITE | NOTE_DELETE,
+		.udata = path,
+	};
+	int nevents = kevent(kq, &event, 1, NULL, 0, NULL);
+	if (nevents < 0) err(EX_OSERR, "kevent");
 }
 
 static void exec(char *const argv[]) {
-    pid_t pid = fork();
-    if (pid < 0) err(EX_OSERR, "fork");
+	pid_t pid = fork();
+	if (pid < 0) err(EX_OSERR, "fork");
 
-    if (!pid) {
-        execvp(*argv, argv);
-        err(EX_NOINPUT, "%s", *argv);
-    }
+	if (!pid) {
+		execvp(*argv, argv);
+		err(EX_NOINPUT, "%s", *argv);
+	}
 
-    int status;
-    pid = wait(&status);
-    if (pid < 0) err(EX_OSERR, "wait");
+	int status;
+	pid = wait(&status);
+	if (pid < 0) err(EX_OSERR, "wait");
 
-    if (WIFEXITED(status)) {
-        warnx("exit %d\n", WEXITSTATUS(status));
-    } else if (WIFSIGNALED(status)) {
-        warnx("signal %d\n", WTERMSIG(status));
-    } else {
-        warnx("status %d\n", status);
-    }
+	if (WIFEXITED(status)) {
+		warnx("exit %d\n", WEXITSTATUS(status));
+	} else if (WIFSIGNALED(status)) {
+		warnx("signal %d\n", WTERMSIG(status));
+	} else {
+		warnx("status %d\n", status);
+	}
 }
 
 int main(int argc, char *argv[]) {
-    if (argc < 3) return EX_USAGE;
+	if (argc < 3) return EX_USAGE;
 
-    int kq = kqueue();
-    if (kq < 0) err(EX_OSERR, "kqueue");
+	int kq = kqueue();
+	if (kq < 0) err(EX_OSERR, "kqueue");
 
-    int i;
-    for (i = 1; i < argc - 1; ++i) {
-        if (argv[i][0] == '-') {
-            i++;
-            break;
-        }
-        watch(kq, argv[i]);
-    }
+	int i;
+	for (i = 1; i < argc - 1; ++i) {
+		if (argv[i][0] == '-') {
+			i++;
+			break;
+		}
+		watch(kq, argv[i]);
+	}
 
-    exec(&argv[i]);
+	exec(&argv[i]);
 
-    for (;;) {
-        struct kevent event;
-        int nevents = kevent(kq, NULL, 0, &event, 1, NULL);
-        if (nevents < 0) err(EX_OSERR, "kevent");
+	for (;;) {
+		struct kevent event;
+		int nevents = kevent(kq, NULL, 0, &event, 1, NULL);
+		if (nevents < 0) err(EX_OSERR, "kevent");
 
-        if (event.fflags & NOTE_DELETE) {
-            close(event.ident);
-            sleep(1);
-            watch(kq, event.udata);
-        }
+		if (event.fflags & NOTE_DELETE) {
+			close(event.ident);
+			sleep(1);
+			watch(kq, event.udata);
+		}
 
-        exec(&argv[i]);
-    }
+		exec(&argv[i]);
+	}
 }
diff --git a/bin/xx.c b/bin/xx.c
index 82e00b43..663ee044 100644
--- a/bin/xx.c
+++ b/bin/xx.c
@@ -24,110 +24,110 @@
 #include <unistd.h>
 
 static bool zero(const uint8_t *ptr, size_t size) {
-    for (size_t i = 0; i < size; ++i) {
-        if (ptr[i]) return false;
-    }
-    return true;
+	for (size_t i = 0; i < size; ++i) {
+		if (ptr[i]) return false;
+	}
+	return true;
 }
 
 static struct {
-    size_t cols;
-    size_t group;
-    bool ascii;
-    bool offset;
-    bool skip;
+	size_t cols;
+	size_t group;
+	bool ascii;
+	bool offset;
+	bool skip;
 } options = { 16, 8, true, true, false };
 
 static void dump(FILE *file) {
-    bool skip = false;
+	bool skip = false;
 
-    uint8_t buf[options.cols];
-    size_t offset = 0;
-    for (
-        size_t size;
-        (size = fread(buf, 1, sizeof(buf), file));
-        offset += size
-    ) {
-        if (options.skip) {
-            if (zero(buf, size)) {
-                if (!skip) printf("*\n");
-                skip = true;
-                continue;
-            } else {
-                skip = false;
-            }
-        }
+	uint8_t buf[options.cols];
+	size_t offset = 0;
+	for (
+		size_t size;
+		(size = fread(buf, 1, sizeof(buf), file));
+		offset += size
+	) {
+		if (options.skip) {
+			if (zero(buf, size)) {
+				if (!skip) printf("*\n");
+				skip = true;
+				continue;
+			} else {
+				skip = false;
+			}
+		}
 
-        if (options.offset) {
-            printf("%08zX:  ", offset);
-        }
+		if (options.offset) {
+			printf("%08zX:  ", offset);
+		}
 
-        for (size_t i = 0; i < sizeof(buf); ++i) {
-            if (options.group) {
-                if (i && !(i % options.group)) {
-                    printf(" ");
-                }
-            }
-            if (i < size) {
-                printf("%02hhX ", buf[i]);
-            } else {
-                printf("   ");
-            }
-        }
+		for (size_t i = 0; i < sizeof(buf); ++i) {
+			if (options.group) {
+				if (i && !(i % options.group)) {
+					printf(" ");
+				}
+			}
+			if (i < size) {
+				printf("%02hhX ", buf[i]);
+			} else {
+				printf("   ");
+			}
+		}
 
-        if (options.ascii) {
-            printf(" ");
-            for (size_t i = 0; i < size; ++i) {
-                if (options.group) {
-                    if (i && !(i % options.group)) {
-                        printf(" ");
-                    }
-                }
-                printf("%c", isprint(buf[i]) ? buf[i] : '.');
-            }
-        }
+		if (options.ascii) {
+			printf(" ");
+			for (size_t i = 0; i < size; ++i) {
+				if (options.group) {
+					if (i && !(i % options.group)) {
+						printf(" ");
+					}
+				}
+				printf("%c", isprint(buf[i]) ? buf[i] : '.');
+			}
+		}
 
-        printf("\n");
-    }
+		printf("\n");
+	}
 }
 
 static void undump(FILE *file) {
-    uint8_t byte;
-    int match;
-    while (0 < (match = fscanf(file, " %hhx", &byte))) {
-        printf("%c", byte);
-    }
-    if (!match) errx(EX_DATAERR, "invalid input");
+	uint8_t byte;
+	int match;
+	while (0 < (match = fscanf(file, " %hhx", &byte))) {
+		printf("%c", byte);
+	}
+	if (!match) errx(EX_DATAERR, "invalid input");
 }
 
 int main(int argc, char *argv[]) {
-    bool reverse = false;
-    const char *path = NULL;
+	bool reverse = false;
+	const char *path = NULL;
 
-    int opt;
-    while (0 < (opt = getopt(argc, argv, "ac:g:rsz"))) {
-        switch (opt) {
-            case 'a': options.ascii ^= true; break;
-            case 'c': options.cols = strtoul(optarg, NULL, 0); break;
-            case 'g': options.group = strtoul(optarg, NULL, 0); break;
-            case 'r': reverse = true; break;
-            case 's': options.offset ^= true; break;
-            case 'z': options.skip ^= true; break;
-            default: return EX_USAGE;
-        }
-    }
-    if (argc > optind) path = argv[optind];
-    if (!options.cols) return EX_USAGE;
+	int opt;
+	while (0 < (opt = getopt(argc, argv, "ac:g:rsz"))) {
+		switch (opt) {
+			case 'a': options.ascii ^= true; break;
+			case 'c': options.cols = strtoul(optarg, NULL, 0); break;
+			case 'g': options.group = strtoul(optarg, NULL, 0); break;
+			case 'r': reverse = true; break;
+			case 's': options.offset ^= true; break;
+			case 'z': options.skip ^= true; break;
+			default: return EX_USAGE;
+		}
+	}
+	if (argc > optind) path = argv[optind];
+	if (!options.cols) return EX_USAGE;
 
-    FILE *file = path ? fopen(path, "r") : stdin;
-    if (!file) err(EX_NOINPUT, "%s", path);
+	FILE *file = path ? fopen(path, "r") : stdin;
+	if (!file) err(EX_NOINPUT, "%s", path);
 
-    if (reverse) {
-        undump(file);
-    } else {
-        dump(file);
-    }
-    if (ferror(file)) err(EX_IOERR, "%s", path);
+	if (reverse) {
+		undump(file);
+	} else {
+		dump(file);
+	}
+	if (ferror(file)) err(EX_IOERR, "%s", path);
 
-    return EX_OK;
+	return EX_OK;
 }