diff options
| author | Sam Nystrom <sam@samnystrom.dev> | 2024-10-15 13:29:10 -0400 |
|---|---|---|
| committer | Sam Nystrom <sam@samnystrom.dev> | 2024-10-15 13:29:10 -0400 |
| commit | 2c98bbacc8db3b251e1679f9da84cf1f5ed5726a (patch) | |
| tree | 10d44c9b82d275d66d880ff8ec33992cddda12b5 /bin/infinity.c | |
| parent | c8c79e6c6a5c4bb1e0ba44f309ce5ae612f97e1c (diff) | |
update ~/bin
Diffstat (limited to 'bin/infinity.c')
| -rw-r--r-- | bin/infinity.c | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/bin/infinity.c b/bin/infinity.c new file mode 100644 index 0000000..10a45b0 --- /dev/null +++ b/bin/infinity.c @@ -0,0 +1,216 @@ +/* + infinity.c: the Book of Infinity, adapted for skalibs. + Original work by David Madore: http://www.madore.org/~david/ + Adaptation by Laurent Bercot: http://skarnet.org/ + License: GNU GPL v2, with the special plea that the text of the Book + not be modified. + The original code can be found at: + http://www.madore.org/~david/programs/programs-1.36.html#prog_infinity +*/ + +#include <string.h> +#include <stdlib.h> + +#include <skalibs/bytestr.h> +#include <skalibs/env.h> +#include <skalibs/buffer.h> +#include <skalibs/stralloc.h> +#include <skalibs/sha256.h> + +static char const STRING1[] = "Wake! For the Sun, who scatter'd into flight\n" ; +static char const STRING2[] = "The Stars before him from the Field of Night,\n" ; +static char const STRING3[] = "\240\240\240Drives Night along with them from Heav'n, and strikes\n" ; +static char const STRING4[] = "The Sult\341n's Turret with a Shaft of Light.\n" ; + +#define die() return(111) + + +typedef struct magic_string_state_s magic_string_state_t, *magic_string_state_t_ref ; +struct magic_string_state_s +{ + char vowel ; + char sequent ; +} ; + +#define MAGIC_STRING_STATE_ZERO { 0, 0 } ; + +static char const *magic_string (unsigned char data_byte, magic_string_state_t_ref st, char final) +{ + char const *s ; + char oldsequent = st->sequent ; + if (((data_byte % 7) == 0 ) && st->sequent && !final) + { + st->sequent = 0 ; + return " " ; + } + st->sequent = 1 ; + if (st->vowel) + { + st->vowel = 0 ; + if (data_byte < 40) s = "a" ; + else if (data_byte < 80) s = "e" ; + else if (data_byte < 115) s = "i" ; + else if (data_byte < 145) s = "o" ; + else if (data_byte < 175) s = "u" ; + else if (data_byte < 195) s = "y" ; + else if (data_byte < 200) s = "ai" ; + else if (data_byte < 205) s = "ei" ; + else if (data_byte < 210) s = "oi" ; + else if (data_byte < 215) s = "au" ; + else if (data_byte < 220) s = "eu" ; + else if (data_byte < 225) s = "ou" ; + else if (data_byte < 230) s = "ae" ; + else if (data_byte < 235) s = "oe" ; + else if (data_byte < 240) s = "aa" ; + else if (data_byte < 250) s = "'" ; + else + { + s = "" ; + st->sequent = oldsequent ; + } + } + else + { + st->vowel = 1 ; + if ( data_byte < 12 ) s = "p" ; + else if (data_byte < 24) s = "b" ; + else if (data_byte < 36) s = "t" ; + else if (data_byte < 48) s = "d" ; + else if (data_byte < 60) s = "k" ; + else if (data_byte < 72) s = "g" ; + else if (data_byte < 84) s = "s" ; + else if (data_byte < 96) s = "z" ; + else if (data_byte < 108) s = "sh" ; + else if (data_byte < 120) s = "zh" ; + else if (data_byte < 132) s = "f" ; + else if (data_byte < 144) s = "v" ; + else if (data_byte < 156) s = "ch" ; + else if (data_byte < 168) s = "j" ; + else if (data_byte < 174) s = "ks" ; + else if (data_byte < 180) s = "x" ; + else if (data_byte < 192) { s = "h" ; st->vowel = (data_byte < 190) ; } + else if (data_byte < 204) { s = "n" ; st->vowel = (data_byte < 198) ; } + else if (data_byte < 216) { s = "r" ; st->vowel = (data_byte < 210) ; } + else if (data_byte < 222) s = "st" ; + else if (data_byte < 228) s = "zd" ; + else if (data_byte < 234) s = "ts" ; + else if (data_byte < 240) s = "dz" ; + else if (data_byte < 242) s = "pn" ; + else if (data_byte < 244) s = "bn" ; + else if (data_byte < 247) s = "sht" ; + else if (data_byte < 250) s = "zhd" ; + else + { + s = "" ; + st->sequent = oldsequent ; + } + } + return s ; +} + +static int page_make_name (stralloc *sa, char const *seed, unsigned int seedlen) +{ + SHA256Schedule context = SHA256_INIT() ; + magic_string_state_t st = MAGIC_STRING_STATE_ZERO ; + char data[64] ; + + sha256_update(&context, STRING1, sizeof(STRING1) - 1) ; + sha256_update(&context, seed, seedlen) ; + sha256_update(&context, STRING2, sizeof(STRING2) - 1) ; + sha256_update(&context, seed, seedlen) ; + sha256_final(&context, data) ; + sha256_init(&context) ; + sha256_update(&context, STRING3, sizeof(STRING3) - 1) ; + sha256_update(&context, seed, seedlen) ; + sha256_update(&context, STRING4, sizeof(STRING4) - 1) ; + sha256_update(&context, seed, seedlen) ; + sha256_final(&context, data + 32) ; + + { + unsigned int i = 0 ; + for (; i < 64 ; i++) + if (!stralloc_cats(sa, magic_string(data[i], &st, i == 63))) + return 0 ; + } + return 1 ; +} + +int main (void) +{ + stralloc url_start = STRALLOC_ZERO ; + stralloc page_name = STRALLOC_ZERO ; + stralloc new_path = STRALLOC_ZERO ; + stralloc new_page_name = STRALLOC_ZERO ; + char const *script_name = getenv("SCRIPT_NAME") ; + unsigned int new_path_start ; + unsigned int i = 0 ; + + if (!script_name) script_name = "infinity.cgi" ; + + { + char const *x = getenv("PATH_INFO") ; + if (!x || !*x) x = "/" ; + if (!stralloc_cats(&new_path, x)) die() ; + x = getenv("SERVER_NAME") ; + if (x) + { + if (!stralloc_cats(&url_start, "//")) die() ; + if (!stralloc_cats(&url_start, x)) die() ; + x = getenv("SERVER_PORT") ; + if (x && strcmp(x, "80")) + { + if (!stralloc_catb(&url_start, ":", 1)) die() ; + if (!stralloc_cats(&url_start, x)) die() ; + } + } + } + + if (!page_make_name(&page_name, new_path.s, new_path.len)) die() ; + buffer_puts(buffer_1, "Last-Modified: Wed, 24 May 2017 12:20:00 GMT\r\nContent-Type: text/html\r\n\r\n<html>\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\r\n<meta http-equiv=\"Content-Language\" content=\"en\" />\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n<title>") ; + buffer_put(buffer_1, page_name.s, page_name.len) ; + buffer_puts(buffer_1, "</title>\r\n<meta name=\"robots\" content=\"noindex, nofollow\" />\r\n<meta name=\"description\" content=\"One Page from the Book of Infinity\" />\r\n<meta name=\"keywords\" content=\"infinite web space ") ; + buffer_put(buffer_1, page_name.s, page_name.len) ; + buffer_puts(buffer_1, "\" />\r\n</head>\r\n<body>\r\n<h1>") ; + buffer_put(buffer_1, page_name.s, page_name.len) ; + buffer_puts(buffer_1, "</h1>\r\n<p> You are in a maze of twisty little web pages, all alike. </p>\r\n<p> From here you can get to the following places: </p>\r\n<ul>\r\n") ; + + new_path_start = new_path.len ; + for (; i < 14 ; i++) + { + new_path.len = new_path_start ; + buffer_puts(buffer_1, "<li>") ; + switch (i) + { + case 0 : + case 13 : + { + while (new_path.len > 1) if (new_path.s[--new_path.len - 1] == '/') break ; + if (!i) buffer_puts(buffer_1, "Back to ") ; + else + { + if (!stralloc_catb(&new_path, page_name.s, byte_chr(page_name.s, page_name.len, ' '))) die() ; + if (!stralloc_catb(&new_path, "/", 1)) die() ; + } + break ; + } + default: + { + char const *const zodiac[12] = { "aries", "taurus", "gemini", "cancer", "leo", "virgo", "libra", "scorpius", "sagittarius", "capricornus", "aquarius", "pisces" } ; + if (!stralloc_cats(&new_path, zodiac[i-1])) die() ; + if (!stralloc_catb(&new_path, "/", 1)) die() ; + } + } + buffer_puts(buffer_1, "<a href=\"") ; + if (url_start.s) buffer_put(buffer_1, url_start.s, url_start.len) ; + buffer_puts(buffer_1, script_name) ; + buffer_put(buffer_1, new_path.s, new_path.len) ; + buffer_puts(buffer_1, "\">") ; + new_page_name.len = 0 ; + if (!page_make_name(&new_page_name, new_path.s, new_path.len)) die() ; + buffer_put(buffer_1, new_page_name.s, new_page_name.len) ; + buffer_puts(buffer_1, "</a></li>\r\n") ; + } + buffer_putsflush(buffer_1, "</ul>\r\n</body>\r\n</html>\r\n") ; + return 0 ; +} + |
