fortune: add a small efficient implementation of fortune
authorAlan Cox <alan@linux.intel.com>
Sat, 26 Mar 2016 00:27:19 +0000 (00:27 +0000)
committerAlan Cox <alan@linux.intel.com>
Sat, 26 Mar 2016 00:27:19 +0000 (00:27 +0000)
Applications/games/Makefile
Applications/games/fortune-gen.c [new file with mode: 0644]
Applications/games/fortune.c [new file with mode: 0644]

index 5f2b236..d55ef7f 100644 (file)
@@ -16,12 +16,12 @@ BINMAN = ../../Library/tools/binman
 
 .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 = 
 
diff --git a/Applications/games/fortune-gen.c b/Applications/games/fortune-gen.c
new file mode 100644 (file)
index 0000000..e52f6d4
--- /dev/null
@@ -0,0 +1,69 @@
+#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);
+  }
+}
diff --git a/Applications/games/fortune.c b/Applications/games/fortune.c
new file mode 100644 (file)
index 0000000..a4e1802
--- /dev/null
@@ -0,0 +1,75 @@
+#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