diff --git a/.build.yml b/.build.yml new file mode 100644 index 0000000..173e7b6 --- /dev/null +++ b/.build.yml @@ -0,0 +1,12 @@ +image: alpine/edge +oauth: pages.sr.ht/PAGES:RW +packages: +- hut +- python3 +tasks: +- package: | + make -C src/homepage generate + tar cvz --exclude .git -C src/homepage . >site.tar.gz + ls -l site.tar.gz +- upload: | + hut pages publish -d trinity.moe site.tar.gz diff --git a/cat/Makefile b/cat/Makefile new file mode 100644 index 0000000..22217fe --- /dev/null +++ b/cat/Makefile @@ -0,0 +1,7 @@ +cat: cat.c + $(CC) -g -o cat cat.c + +clean: + rm -f cat.c + +.PHONY: clean diff --git a/cat/cat.c b/cat/cat.c index 4084dd8..b1d7147 100644 --- a/cat/cat.c +++ b/cat/cat.c @@ -1,104 +1,112 @@ -#include -#include -#include -#include +#include /* errno, EBADF, EFAULT, EINVAL, ELOOP, ENAMETOOLONG, + * ENOENT, ENOMEM, ENOTDIR, EOVERFLOW */ +#include /* fprintf(3), getc(3), putc(3), setvbuf(3), stderr, stdin, + * stdout */ +#include /* EX_DATAERR, EX_NOINPUT, EX_OK, EX_OSERR, + * EX_UNAVAILABLE, EX_USAGE */ +#include /* getopt(3) */ +#include /* stat(2), struct stat, S_ISDIR */ -/* NetBSD's default according to an strace */ -#define BUFFER 4096 -static unsigned char buf[BUFFER]; - -static char *program_name = "cat"; +/* NetBSD's default size according to an strace */ +static unsigned char buf[4096]; +static char *default_argv[] = { + "cat", + "-", + (char *)NULL +}; +static char *stdout_name = "/dev/stdin"; int main(int argc, char *argv[]){ - char *argv0; - int argv0_s; - extern int errno; - char *f; - int b; /* how many meaningful bytes are in the buffer */ + int arguing; int c; - int fd; - int multiple_files; + extern int errno; + extern int opterr; + extern int optind; + struct stat fi; /* info */ + char *fn; /* name */ + FILE *fo; /* object */ - if(argv[0] == NULL) - goto dumb; - - argv0 = argv[0]; - for(argv0_s = 0; argv0_s != '\0'; ++argv0_s); - - while((c = getopt(argc, argv, "hu")) != -1) - switch(c){ - case 'u': - /* cat(1p) says the following: - * "Write bytes from the input file to the standard - * output without delay as each is read." - * Then in Application Usage: - * "It is unspecified whether standard output is or is - * not buffered in the default case." - * POSIX defines "buffering" to be a not-strictly - * -necessary delay in processing input, so there still - * needs to be a place in memory to put data, which for - * the purposes of this implementation is buf[]. - * - * Using the standard library would make it more - * difficult to manage this flow manually. */ - break; - case 'h': default: usage: - write(2, "Usage: ", 7); - write(2, argv[0], argv0_s); - write(2, "(-hu) (file...)\n", 16); - return EX_USAGE; - } - - argc -= optind; - argv += optind - 1; - multiple_files = argc > 1; - - do{ - ++argv; - if(argc == 0) /* `cat` */ -dumb: fd = 1; - else if((fd = open(*argv, O_RDONLY)) == -1){ -ferr: /* `cat bad_file` */ - - /* `cat: file: ` */ - write(2, argv0, argv0_s); - write(2, ": ", 2); - for(i = 0; argv[0][i] != '\0'; ++i); - write(2, *argv, i); - write(2, ": ", 2); - - switch(errno){ - case EISDIR: - write(2, "Is directory.\n", 14); - return EX_NOINPUT; - case EACCES: case EFAULT: case EPERM: - write(2, "Unable to open file.\n", 21); - return EX_NOINPUT; - case ENAMETOOLONG: case ENFILE: case EBADF: - write(2, "Operating system error.\n", 24); - return EX_OSERR; - case EMFILE: - write(2, "Internal error.\n", 16); - return EX_SOFTWARE; - case ENOENT: case ENOTDIR: case ENXIO: - write(2, "File does not exist.\n", 21); - return EX_NOINPUT; - default: - write(2, "Unknown error.", 14); - return 1; + setvbuf(stdout, buf, _IOFBF, (sizeof buf)/(sizeof *buf)); + if(argc < 2){ + argc = 2; + if(argc > 0) + default_argv[0] = argv[0]; + argv = default_argv; + } + arguing = 1; + opterr = 0; + while(optind < argc){ + if(arguing && (c = getopt(argc, argv, "hu")) != -1) + switch(c){ + case 'u': + setvbuf(stdout, NULL, _IONBF, 0); + continue; + case '-': + arguing = 0; + continue; + case 'h': default: usage: + fprintf(stderr, "Usage: %s (-h) (file...)\n", + argv[0]); + return EX_USAGE; + } + if(arguing && *argv[optind] == '-'){ /* "--" */ + arguing = 0; + continue; + } + if(*argv[optind] == '-' && argv[optind][1] == '\0'){ /* "-" */ + fn = stdin_name; + fo = stdin; + }else{ + fn = argv[optind]; + if(stat(fn, &fi) == -1){ + switch(errno){ + case EFAULT: case ENOENT: case ENOTDIR: + fprintf(stderr, + "%s: %s: Unable to open file." + " Does it exist?\n", + argv[0], fn); + return EX_NOINPUT; + case EBADF: case EINVAL: case ENOMEM: + case EOVERFLOW: + fprintf(stderr, + "%s: %s: System error" + " (errno=%d),\n", + argv[0], fn, errno); + return EX_OSERR; + case ELOOP: case ENAMETOOLONG: + fprintf(stderr, + "%s: %s: Unable to open file.", + argv[0], fn); + return EX_DATAERR; + } + } + if(S_ISDIR(fi.st_mode)){ + fprintf(stderr, "%s: %s: Is a directory.\n", + argv[0], fn); + return EX_DATAERR; + } + if((fo = fopen(fn, "r")) == NULL){ + fprintf(stderr, + "%s: %s: Error opening file.\n", + argv[0], fn); + return EX_OSERR; } - }else if(multiple_files){ - /* `cat good_file good_file ...` */ - } - for(b = 0; b == -1;){ - - } + while((c = getc(fo)) != EOF) + if(putc(c, stdout) == EOF){ + fprintf(stderr, + "%s: Exiting due to error writing to" + " output...\n", + argv[0]); + fclose(fo); + return EX_UNAVAILABLE; + } - if(fd < 0 && fd > 2) - close(fd); - }while(--argc > 0); + if(fo != stdin) + fclose(fo); + ++optind; + } return EX_OK; } diff --git a/com/com b/com/com new file mode 100644 index 0000000..43c5d62 --- /dev/null +++ b/com/com @@ -0,0 +1,84 @@ +#!/bin/sh + +set -e + +# http://www.iq0.com/duffgram/com.html implementation +# (consulted source to see what -n did) + +arv0="$0"; shell='sh -c' + +usage(){ + printf 'Usage: %s (-n) (file...)\n' "$argv0" >&2 + exit 64 # sysexits(3) EX_USAGE +} + +for arg in "$@" +do + printf '%s\n' "$arg" \ + | grep '^-' >/dev/null 2>&1 \ + || break + shift + printf '%s\n' "$arg" \ + | grep 'n' >/dev/null 2>&1 \ + && shell=echo \ + || true + printf '%s\n' "$arg" \ + | grep '[^-n]' >/dev/null 2>&1 \ + && usage \ + || true + printf '%s\n' "$arg" \ + | grep -- '-.*-' >/dev/null 2>&1 \ + && break \ + || true +done + +test -n "$1" \ + || set -- "$(cat .comfile 2>/dev/null)" \ + && test -n "$1" \ + || usage + +>.comfile + +awk -v argv0="$argv0" -v shell="$shell" ' +# https://www.gnu.org/software/gawk/manual/html_node/Filetrans-Function.html +FILENAME != current_file { + processed = 0; + if(current_file != 0){ + print current_file >>".comfile"; + if(cmd == ""){ + # https://www.gnu.org/software/gawk/manual/html_node/ + # Special-FD.html + printf("%s: no command\n", ARGV[2]) >"/dev/stderr"; + exit 65 # sysexits(3) EX_DATAERR + }else{ + print cmd | shell; + cmd = ""; + } + } + current_file = FILENAME; +} +cmd == "" && /\/\*%/ { + sub(/.*\/\*%[:space:]*/, ""); + stem = FILENAME; + sub(/\.[^.]*$/, "", stem); + for(i = 0; i < length($0) - 1; ++i) + cmd = cmd ((substr($0, i, 2) == "##" || substr($0, i, 2) == "%%") \ + ? substr($0, i++, 1) \ + : (substr($0, i, 1) == "%") \ + ? FILENAME \ + : (substr($0, i, 1) == "#") \ + ? stem \ + : substr($0, i, 1)) \ + ; + cmd = cmd substr($0, i, 2); +} +END { + print current_file >>".comfile"; + if(cmd != "") + print cmd | shell; + if(processed == 0){ + printf("%s: no command\n", argv0) > "/dev/stderr"; + exit 65; # sysexits(3) EX_DATAERR + } +} + ' diff --git a/dotfiles/README.md b/dotfiles/README.md new file mode 100644 index 0000000..f31fef8 --- /dev/null +++ b/dotfiles/README.md @@ -0,0 +1,5 @@ +# trinity/dotfiles +Pretty config stuff. + +![This is a screenshot of my desktop.](https://web.archive.org/web/20200926155417if_/https://i.redd.it/jwhsmokcfcp51.png) +For this configuration, [posted on r/unixporn on 2020-09-25](https://www.reddit.com/r/unixporn/comments/izpvwp/i3gaps_basic_but_it_works/), refer to the [state of the repository around 2020-09-26](https://git.sr.ht/~trinity/src/tree/86abade1455cfda2f06aff6bc66c6493453512ef/item/dotfiles-old/README.md) or so. diff --git a/homepage/.gitignore b/homepage/.gitignore new file mode 100644 index 0000000..9daeafb --- /dev/null +++ b/homepage/.gitignore @@ -0,0 +1 @@ +test diff --git a/homepage/CNAME b/homepage/CNAME new file mode 100644 index 0000000..6b04142 --- /dev/null +++ b/homepage/CNAME @@ -0,0 +1 @@ +www.trinity.moe diff --git a/homepage/Makefile b/homepage/Makefile new file mode 100644 index 0000000..e88fe7e --- /dev/null +++ b/homepage/Makefile @@ -0,0 +1,26 @@ +.POSIX: + +FILES = CNAME css homepage img Makefile README +RM = rm -f + +test: + mkdir test + cp -R $(FILES) test/ + make -C test generate + +clean_test: + rm -r test + +retest: + make clean_test + make test + +generate: clean.sh + +clean.sh: + sh homepage + +clean: clean.sh + sh clean.sh + +.PHONY: generate clean test clean_test retest diff --git a/homepage/README b/homepage/README new file mode 100644 index 0000000..108e391 --- /dev/null +++ b/homepage/README @@ -0,0 +1,3 @@ + /\ |/||\|| _\|||\ |||||/||\|\\// |\ /|/ \||\| + / \ || || /|||\\|||| || || ||\/|| | ||> +/____\ _||__||\\||||\\|||__||_ _||_()||\/||\_/||/| diff --git a/homepage/css/2023.css b/homepage/css/2023.css new file mode 100644 index 0000000..c795fa6 --- /dev/null +++ b/homepage/css/2023.css @@ -0,0 +1,8 @@ +a{ + color: #FF0000; +} + +body{ + background-color: #000000; + color: #FFDBDB; +} diff --git a/homepage/css/4chanog.css b/homepage/css/4chanog.css new file mode 100644 index 0000000..55cfcf3 --- /dev/null +++ b/homepage/css/4chanog.css @@ -0,0 +1,11 @@ +/* is this really an OG 4chan theme? + * screenshots from nov 2003 look like + * this but idk... */ + +body: + background-color: #000000; + color: #FFFFFF; + +h1, h2, h3, .sidebar { + color: #B77F75 +} diff --git a/homepage/css/Makefile b/homepage/css/Makefile new file mode 100644 index 0000000..e870928 --- /dev/null +++ b/homepage/css/Makefile @@ -0,0 +1,2 @@ +index.html: index.m4 ../head.m4 + m4 index.m4 >index.html diff --git a/homepage/css/blank.css b/homepage/css/blank.css new file mode 100644 index 0000000..e69de29 diff --git a/homepage/css/calebmode.css b/homepage/css/calebmode.css new file mode 100644 index 0000000..65946a0 --- /dev/null +++ b/homepage/css/calebmode.css @@ -0,0 +1,10 @@ +body { + background-color: #000000; + color: #FFFFFF; + font-weight: bold; +} + +a { + color: #FFFFFF; + font-weight: normal; +} \ No newline at end of file diff --git a/homepage/css/discord.css b/homepage/css/discord.css new file mode 100644 index 0000000..dd17d13 --- /dev/null +++ b/homepage/css/discord.css @@ -0,0 +1,9 @@ +/* found on https://colorswall.com/palette/181/. seems accurate */ +body { + background-color: #23272A; + color: #99AAB5; +} + +a { + color: #7289DA; +} diff --git a/homepage/css/givemerights.css b/homepage/css/givemerights.css new file mode 100644 index 0000000..92aaf5b --- /dev/null +++ b/homepage/css/givemerights.css @@ -0,0 +1,3 @@ +body { + background-image: linear-gradient(#bcdeff, #efdbfc, #bcdeff); +} \ No newline at end of file diff --git a/homepage/css/index.m4 b/homepage/css/index.m4 new file mode 100644 index 0000000..f45332c --- /dev/null +++ b/homepage/css/index.m4 @@ -0,0 +1,57 @@ +define(`_PAGE', `css/')dnl +define(`_TITLE', `trinity.moe/css/')dnl +define(`_DESCRIPTION', `trinity.moe css')dnl +define(`_STYLE', `') +define(`csspage', ` + +
')dnl + + +include(`../head.m4')dnl + +

~ Return to the rest of the site

+ + + +

Site CSS selector

+
+

+This page may be hostile to screen readers and other web assistive technologies because it's essentially a raw list of filenames with paths and extensions. +If you'd like a friendlier view, it's possible the webview directory list for the repository service I use could be a better way to browse this site's more hidden stylesheets. +Otherwise, pull requests are open for the repository, and my e-mail is on the site index if you don't have an account on the service being used. +

+

+This page uses JavaScript. +The URLs to the sheets are provided in their entry. +If you do not wish to use JavaScript for this page, you may set a custom theme for this website in your browser settings using the sheet file. +

+ +csspage(`blank') +csspage(`4chanog') +csspage(`calebmode') +csspage(`discord') +csspage(`givemerights') +csspage(`instantfloppy') +csspage(`instantfloppy-redandwhite') +csspage(`k') + + +
+csspage(`nevertoodark') +csspage(`pink') +csspage(`windowsclassic') +csspage(`yarahmode') + +

side-effects

+ + + + + + diff --git a/homepage/css/instantfloppy-redandwhite.css b/homepage/css/instantfloppy-redandwhite.css new file mode 100644 index 0000000..8b78497 --- /dev/null +++ b/homepage/css/instantfloppy-redandwhite.css @@ -0,0 +1,12 @@ +/** add stylesheet.css, then add this sheet **/ + +body { + /** cloning CNN, cheaply. **/ + background-color: #DDDDDD; + color: #111111; +} + +a { + color: #EE0000; + text-decoration: underline; +} \ No newline at end of file diff --git a/homepage/css/instantfloppy.css b/homepage/css/instantfloppy.css new file mode 100644 index 0000000..fe623af --- /dev/null +++ b/homepage/css/instantfloppy.css @@ -0,0 +1,17 @@ +body { + background-color: #000000; + color: #00FF00; + font-size: 100%; +} +a { + color: #FF4444; + text-decoration: none; + font-weight: bold; +} + +h1, h2, h3, h4, h5, h6, h7 { font-weight: normal; } + +h1 { font-size: 1.25em; /* 20px */ } +h2 { font-size: 1.125em; /* 18px */ } +h3 { font-size: 1em; /* 16px */ } +h7 { font-size: 0.625em; /* 10px */ } diff --git a/homepage/css/k.css b/homepage/css/k.css new file mode 100644 index 0000000..ec288be --- /dev/null +++ b/homepage/css/k.css @@ -0,0 +1,10 @@ +body { + background-color: #000000; + color: #FFDBDB; + font-weight: bold; +} + +a { + color: #FFDBDB; + font-weight: normal; +} diff --git a/homepage/css/lists.css b/homepage/css/lists.css new file mode 100644 index 0000000..71aec0d --- /dev/null +++ b/homepage/css/lists.css @@ -0,0 +1,8 @@ +/* stolen a bit from http://www.lord-enki.net/vt240.css */ +tr, td, ul, ol { + outline: 1px solid; + padding-top: 5px; + padding-bottom: 5px; + margin-top: 5px; + margin-bottom: 10px; +} \ No newline at end of file diff --git a/homepage/css/mcupdate.css b/homepage/css/mcupdate.css new file mode 100644 index 0000000..d5fb74f --- /dev/null +++ b/homepage/css/mcupdate.css @@ -0,0 +1,39 @@ +/* SITE LICENSE DOES NOT APPLY TO THIS FILE. +This file is UNLICENSED. Its copyright belongs to its original creators (NOT +Deven Blake), they are the only ones who can license this file. + + mcupdate.css + site theme stolen from mcupdate.tumblr.com -- + + Photo Minimal + A Tumblr theme by William Rainbird - http://william.rainbird.me + + Tweaked for the Minecraft Launcher by Mojang + +*/ + +body { + font-family: sans-serif; + background-color: #222222; + background-image: url('https://static.tumblr.com/qfn3sex/ezom7y7iq/bg_main.png'); + color: #e0d0d0; +} + +a { color: #aaaaff; } + +hr { + border: 0; + color: #111111; + background-color: #111111; + height: 2px; +} + +h3 { + color: #ffffff; + font-size: 16px; +} + +img { + border:0; + margin:0; +} diff --git a/homepage/css/nevertoodark.css b/homepage/css/nevertoodark.css new file mode 100644 index 0000000..e387188 --- /dev/null +++ b/homepage/css/nevertoodark.css @@ -0,0 +1,8 @@ +body { + background-color: #000000; + color: #222222; +} + +a { + color: #333333; +} diff --git a/homepage/css/pink.css b/homepage/css/pink.css new file mode 100644 index 0000000..348dfb3 --- /dev/null +++ b/homepage/css/pink.css @@ -0,0 +1,3 @@ +body { + background-color: #FFDBDB; +} diff --git a/homepage/css/windowsclassic.css b/homepage/css/windowsclassic.css new file mode 100644 index 0000000..73f3860 --- /dev/null +++ b/homepage/css/windowsclassic.css @@ -0,0 +1,10 @@ +body { + background-color: #3B6EA5; + color: #FFFFFF; + font-weight: bold; +} + +a { + color: #FFFFFF; + font-weight: normal; +} \ No newline at end of file diff --git a/homepage/css/yarahmode.css b/homepage/css/yarahmode.css new file mode 100644 index 0000000..428e1cf --- /dev/null +++ b/homepage/css/yarahmode.css @@ -0,0 +1,6 @@ +body { + background-color: #66AA88; +} +a { + color: #7E4662; +} diff --git a/homepage/homepage b/homepage/homepage new file mode 100755 index 0000000..5f7fcf5 --- /dev/null +++ b/homepage/homepage @@ -0,0 +1,11320 @@ +#!/bin/sh +#llllmmmm11234567892123456789312345678941234567895123456789612345678971234567890 +set -ex +<"$0" python3 -c ' +import os, sys +class File: + attributes = []; content = ""; substitutions = dict() + figurative = True; stub = True + def addattribute(self, *args): + for a in args: # sloppy but works + if a == "stub": self.stub = True + elif a == "verbatim": self.stub = False + elif a == "figuratively": self.figurative = True + elif a == "literally": self.figurative = False + def __init__(self, **kwargs): + for key in kwargs: + if key == "attributes": self.addattribute(*kwargs[key]) + else: setattr(self, key, kwargs[key]) +files = dict() +for part in reversed(sys.stdin.read().split("\n\n\n")): + name = "." + part.split("\n")[0] + if "\t" in "." + name: + attributes = name.split("\t")[1].split(",") + name = name.split("\t")[0] + else: attributes = [] + if len(name) <= 1 or name[1] != "/" or "ignore" in attributes: + continue + content = part.split("\n\n")[0].split("\n") + substitutions = dict() + if(len(content) > 1): + for s in content[1:]: + s = s.split("\t") + if len(s) == 2: substitutions[s[0]] = s[1] + mode = "replace" + for attribute in attributes: + if attribute in ["append", "replace"]: + mode = attribute + attributes = list(set(attributes) ^ {"append", "replace"}) + content = part[len("\n".join(content))+2:] + file = File(attributes = attributes, content = content + "\n", + substitutions = substitutions) + if mode == "append": + if not(name in files): + sys.stderr.write(sys.argv[0] + ": " + name + ": " + + "appending to nothing\n") + else: + file.content = files[name].content + file.content + files[name] = file +for name in files: + if files[name].stub: + p = ""; s = ""; d = name + while True: + d = os.path.dirname(d) + if (p == "" + and os.path.join(d, "Prefix") + in files.keys()): + p = files[os.path.join(d, "Prefix")].content + if (s == "" + and os.path.join(d, "Suffix") + in files.keys()): + s = files[os.path.join(d, "Suffix")].content + if d == "." or (not(p == "") and not(s == "")): + break + files[name].content = p + files[name].content + s + if files[name].figurative: + content = files[name].content + for s in files[name].substitutions: + instances = [] + i = 0 + while True: + instance = content.find(s, i) + if instance == -1: break + instances += [instance] + i = instance + len(s) + if len(instances) == 0: continue + for i in reversed(instances): + content = (content[:i] + + files[name].substitutions[s] + + content[i+len(s):]) + files[name].content = content + # TODO error checking + if not(os.path.isdir(os.path.dirname(name))): + os.makedirs(os.path.dirname(name)) + with open(name, "w") as fd: fd.write(files[name].content) +d = ""; bucket = "#!/bin/sh\n" +for name in files: + d = name + while True: + if os.path.dirname(d) == ".": + mop = ("rm " + + "-r " * os.path.isdir(d) + + name # yeah this sucks + + "\n" + ) + if not(mop in bucket): bucket += mop + break + else: + d = os.path.dirname(d) +if len(bucket.split("\n")) > 2: + with open("./cleanup.sh", "w") as fd: + fd.write(bucket) +' +test -x homepage.local \ + && exec ./homepage.local \ + || test -e homepage.local \ + && exec sh ./homepage.local \ + || exit 0 + + +/LICENSE verbatim + +Other than noted exceptions, this is free and unencumbered data +released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this data, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this data dedicate any and all copyright interest in the data to the +public domain. We make this dedication for the benefit of the public at +large and to the detriment of our heirs and successors. We intend this +dedication to be an overt act of relinquishment in perpetuity of all +present and future rights to this data under copyright law. + +THE DATA IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE DATA OR THE USE OR +OTHER DEALINGS IN THE DATA. + +For more information, please refer to + + +/homepage.html +$!TITLE "homepage" documentation +$!DESCRIPTION one file, one website + +

"homepage" documentation

+

the forest

+

+homepage is a single-file static site generator written in UNIX sh(1) shell +script, the goal being to contain a website with heirarchical page +organization within a single file that can be run to extract it out to the +filesystem, almost like a self-extracting UNIX tape archive that documents its +own layout in a UTF-8 script closer to English. +

+

trees

+

files

+

+To add a file to your homepage, append three newlines ('\n', or the +Enter/Return key on your keyboard) to the end of the homepage file, followed +by the path of the file to add. A homepage file path starts with a slash ('/') +and is followed by the path to the file relative to the prefix directory (the +directory containing homepage). A file path that starts with a hash ('#') is +discarded. For all non-slash- non-hash- prefixed file paths, the behavior of +homepage is undefined. +

+

file attributes

+

+On the same line as the file path, if, after the path, a tab ('\t') is +present, the substring following the first tab in the line and spanning to +and excluding the next tab or newline describes the attributes of the file as +it is exported to the file system. These file attributes are delimited by +commas (',') and there's no limit to the amount of attributes a file can +have, though in the event of conflicting attributes the later attribute +"wins" the conflict. +

+ + + + + + + + + + + + +
attribute default?action
"figuratively"yesIndicates the file should be subject to macro expansion.
"ignore" no Ignore the current entry.
"literally" noOpposite of "figuratively".
"stub" yesIndicates the file should be exported to the filesystem with the + appropriate Prefix and Suffix files prepended or appended.
"verbatim" no Opposite of "stub".
+ + +/praise/index.html append,literally + +
  • [] Doctor Eli Selig !!JQHA6kqyl91: >Maid Phone user / >mfw / ["Heart hands.jpg"]
  • + + +/praise/Prefix verbatim + + + + + + + + + + + + + + + +trinity's "shitlist" + + +

    ~ Return to the rest of the site

    + + + +

    trinity's "shitlist"

    +
    +

    +This is my "shitlist", or list of things you shouldn't like (- I like some of these things but probably shouldn't). +This is a list of public figures and brands, nothing personal. +If you're on this list you're probably famous enough to not have to care. +

    +

    (Partial) Table of Contents

    + +

    Disclaimers

      +

      +I would like to mention that the omission of a brand or figure on this list does not make them good. +For instance, Donald Trump is not yet well-covered on this list because of the sheer quantity of terrible things he's done. +"Good brands", in my experience, are just brands about which less is known. +I am also a human and therefore biased. +

      +

      +Any company that currently employs me will not appear on this list, and if I am employed by a company, they'll be removed. +

      +

      +You're welcome to suggest additions to this list via a pull request on this website's git repository, +information about this can be found on the site index. +Or just email me. +

      +

      +There are parts of this list that contain commentary of my own (rather than contextualization), those parts are gray and have the CSS class "opinion" - in uBlock Origin the rule to remove these bits is ##.opinion. +

      +

      +Finally, I'm human and I make mistakes curating this list. +Removed entries listed with explanations as to why they were removed. +

      +

      +I do this to jog my own memory, not to make money. +Please redirect any donations to The Internet Archive. +Without their Wayback Machine this list would be impossible to compile. +

      +
    + +

    Prior art

    (other shitlists and shitlist-adjacent content)

    + +

    Brands

    + + +

    Police Departments

    + + +

    Public Figures

    + + +

    Removed entries

    + +

    Acknowledgements

      +
    • The other shitlists in the Prior Art section.
    • +
    • My friend Yarah, for contributing a couple articles.
    • +
    • My friend Jacob Morin, for calling to my attention an error in my curation.
    • +
    • Wikipedia. On its own it's imperfect but I steal links from the citation sections.
    • +
    + +
  • Template
  • + + + diff --git a/liminality/Makefile b/liminality/Makefile new file mode 100644 index 0000000..ac72864 --- /dev/null +++ b/liminality/Makefile @@ -0,0 +1,2 @@ +liminality: libinality.h liminality.c + $(CC) -g -o liminality liminality.c diff --git a/liminality/libinality.h b/liminality/libinality.h new file mode 100644 index 0000000..bae344b --- /dev/null +++ b/liminality/libinality.h @@ -0,0 +1,6 @@ +#ifndef _LIMINALITY_H +# define _LIMINALITY_H +static char *Liminality_prefix = "FROM "; +static char *Liminality_infix = "\nBODY "; +static char *Liminality_suffix = "\n"; +#endif /* ifndef _LIMINALITY_H */ diff --git a/liminality/liminal b/liminality/liminal new file mode 100755 index 0000000..eca85dc --- /dev/null +++ b/liminality/liminal @@ -0,0 +1,7 @@ +#!/bin/sh + +test -z "$2" || test -n "$3" \ + && printf "Usage: %s [server] [port]\n" "$0" >&2 \ + && exit 64 # sysexits(3) EX_USAGE + +liminality | nc "$1" "$2" diff --git a/liminality/liminality.c b/liminality/liminality.c new file mode 100644 index 0000000..90153ab --- /dev/null +++ b/liminality/liminality.c @@ -0,0 +1,32 @@ +#include +#include +#include "libinality.h" + +char *signoff = ""; +char *user = "user"; + +int main(int argc, char *argv[]){ + int c; + char exiting; + char *s; + + if((s = getenv("USER")) != NULL) + user = s; + + do{ + fputs(Liminality_prefix, stdout); + fputs(user, stdout); + fputs(Liminality_infix, stdout); + while((c = getc(stdin)) != '\n') + if(c != EOF) + putc(c, stdout); + else{ + exiting = 1; + fputs(signoff, stdout); + break; + } + fputs(Liminality_suffix, stdout); + }while(!exiting); + + return 0; +} diff --git a/lsd/LICENSE b/lsd/LICENSE new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/lsd/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/lsd/README.md b/lsd/README.md new file mode 100644 index 0000000..0d1fe9f --- /dev/null +++ b/lsd/README.md @@ -0,0 +1,5 @@ +# trilsd + +*trinity's linux software distribution* + +See `/dist/documentation/trilsd.7'. diff --git a/lsd/dist/Makefile b/lsd/dist/Makefile new file mode 100644 index 0000000..368d2b6 --- /dev/null +++ b/lsd/dist/Makefile @@ -0,0 +1,112 @@ +include mk.conf + +all: fhs learn + +destroy: + cd "$(PREFIX)" + git clean -f -d + +fhs: + # Filesystem Hierarchy Standard 3.0, 2015 + # https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.pdf + + # section 3.2 + mkdir -p "$(PREFIX)/bin" + mkdir -p "$(PREFIX)/boot" + mkdir -p "$(PREFIX)/dev" + mkdir -p "$(PREFIX)/etc" + mkdir -p "$(PREFIX)/lib" + mkdir -p "$(PREFIX)/media" + mkdir -p "$(PREFIX)/mnt" + mkdir -p "$(PREFIX)/opt" + mkdir -p "$(PREFIX)/run" + mkdir -p "$(PREFIX)/sbin" + mkdir -p "$(PREFIX)/srv" + mkdir -p "$(PREFIX)/tmp" + mkdir -p "$(PREFIX)/usr" + mkdir -p "$(PREFIX)/var" + + # section 3.7.4 + mkdir -p "$(PREFIX)/etc/opt" + + # section 4.2 + mkdir -p "$(PREFIX)/usr/bin" + mkdir -p "$(PREFIX)/usr/lib" + mkdir -p "$(PREFIX)/usr/local" + mkdir -p "$(PREFIX)/usr/sbin" + mkdir -p "$(PREFIX)/usr/share" + + # section 4.3 + mkdir -p "$(PREFIX)/usr/include" + mkdir -p "$(PREFIX)/var/spool" + mkdir -p "$(PREFIX)/var/tmp" + mkdir -p "$(PREFIX)/var/lock" + ln -s "$(PREFIX)/usr/spool" "$(PREFIX)/var/spool" + ln -s "$(PREFIX)/usr/tmp" "$(PREFIX)/var/tmp" + ln -s "$(PREFIX)/usr/spool/locks" "$(PREFIX)/var/lock" + + # section 4.6 + mkdir -p "$(PREFIX)/usr/lib" + + # section 4.9 + mkdir -p "$(PREFIX)/usr/local" + + # section 4.9.2 + mkdir -p "$(PREFIX)/usr/local/bin" + #mkdir -p "$(PREFIX)/usr/local/etc" # see section 4.9.3 + mkdir -p "$(PREFIX)/usr/local/games" + mkdir -p "$(PREFIX)/usr/local/include" + mkdir -p "$(PREFIX)/usr/local/lib" + mkdir -p "$(PREFIX)/usr/local/man" + mkdir -p "$(PREFIX)/usr/local/sbin" + mkdir -p "$(PREFIX)/usr/local/share" + mkdir -p "$(PREFIX)/usr/local/src" + + # section 4.9.3 + ln -s "$(PREFIX)/usr/local/etc" "$(PREFIX)/etc/local" + + # section 4.11.6 + mkdir -p "$(PREFIX)/usr/share/man" + + # section 4.11.7 + mkdir -p "$(PREFIX)/usr/share/misc" + + # section 4.12 + mkdir -p "$(PREFIX)/usr/src" + + # section 5.2 + mkdir -p "$(PREFIX)/var/lib" + mkdir -p "$(PREFIX)/var/local" + mkdir -p "$(PREFIX)/var/log" + mkdir -p "$(PREFIX)/var/opt" + #mkdir -p "$(PREFIX)/var/run" # see section 5.13.2 + + # section 5.8.2 + mkdir -p "$(PREFIX)/var/lib/misc" + + # section 5.13.2 + ln -s "$(PREFIX)/var/run" "$(PREFIX)/run" + + # section 6.1.10 + mkdir -p "$(PREFIX)/var/spool/cron" + +learn: fhs + mkdir -p "$(PREFIX)/usr/man/man1" + cp "$(PREFIX)/dist/doc/*.1" "$(PREFIX)/usr/man/man1/" + mkdir -p "$(PREFIX)/usr/man/man7" + cp "$(PREFIX)/dist/doc/*.7" "$(PREFIX)/usr/man/man7/" + +musl_fetch: "$(PREFIX)/usr/src/musl" + git clone "$(MUSL_UPSTREAM)" "$(PREFIX)/usr/src/musl" || true + +musl: musl_fetch + cd "$(PREFIX)/usr/src/musl" + ./configure --prefix="$(PREFIX)" + $(MAKE) install + +unrepo: + rm -rf "$(PREFIX)/.git" + rm -f "$(PREFIX)/LICENSE" + rm -f "$(PREFIX)/README.md" + +.PHONY: all destroy diff --git a/lsd/dist/doc/trilsd.7 b/lsd/dist/doc/trilsd.7 new file mode 100644 index 0000000..88d2cd1 --- /dev/null +++ b/lsd/dist/doc/trilsd.7 @@ -0,0 +1,65 @@ +.TH TRINITX 7 + +.SH PRONUNCIATION +"Try LSD" + +.SH SYNOPSIS +.I TriLSD +is a UNIX-like software distribution built upon the Linux kernel and the +musl C standard library, with nearly all configuration options left to the +user's own device. + +.SH BASE SYSTEM +A +.I TriLSD +system always has the following packages: +dash, +the GNU compiler collection, +GNU make, +musl, +and +linux and util-linux. +.PP +In addition, +.I TriLSD +needs a core utilities package. +The GNU coreutils are a popular choice but Busybox or your own may be used. +.PP +.I TriLSD +also needs an initialization system. +OpenRC is the suggested choice but others may be used. +SystemD is discouraged; it's mentioned for its popularity and frowned upon for +its generally lax security. + +.SH INSTALLATION +To install +.I TriLSD +most of the POSIX specified utilities including awk, git(1), GNU make, and a C +compiler that can build the GNU compiler collection must be installed. + +.PP +For the installation process see +.RB try (1) + +.SH PACKAGE MANAGEMENT +.I TriLSD +does not come with a package manager; the user may choose whatever +system-independent package manager they prefer. + +.SH CONTRIBUTING +Pay attention to projects' guidelines for distributions. +.PP +musl guidelines: https://wiki.musl-libc.org/guidelines-for-distributions.html + +.SH HISTORY +The +.I TriLSD +project was started 2021-12-28 as Trinitx. + +.SH COPYRIGHT +.I TriLSD +documentation and all in-house tools are part of the public domain. +Components of the distribution are of course subject to their own licenses. + +.SH SEE ALSO +.RB try (1) diff --git a/lsd/dist/mk.conf b/lsd/dist/mk.conf new file mode 100644 index 0000000..b7cd31a --- /dev/null +++ b/lsd/dist/mk.conf @@ -0,0 +1,3 @@ +GCC_UPSTREAM=git://gcc.gnu.org/git/gcc.git +MUSL_UPSTREAM=git://git.musl-libc.org/musl +PKGSRC_UPSTREAM=https://cdn.netbsd.org/pub/pkgsrc/current/pkgsrc.tar.xz diff --git a/streq/Makefile b/streq/Makefile index 9725de1..1d7f442 100644 --- a/streq/Makefile +++ b/streq/Makefile @@ -1,11 +1,7 @@ -all: streq +streq: streq.c + $(CC) -g -o streq streq.c clean: - rm -r streq + rm -f streq -sane: streq - -streq: streq.c - $(CC) -o streq streq.c - -.PHONY: all clean sane +.PHONY: clean diff --git a/streq/streq.c b/streq/streq.c index 5787e6b..d6fd0a6 100644 --- a/streq/streq.c +++ b/streq/streq.c @@ -1,12 +1,10 @@ -#include /* fprintf(3) */ -#include /* stderr, stdin, stdout */ +#include /* fprintf(3), stderr */ #include /* EX_USAGE */ static char *program_name = "streq"; int main(int argc, char *argv[]){ int i; - int j; if(argc < 3){ fprintf(stderr, "Usage: %s [string] [string...]\n", @@ -14,10 +12,9 @@ int main(int argc, char *argv[]){ return EX_USAGE; } - /* i is the arg index, j is the char index */ - for(j = 0; argv[1][j] != '\0'; ++j) + for(; *argv[1] != '\0'; ++argv[1]) for(i = 2; i < argc; ++i) - if(argv[i-1][j] != argv[i][j]) + if(*argv[i-1] != *argv[i]++) return 1; return 0; diff --git a/tekubi/Makefile b/tekubi/Makefile new file mode 100644 index 0000000..8e17bdd --- /dev/null +++ b/tekubi/Makefile @@ -0,0 +1,41 @@ +i2cdevlib_url = https://github.com/jrowberg/i2cdevlib.git + +setup: I2Cdev.cpp I2Cdev.h MPU6050.cpp MPU6050.h + +clean_setup: + rm -rf i2cdevlib i2cdevlib_tmp + rm -f I2Cdev.cpp I2Cdev.h + rm -f MPU6050.cpp MPU6050.h + +i2cdevlib: + rm -rf i2cdevlib_tmp + git init i2cdevlib_tmp + git -C i2cdevlib_tmp remote add -f origin $(i2cdevlib_url) + git -C i2cdevlib_tmp config core.sparseCheckout true + git -C i2cdevlib_tmp sparse-checkout set + git -C i2cdevlib_tmp checkout master + mv i2cdevlib_tmp i2cdevlib + +i2cdevlib/Arduino/I2Cdev: i2cdevlib + git -C i2cdevlib sparse-checkout add Arduino/I2Cdev + git -C i2cdevlib sparse-checkout reapply + git fetch + +i2cdevlib/Arduino/MPU6050: i2cdevlib + git -C i2cdevlib sparse-checkout add Arduino/MPU6050 + git -C i2cdevlib sparse-checkout reapply + git fetch + +I2Cdev.cpp: i2cdevlib/Arduino/I2Cdev + cp i2cdevlib/Arduino/I2Cdev/I2Cdev.cpp ./ + +I2Cdev.h: i2cdevlib/Arduino/I2Cdev + cp i2cdevlib/Arduino/I2Cdev/I2Cdev.h ./ + +MPU6050.cpp: i2cdevlib/Arduino/MPU6050 + cp i2cdevlib/Arduino/MPU6050/MPU6050.cpp ./ + +MPU6050.h: i2cdevlib/Arduino/MPU6050 + cp i2cdevlib/Arduino/MPU6050/MPU6050.h ./ + +.PHONY: setup clean_setup diff --git a/tekubi/main.ino b/tekubi/main.ino new file mode 100644 index 0000000..892b28a --- /dev/null +++ b/tekubi/main.ino @@ -0,0 +1,89 @@ +#define RAD_PIN 0 +#define ECG_PIN 14 /* A0 */ +/* TEKUBI + * ___________ ________________________________ + * | | | | + * | USB POWER | | TEENSY 4.0 | + * | | | | + * |__GND__5V__| |__Vin__GND__D0__SDA0__SCL0__A0__| + * | | | | | | | | + * | +--------+----|---|-+--|-----|----|----------+ + * | | | | | | | | | + * +----|-------------+---|-|--|-----|----|-----+ | + * | | | | | | | | | | + * | | +---------|---+ | +---+ | +-+ | | + * __ | __ |__ | __ __ | __ |____ | | | ____ | __ | __ + * | GND 5V INT | | GND Vcc | | | | | GND Vcc | + * | (100mA?) | | (10mA) SDA--+ | +-A (4mA) | + * | | | | | | | + * | GEIGER COUNTER | | GYRO SCL----+ | ECG | + * |________________| |______________| |______________| */ + +/* geiger counter + * https://www.rhelectronics.store + * /radiation-detector-geiger-counter-diy-kit-second-edition */ +#include +#define RAD_LOG_PERIOD 5000 /* milliseconds; sample rate */ +#define MINUTE 60000 /* milliseconds in a minute */ +/* https://www.arduino.cc/reference/en/language/variables/data-types/ + * unsignedlong/ - 32 bit */ +unsigned long rad_count = 0; +unsigned long rad_cpm; +void rad_interrupt(){ ++rad_count; } +/* https://www.pjrc.com/teensy/td_timing_elaspedMillis.html */ +elapsedMillis rad_period = 0; +void geiger_setup(){ + pinMode(RAD_PIN, INPUT); + digitalWrite(RAD_PIN, HIGH); + attachInterrupt(0, rad_interrupt, FALLING); +} +void geiger_loop(){ + if(rad_period > RAD_LOG_PERIOD){ + rad_cpm = rad_count * (MINUTE / RAD_LOG_PERIOD); + rad_period = 0; + } + /* use rad_cpm */ +} + +/* gyro + * https://www.elecrow.com/crowtail-mpu6050-accelerometer-gyro.html */ +/* https://github.com/jrowberg/i2cdevlib/ + * Most inexplicable stuff is because it was in Arduino/MPU6050/examples/ + * MPU6050_raw/MPU6050_raw.ino */ +#include "I2Cdev.h" +#include "MPU6050.h" +#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE +# include "Wire.h" +#endif +MPU6050 accelgyro; +int16_t accel_x, accel_y, accel_z, gyro_x, gyro_y, gyro_z; +void gyro_setup(){ + #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE + Wire.begin(); + #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE + Fastwire::setup(400, true); + #endif + accelgyro.initialize(); +} +void gyro_loop(){ + accelgyro.getMotion6(&accel_x, &accel_y, &accel_z, + &gyro_x, &gyro_y, &gyro_z); + /* use accel_*, gyro_* */ +} + +/* ecg + * https://www.elecrow.com/crowtail-pulse-sensor-p-1673.html */ +void ecg_setup(){ +} + +/* teensy 4.0 + * https://www.pjrc.com/store/teensy40.html */ +void setup(){ + geiger_setup(); + gyro_setup(); + ecg_setup(); +} +void loop(){ + geiger_loop(); + gyro_loop(); +} diff --git a/xjiggler/xjiggler b/xjiggler/xjiggler new file mode 100755 index 0000000..7febbb9 --- /dev/null +++ b/xjiggler/xjiggler @@ -0,0 +1,116 @@ +#!/bin/sh +set -e + +# based on https://github.com/carrot69/keep-presence/ + +test -n "$XJIGGLER_DELAY_ACTION" \ + || XJIGGLER_DELAY_ACTION=300 # seconds +test -n "$XJIGGLER_DELAY_DETECTION" \ + || XJIGGLER_DELAY_DETECTION=60 # seconds +test -n "$XJIGGLER_KEYBOARD_ENABLED" \ + || XJIGGLER_KEYBOARD_ENABLED='' # zero-len nonzero-len +test -n "$XJIGGLER_MOUSE_DIRECTION" \ + || XJIGGER_MOUSE_DIRECTION=DIAGONAL # "CIRCULAR" "DIAGONAL" +test -n "$XJIGGLER_MOUSE_DISTANCE" \ + || XJIGGLER_MOUSE_DISTANCE=1 # pixels +test -n "$XJIGGLER_MOUSE_ENABLED" \ + || XJIGGLER_MOUSE_ENABLED=yes # zero-len nonzero-len + +# eval is scary but this use was mentioned in the man page +getmouselocation(){ + eval $(xdotool getmouselocation --shell | sed 's/^/XJIGGLER_/g') + XJIGGLER_T="$(date '+%s')" +} + +jiggle(){ + test -z "$XJIGGLER_MOUSE_ENABLED" \ + || xdotool mousemove_relative "$XJIGGLER_MOUSE_dX" \ + "$XJIGGLER_MOUSE_dY" +} + +pushmouselocation(){ + XJIGGLER_lastT="$XJIGGLER_T" + XJIGGLER_lastX="$XJIGGLER_X" + XJIGGLER_lastY="$XJIGGLER_Y" +} + +printdebug(){ + printf "XJIGGLER_T=%s\n" "$XJIGGLER_T" # seconds since epoch + printf "XJIGGLER_X=%s\n" "$XJIGGLER_X" # pixels + printf "XJIGGLER_Y=%s\n" "$XJIGGLER_Y" # pixels + printf "XJIGGLER_lastT=%s\n" "$XJIGGLER_lastT" + printf "XJIGGLER_lastX=%s\n" "$XJIGGLER_lastX" + printf "XJIGGLER_lastY=%s\n" "$XJIGGLER_lastY" +} + +rotatemousedirection(){ + case "$XJIGGLER_MOUSE_DIRECTION" in + up) XJIGGLER_MOUSE_DIRECTION=right + XJIGGLER_MOUSE_dX="$XJIGGLER_MOUSE_DISTANCE" + XJIGGLER_MOUSE_dY=0 + return; ;; + right) XJIGGLER_MOUSE_DIRECTION=down + XJIGGLER_MOUSE_dX=0 + XJIGGLER_MOUSE_dY="$XJIGGLER_MOUSE_DISTANCE" + return; ;; + down) XJIGGLER_MOUSE_DIRECTION=left + XJIGGLER_MOUSE_dX=-"$XJIGGLER_MOUSE_DISTANCE" + XJIGGLER_MOUSE_dY=0 + return; ;; + CIRCULAR | left) + XJIGGLER_MOUSE_DIRECTION=up + XJIGGLER_MOUSE_dX=0 + XJIGGLER_MOUSE_dY=-"$XJIGGLER_MOUSE_DISTANCE" + DIAGONAL | *) + XJIGGLER_MOUSE_dX="$XJIGGLER_MOUSE_DISTANCE" + XJIGGLER_MOUSE_dY="$XJIGGLER_MOUSE_DISTANCE" + return; ;; + return; ;; + esac +} + +usage(){ + printf 'Usage: %s (-chm) (-d [distance]) %s\n' \ + "$0" '(-s [action delay seconds])'>&2 + exit 64 # sysexits(3) EX_USAGE +} + +while getopts :cd:hms: OPTION +do + case "$OPTION" in + c) XJIGGLER_MOUSE_DIRECTION=DIAGONAL ;; + d) XJIGGLER_MOUSE_DISTANCE="$OPTARG)" ;; + m) XJIGGLER_MOUSE_ENABLED='' ;; + s) XJIGGLER_DELAY_ACTION="$(OPTARG)" ;; + *) usage ;; + esac +done + +getmouselocation; pushmouselocation + +while true +do + + sleep "$XJIGGLER_DELAY_DETECTION" + getmouselocation + if test "$XJIGGLER_lastX" = "$XJIGGLER_X" \ + && test "$XJIGGLER_lastY" = "$XJIGGLER_Y" + then # no movement + command -v xprintidle \ + && test "$(xprintidle \ + | sed -e 's/^/0/' -e 's/...$//')" \ + -gt "$XJIGGLER_DELAY_ACTION" \ + || test "$(printf '%s\n%s\n-\np\n' "$XJIGGLER_T" \ + "$XJIGGLER_lastT" \ + | dc)" -gt "$XJIGGLER_DELAY_ACTION" \ + || continue # hasn't been long enough + rotatemousedirection; jiggle + printf '%s: Jiggled:\n' "$0" + printdebug | sed 's/^/\t/g' + getmouselocation + else # movement + printf '%s: Movement detected:\n' "$0" + printdebug | sed 's/^/\t/g' + fi + pushmouselocation +done >&2