.SUFFIXES: .c .rel
-SRCSNS = qrun.c
+SRCSNS = qrun.c fortune.c
SRCS = adv01.c adv02.c adv03.c adv04.c adv05.c adv06.c adv07.c \
adv08.c adv09.c adv10.c adv11.c adv12.c adv13.c adv14a.c adv14b.c \
myst01.c myst02.c myst03.c myst04.c myst05.c myst06.c myst07.c \
- myst08.c myst09.c myst10.c myst11.c
+ myst08.c myst09.c myst10.c myst11.c fortune-gen.c
SRCSBAD =
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+static char buf[256];
+static int n;
+static off_t off;
+
+static void write_record(void)
+{
+ uint32_t o = off;
+ if (fseek(stdout, 2 + 4 * n, 0) == -1) {
+ perror("fseek");
+ exit(1);
+ }
+ if (fwrite(&o, 4, 1, stdout) != 1) {
+ perror("fwrite1");
+ exit(1);
+ }
+ if (fseek(stdout, off, 0) == -1) {
+ perror("fseek");
+ exit(1);
+ }
+ n++;
+}
+
+int main(int argc, char *argv[])
+{
+ uint16_t count = 0;
+
+ while(fgets(buf, 255, stdin)) {
+ if (strcmp(buf, "%\n") == 0)
+ count++;
+ }
+
+ fprintf(stderr, "%d fortunes.\n", (int)count);
+
+ if (fseek(stdin, 0L, 0) == -1) {
+ perror("fseek");
+ exit(1);
+ }
+
+ off = 2 + 4 * count;
+ write_record();
+
+ while(fgets(buf, 255, stdin)) {
+ if (strcmp(buf, "%\n") == 0) {
+ write_record();
+ } else {
+ if (fwrite(buf, strlen(buf), 1, stdout) != 1) {
+ perror("fwrite2");
+ exit(1);
+ }
+ off += strlen(buf);
+ }
+ }
+ write_record();
+ if (fseek(stdout, 0L, 0) == -1) {
+ perror("fseek");
+ exit(1);
+ }
+ if (fwrite(&count, 2, 1, stdout) != 1) {
+ perror("fwrite3");
+ exit(1);
+ }
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <time.h>
+
+#define COOKIE_JAR "/usr/games/fortune.dat"
+
+struct f_off {
+ uint32_t off;
+ uint32_t next;
+};
+
+
+static uint8_t buf[512];
+static uint16_t cookies;
+static uint16_t cookie;
+
+struct f_off off;
+
+int main(int argc, char *argv[])
+{
+ int fd = open(COOKIE_JAR, O_RDONLY);
+ int n;
+ int r;
+ int len;
+
+ if (fd == -1) {
+ perror(COOKIE_JAR);
+ exit(1);
+ }
+
+ if (read(fd, &cookies, 2) != 2) {
+ perror("read");
+ exit(1);
+ }
+
+ srand(getpid() ^ getuid() ^ (uint16_t)time(NULL));
+ cookie = rand() % cookies;
+
+ if (lseek(fd, 2 + 4 * cookie, SEEK_SET) == -1) {
+ perror("lseek");
+ exit(1);
+ }
+
+ if (read(fd, &off, 8) != 8) {
+ perror("read2");
+ exit(1);
+ }
+
+ if (lseek(fd, off.off, SEEK_SET) == -1) {
+ perror("lseek2");
+ exit(1);
+ }
+
+ len = off.next - off.off;
+ while (len) {
+ n = 512;
+ if (len < 512)
+ n = len;
+ r = read(fd,buf, n);
+ if (r != n) {
+ perror("read3");
+ exit(1);
+ }
+ write(1, buf, r);
+ len -=r;
+ }
+ close(fd);
+ exit(0);
+}
+
+
\ No newline at end of file