1
0

spring cleaning 1

This commit is contained in:
dtb
2023-12-31 10:46:23 -07:00
parent ea31d1221c
commit f501a77764
116 changed files with 4712 additions and 8 deletions

21
Wip/bitch/Makefile Normal file
View File

@@ -0,0 +1,21 @@
CFLAGS = -g
RM = rm -f
SOURCE = bitch.c
TARGETS = bitch
all: $(TARGETS)
motif: $(SOURCE)
$(CC) $(CFLAGS) -o $@ \
-DMOTIF -I/usr/pkg/include/ -I/usr/X11R7/include/ \
-L/usr/pkg/lib/ -L/usr/X11R7/lib -lXm -lX11 \
$(SOURCE)
gtk4: $(SOURCE)
$(CC) $(CFLAGS) -o $@ \
-DGTK4 `pkg-config --cflags gtk4` `pkg-config --libs gtk4` \
$(SOURCE)
clean:
$(RM) $(TARGETS)
%: %.c
$(CC) -o $@ $(CFLAGS) $@.c
.PHONY: all clean

45
Wip/bitch/bitch.1 Normal file
View File

@@ -0,0 +1,45 @@
.TH BITCH 1
.SH NAME
bitch \(en a pretty interface from which to select tasks
.SH SYNOPSIS
bitch
.RB ( -rx )
.RB [ -h
.BR horizontal ]
.RB [ -v
.BR vertical ]
.SH GRAPHICS
Bitch is written for the GNU Image Manipulation Program's Graphical Toolkit 4.
A windowing system is required to use bitch.
.SH DESCRIPTION
Bitch reads a list of newline-delimited items from standard input and presents a menu with the options.
.PP
With the
.B -x
option, bitch will eXit when the first item is chosen, otherwise bitch will print or execute subsequent selections.
.PP
With the
.B -r
option, bitch will execute the selected item with system(3). Otherwise, bitch will print the selection text.
.PP
The window bitch presents will be of the horizontal and vertical resolution specified with
.B -h
and
.B -v
respectively.
.SH BUGS
He who calls bitches bitches gets no bitches.
.SH COPYRIGHT
Public domain.

208
Wip/bitch/bitch.c Normal file
View File

@@ -0,0 +1,208 @@
#include <stdio.h>
#include <stdlib.h> /* stderr, atoi(3) */
#include <string.h> /* strchr(3) */
#include <sysexits.h> /* EX_USAGE */
#include <unistd.h> /* getopt(3) */
#ifdef GTK4
# include <gtk/gtk.h>
#endif
#ifdef MOTIF
# include <Xm/Xm.h>
# include <Xm/PushB.h>
#endif
#define BUF 100
/* Pinephone dimensions as default */
static unsigned int h = 720;
static unsigned int v = 1440;
static char *argv0;
static char buf[BUF];
static char f;
static unsigned char shy = 0;
static int fake_argc = 1;
static char *fake_argv[2] = { NULL, NULL };
#ifdef GTK4
static GtkApplication *app;
static void activate(GtkApplication *app, gpointer user_data);
static void button_pressed(GtkWidget *button, gpointer data);
#endif
#ifdef MOTIF
static XtAppContext app_context;
static void activate(void);
static void button_pressed(
Widget w, XtPointer client_data, XmPushButtonCallbackStruct *cbs
);
#endif
int main(int argc, char *argv[]){
int c;
extern char *optarg;
int status;
argv0 = argv[0];
fake_argv[0] = argv0;
f = 'x';
while((c = getopt(argc, argv, "h:v:wx")) != -1)
switch(c){
case 'h':
h = atoi(optarg);
break;
case 'w':
f = 'w';
break;
case 'v':
v = atoi(optarg);
break;
case 'x':
shy = 1;
break;
default: usage:
fprintf(stderr, "\
Usage: %s (-rx)\n\
\t(-h [horizontal resolution]) (-v [vertical resolution])\n",
argv0
);
return EX_USAGE;
}
#ifdef GTK4
app = gtk_application_new(
"org.trinity.femaledog", G_APPLICATION_FLAGS_NONE
);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), 1, fake_argv);
g_object_unref(app);
#endif
#ifdef MOTIF
activate();
#endif
return status;
}
char *
sip(void){
int c;
char *s;
if(fgets(buf, sizeof(buf) / sizeof(*buf), stdin) == NULL){
if(ferror(stdin) != 0)
#ifdef GTK4
g_print
#else
printf
#endif
("%s: stdin: file read error\n", argv0);
return NULL;
}
if((s = strchr(buf, '\n')) == NULL) /* flush */
while((c = getc(stdin)) != '\n' && c != EOF);
else
*s = '\0';
return buf;
}
#ifdef GTK4
static void
activate(GtkApplication *app, gpointer user_data){
GtkWidget *box;
GtkWidget *button;
int c;
char *s;
GtkWidget *scrolledwindow;
GtkWidget *window;
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window), "Bitch");
gtk_window_set_default_size(GTK_WINDOW(window), h, v);
scrolledwindow = gtk_scrolled_window_new();
gtk_scrolled_window_set_overlay_scrolling(GTK_SCROLLED_WINDOW(scrolledwindow), 1);
gtk_window_set_child(GTK_WINDOW(window), scrolledwindow);
box = gtk_list_box_new();
//gtk_widget_set_halign(box, GTK_ALIGN_CENTER);
//gtk_widget_set_valign(box, GTK_ALIGN_CENTER);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrolledwindow), box);
for(;;){
if(sip() == NULL)
break;
button = gtk_button_new_with_label(buf);
g_signal_connect(
button, "clicked", G_CALLBACK(button_pressed), NULL
);
gtk_list_box_insert(GTK_LIST_BOX(box), button, -1);
}
gtk_window_present(GTK_WINDOW(window));
return;
}
static void
button_pressed(GtkWidget *button, gpointer data){
switch(f){
case 'w':
g_print("%s\n", gtk_button_get_label(GTK_BUTTON(button)));
break;
case 'x':
system(gtk_button_get_label(GTK_BUTTON(button)));
break;
}
if(shy)
g_application_quit(G_APPLICATION(app));
return;
}
#endif /* ifdef GTK4 */
#ifdef MOTIF
static void
activate(void){
Widget button;
Widget top_wid;
top_wid = XtVaAppInitialize(
&app_context, "Bitch", NULL, 0, &fake_argc, fake_argv, NULL,
NULL
);
for(;;){
if(sip() == NULL)
break;
button = XmCreatePushButton(top_wid, buf, NULL, 0);
XtManageChild(button);
XtAddCallback(button, XmNactivateCallback, button_pressed, NULL);
}
XtRealizeWidget(top_wid);
XtAppMainLoop(app_context);
}
static void
button_pressed(
Widget w,
XtPointer client_data,
XmPushButtonCallbackStruct *cbs
){
printf("pressed\n");
if(shy)
XtAppSetExitFlag(app_context);
}
#endif

7
Wip/bitch/bitch_please Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -ex
$(for folder in $(printf "%s\n" "$PATH" | tr ':' '\n');
do ls $folder
done | sort | $(command -v bitch))

84
Wip/com/com Normal file
View File

@@ -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
}
}
'

55
Wip/cstdlib/ctype.c Normal file
View File

@@ -0,0 +1,55 @@
int
isblank(int c){
return c == '\t'
|| c == ' ';
}
int
isspace(int c){
return isblank(c)
|| c == '\n'
|| c == '\v'
|| c == '\f'
|| c == '\r';
}
int
isgraph(int c){ return c >= '!' && c <= '~'; }
int
isprint(int c){ return c == ' ' || isgraph(c); }
int
iscntrl(int c){ return !isprint(c); }
int
isdigit(int c){ return c >= '0' && c <= '9'; }
int
islower(int c){ return c >= 'a' && c <= 'z'; }
int
isupper(int c){ return c >= 'A' && c <= 'Z'; }
int
isxdigit(int c){
return
isdigit(c)
|| (c >= 'a' && c <= 'f')
|| (c >= 'A' && c <= 'F');
}
int
isalpha(int c){ return islower(c) || isupper(c); }
int
isalnum(int c){ return isalpha(c) || isdigit(c) };
int
ispunct(int c){ return c != ' ' && !isalnum(c) };
int
tolower(int c){ return c - isupper(c) * ('A' - 'a'); }
int
toupper(int c){ return c + islower(c) * ('A' - 'a'); }

17
Wip/cstdlib/ctype.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef _CTYPE_H
# define CTYPE_H
int isblank(int c);
int isspace(int c);
int isgraph(int c);
int isprint(int c);
int iscntrl(int c);
int isdigit(int c);
int islower(int c);
int isupper(int c);
int isxdigit(int c);
int isalpha(int c);
int isalnum(int c);
int ispunct(int c);
int tolower(int c);
int toupper(int c);
#endif /* ifndef _CTYPE_H */

53
Wip/cstdlib/string.c Normal file
View File

@@ -0,0 +1,53 @@
char *
strchr(const char *s, int c){
char *r;
for(r = s; ; ++r){
if(*r == c)
return r;
if(*r == '\0')
return NULL;
}
}
char *
strrchr(const char *s, int c){
char *r;
char *p;
for(p = s, r = NULL; ; ++p){
if(*p == c)
r = p;
if(*p == '\0')
break;
}
return r;
}
char *
strchrnul(const char *s, int c){
char *r;
for(r = s; ; ++r)
if(*r == c || r == '\0')
return r;
}
size_t
strlen(const char *s){
size_t r;
for(r = 0; s[r] != '\0'; ++r);
return r;
}
size_t
strnlen(const char *s, size_t maxlen){
size_t r;
for(r = 0; s[r] != '\0' && r < maxlen; ++r);
return r;
}

8
Wip/cstdlib/string.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef _STRING_H
# define _STRING_H
char * strchr(const char *s, int c);
char * strrchr(const char *s, int c);
char *strchrnul(const char *s, int c);
size_t strlen(const char *s);
size_t strnlen(const char *s, size_t maxlen);
#endif /* ifndef _STRING_H */

67
Wip/cut/cut.c Normal file
View File

@@ -0,0 +1,67 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
#include "noargvzero.h"
extern char *optarg; /* getopt(3); unistd.h */
extern int optind, opterr, optopt; /* getopt(3); unistd.h */
void
occurrences(FILE *f, char *s){
}
void
usage(char *name){
fprintf(stderr,
"Usage: %s (-b [list] (-n))"
"\t|(-c [list])"
"\t|(-f [list] (-d [delim]) (-s))"
"\t[file...]\n", name);
exit(EX_USAGE);
}
int
main(int argc, char *argv[]){
int c;
char *delimiter;
char *list;
char mode;
NOARGVZERO(argv[0]);
/* perhaps mode could be specified after submodal stuff. this would
* move checks to after argument parsing though which could take more
* time. */
mode = 0;
submode = 0;
while((c = getopt(argc, argv, "b:c:d:f:ns")) != -1)
switch(c){
case 'b': case 'c': case 'f':
if(mode != 0)
usage(argv[0]);
mode = c;
list = optarg;
break;
case 'd':
if(mode != 'f')
usage(argv[0]);
delimiter = optarg;
break;
case 'n': case 's':
if((c == 's' && mode != 'f')
|| (c == 'b' && mode != 'b'))
usage(argv[0]);
submode = c;
break;
default:
usage(argv[0]);
}
return EX_OK;
}

3
Wip/ftesosd/LICENSE Normal file
View File

@@ -0,0 +1,3 @@
Derived from
https://gist.github.com/artixnous/41f4bde311442aba6a4f5523db921415
without license.

257
Wip/ftesosd/eyesockets.sh Executable file
View File

@@ -0,0 +1,257 @@
#!/bin/sh
# nous,2019-2020
# trinity,2021
# fork from the original FUCKTHESKULLOFSYSTEMD on GitHub Gists:
# https://gist.github.com/artixnous/41f4bde311442aba6a4f5523db921415
# Test Arch ISO installation:
# cfdisk /dev/sda
# mkfs.ext4 /dev/sda1
# mount /dev/sda1 /mnt
# pacstrap /mnt base linux linux-firmware openssh wget rsync dhcpcd grub
# arch-chroot /mnt
# grub-install /dev/sda
# mkinitcpio -P
# grub-mkconfig -o /boot/grub/grub.cfg
# the package name MUST be the same as the editor itself
# e.g. vim, ed, nano, ne, vis
# nous' default was nano, most people know how to use that one so that's what's
# being used here
DEFAULT_EDITOR="nano"
if [ -z "$VISUAL" ] && [ -n "$EDITOR" ]; then
VISUAL="$EDITOR"
elif [ -z "$VISUAL" ] && [ -z "$EDITOR" ]; then
VISUAL="$DEFAULT_EDITOR"
fi
. /usr/share/makepkg/util/message.sh
colorize
printf "$BOLD\
You should run this from inside screen(1) or tmux(1), especially if this is a
remote box. Use a terminal/session with a large scrollback buffer.
"
read -n 1 -p "$RED Last chance to press CTRL-C, ENTER to continue. "
printf "$CYAN\
Starting operation $RED\ FUCKTHESKULLOFSYSTEMD
"
error
error() {
printf "$RED\
An error occured, aborting to prevent incomplete conversion. Fix it and re-run
the script FROM THE LAST STEP ONWARDS.
"
exit 1
}
[ "$1" = "openrc" ] && target="openrc"
[ "$1" = "runit" ] && target="runit"
# runit not yet implemented
#[[ $target ]] || { echo "Usage: $0 <openrc|runit>" ; exit 1; }
#echo "Target: $target"
rm -f /var/lib/pacman/db.lck
sed -i s/Arch/Artix/g /etc/default/grub
# A full systemd update is needed, because libsystemd->systemd-libs
printf "$GREEN\
Updating Arch system first, if this fails abort and update manually;
then re-run the script \
$ALL_OFF"
pacman -Syu --noconfirm \
|| error
pacman -S --needed --noconfirm wget "$VISUAL" rsync \
|| error
cd /etc
printf "$GREEN\
Replacing Arch repositories with Artix\
$ALL_OFF"
mv -vf pacman.conf pacman.conf.arch
wget https://gitea.artixlinux.org/packagesP/pacman/raw/branch/master/trunk/pacman.conf -O /etc/pacman.conf \
|| error
mv -vf pacman.d/mirrorlist pacman.d/mirrorlist-arch
wget https://gitea.artixlinux.org/packagesA/artix-mirrorlist/raw/branch/master/trunk/mirrorlist -O pacman.d/mirrorlist \
|| error
cp -vf pacman.d/mirrorlist pacman.d/mirrorlist.artix
sed -i 's/Required DatabaseOptional/Never/' pacman.conf
printf "$GREEN\
Refreshing package databases\
$ALL_OFF"
pacman -Syy --noconfirm \
|| error
printf "\n"
read -n 1 -p "$GREEN Press ENTER and answer <yes> to the next question to make sure all packages come from Artix repos $ALL_OFF "
echo
pacman -Scc
echo "$GREEN Importing Artix keys $ALL_OFF"
pacman -S --noconfirm artix-keyring \
|| error
pacman-key --populate artix \
|| error
pacman-key --lsign-key 95AEC5D0C1E294FC9F82B253573A673A53C01BC2 \
|| error
systemctl list-units --state=running | grep -v systemd | awk '{print $1}' | grep service > /root/daemon.list
printf "$MAGENTA\
Your systemd running units are saved in /root/daemon.list.\n
$ALL_OFF"
read -n 1 -p "$RED\
Do not proceed if you've seen errors above.
Press CTRL-C to abort or ENTER to continue
$ALL_OFF"
printf "$GREEN
Downloading systemd-free packages from Artix
$ALL_OFF"
pacman -Sw --noconfirm \
base \
base-devel \
openrc-system \
grub linux-lts \
linux-lts-headers \
elogind-openrc \
openrc \
netifrc \
grub mkinitcpio \
archlinux-mirrorlist \
net-tools \
rsync \
"$VISUAL" \
lsb-release \
esysusers \
etmpfiles \
|| error
printf "$YELLOW\
This is the best part: removing systemd
$ALL_OFF"
pacman -Rdd --noconfirm \
systemd \
systemd-libs \
systemd-sysvcompat \
pacman-mirrorlist \
dbus \
|| error
# Previous pacman-mirrorlist removal also deleted this, restoring
cp -vf pacman.d/mirrorlist.artix pacman.d/mirrorlist
echo "$GREEN Installing clean Artix packages $ALL_OFF"
pacman -Qqn | pacman -S --noconfirm --overwrite '*' - \
|| error
echo "$GREEN Installing Artix system packages $ALL_OFF"
pacman -S --noconfirm --needed --overwrite '*' \
base \
base-devel \
openrc-system \
linux-lts \
linux-lts-headers \
elogind-openrc \
openrc \
netifrc \
grub \
mkinitcpio \
archlinux-mirrorlist \
net-tools \
rsync \
"$DEFAULT_EDITOR" \
lsb-release \
connman \
esysusers \
etmpfiles \
artix-branding-base \
|| error
echo "$GREEN Installing service files $ALL_OFF"
pacman -S --noconfirm --needed \
at-openrc \
xinetd-openrc \
cronie-openrc \
haveged-openrc \
hdparm-openrc \
openssh-openrc \
syslog-ng-openrc \
connman-openrc \
|| error
echo "$YELLOW Removing left-over cruft $ALL_OFF"
rm -fv /etc/resolv.conf
echo "$GREEN Enabling basic services $ALL_OFF"
rc-update add haveged sysinit
rc-update add udev sysinit
rc-update add sshd default
echo
echo "$BOLD Activating standard network interface naming (i.e. enp72^7s128%397 --> eth0)."
echo "$BOLD If you prefer the persistent naming, remove the last line from /etc/default/grub"
echo "$BOLD and run $ALL_OFF grub-mkconfig -o /boot/grub/grub.cfg $BOLD when this script prompts for reboot."
echo
read -n 1 -p "Press ENTER $ALL_OFF"
echo 'GRUB_CMDLINE_LINUX="net.ifnames=0"' >>/etc/default/grub
pacman -S --needed --noconfirm netifrc
printf "\
============================= $BOLD
Write down your IP and route. $ALL_OFF
=============================
"
ifconfig
route
printf " \
=============================================================== $BOLD
Press ENTER to edit conf.d/net to configure static networking.
No editing is needed if you use dhcp or a network manager, but
you MUST enable the daemon manually BEFORE rebooting.
You will be given the option at the end of this procedure.
Default setting is DHCP for eth0, should be enough for most. $ALL_OFF
===============================================================
"
read -n 1 -p " "
"$VISUAL" /etc/conf.d/net
ln -sf /etc/init.d/net.lo /etc/init.d/net.eth0
rc-update add net.eth0 default \
|| error
# Good riddance
echo "$YELLOW Removing more systemd cruft $ALL_OFF"
for user in journal journal-gateway timesync network bus-proxy journal-remote journal-upload resolve coredump;
do userdel systemd-$user
done
rm -vfr /{etc,var/lib}/systemd
echo "$GREEN Restoring pacman.conf security settings $ALL_OFF"
sed -i 's/= Never/= Required DatabaseOptional/' /etc/pacman.conf
echo "$GREEN Making OpenRC start faster $ALL_OFF"
sed -i 's/#rc_parallel="NO"/rc_parallel="YES"/' /etc/rc.conf
echo "$GREEN Replacing Arch with Artix in hostname and issue $ALL_OFF"
sed -i 's/Arch/Artix/ig' /etc/hostname /etc/issue 2>/dev/null
echo "$GREEN Recreating initrds $ALL_OFF"
mkinitcpio -P
echo "$GREEN Recreating grub.cfg $ALL_OFF"
cp -vf /boot/grub/grub.cfg /boot/grub/grub.cfg.arch
grub-mkconfig -o /boot/grub/grub.cfg \
|| error
echo "============================================="
echo "= If you haven't seen any errors ="
echo "= press ENTER to reboot ="
echo "= Otherwise switch console and fix them ="
echo "= ="
echo "= ="
echo "= Press CTRL-C to stop reboot ="
echo "=(mandatory if you need a networking daemon)="
echo "=Or switch console/terminal and type as root="
echo "= $BOLD rc-service add connmand $ALL_OFF ="
echo "= then switch back here and continue ="
echo "============================================="
read -n 1 -p " "
sync
mount -f / -o remount,ro
echo s >| /proc/sysrq-trigger
echo u >| /proc/sysrq-trigger
echo b >| /proc/sysrq-trigger

12
Wip/head/head.c Normal file
View File

@@ -0,0 +1,12 @@
#include <stdio.h>
#include <stdlib.h>
/* The philosophical bits - /should this be a shell script?/ -
* are more complicated than the actual program. sed(1) is not currently a part
* of this project so there shouldn't be reliance on it. */
int main(int argc, char *argv[]){
char *argv0 = argv[0];
size_t i;

3
Wip/ht16k33/Makefile Normal file
View File

@@ -0,0 +1,3 @@
CFLAGS += -I/usr/local/include -L/usr/local/lib
ht16k33: ht16k33.c
$(CC) $(CFLAGS) -lwiringPi -o ht16k33 ht16k33.c

2
Wip/ht16k33/README.txt Normal file
View File

@@ -0,0 +1,2 @@
This program depends on WiringPi. Build instructions can be found in the
Makefile in the root of this project.

14
Wip/ht16k33/ht16k33.c Normal file
View File

@@ -0,0 +1,14 @@
#include <unistd.h>
#include <wiringPiI2C.h>
#include "ht16k33.h"
/* https://cdn-shop.adafruit.com/datasheets/ht16K33v110.pdf */
#define ADDRESS 0x70
int main(int argc, char *argv[]){
int fd;
fd = wiringPiI2CSetup(ADDRESS);
close(fd);
}

11
Wip/ht16k33/ht16k33.h Normal file
View File

@@ -0,0 +1,11 @@
/* Definitions were determined by reading Adafruit code and the datasheet. */
#define HT16K33_SYSTEM_CMD 0x20 /* 0b0010???x */
#define HT16K33_SYSTEM_ON 0x01 /* 0b00000001 */
#define HT16K33_SYSTEM_OFF 0x00 /* 0b00000000 */
/* `0xE0 | n`, where 0 <= n <= 15 and the display dims to (n+1)/16 duty */
#define HT16K33_CMD_BRIGHTNESS 0xE0 /* 0b1110xxxx */
#define HT16K33_BLINK_CMD 0x80 /* 0b1000?xxx */
#define HT16K33_BLINK_DISPLAYON 0x01 /* 0b1000???x */

3
Wip/http/config.h Normal file
View File

@@ -0,0 +1,3 @@
#define Server "UNIX"
#define HTTP_ROOT "/var/www"
#define SERVER_ADDRESS "www.example.com"

94
Wip/http/url.c Normal file
View File

@@ -0,0 +1,94 @@
#include "url.h"
/* safely frees URL struct */
struct Url *
free_url(struct Url *url){
free(url->s);
free(url->ssp);
free(url);
return NULL;
}
/* turns scheme specific part of URL from string into SSP struct */
/* returns NULL on allocation error or scheme syntax error */
struct CommonInternetScheme *
disassemble_commoninternetscheme(char *ssp){
int i;
char *p;
struct CommonInternetScheme *retval;
if( /* embarrassingly long if statement */
(retval
= (struct CommonInternetScheme *)
malloc(sizeof(struct CommonInternetScheme))
) == NULL
)
return NULL;
parsed = 0;
/* the scheme-specific data starts with a double slash to indicate that
* it complies with the common Internet scheme syntax (RFC 1738 3.1) */
if(ssp[0] != '/' || ssp[1] != '/')
return NULL;
ssp += 2;
/* probe to determine what areas of the SSP are filled */
p = ssp;
return retval;
}
/* turns URL string into URL struct */
struct Url *
disassemble_url(char *url){
char *p;
struct Url *retval;
size_t s_s;
size_t ssp_s;
size_t *s;
if((retval = (struct Url *)malloc(sizeof(struct Url))) == NULL)
return NULL;
s_s = 0;
ssp_s = 0;
/* get the lengths of the scheme and scheme specific part, excluding
* the nul byte */
p = url;
s = &s_s;
while(*p != '\0'){
/* standard; scheme names can't contain colons so the first
* colon must delimit the scheme from the scheme specific part
* (RFC 1738 2.1) */
if(s == &s_s && *p == ':'){
s = &ssp_s;
++p;
}
++*p;
}
/* malloc the lengths, including the nul byte */
if((retval->s = (char *)malloc(sizeof(char) * (s_s + 1))) == NULL)
goto free_retval;
if((retval->ssp = (char *)malloc(sizeof(char) * (ssp_s + 1))) == NULL)
goto free_s;
/* copy over the scheme and scheme specific part strings */
p = retval->s;
while(*url != ':')
*(p++) = *(url++);
*p = '\0';
p = retval->ssp;
while(*url != '\0')
*(p++) = *(url++);
*p = '\0';
return retval;
free_s:
free(retval->s);
free_retval:
free(retval);
return NULL;
}

20
Wip/http/url.h Normal file
View File

@@ -0,0 +1,20 @@
/* #include <stdlib.h> /* free(3), malloc(3), NULL */
/* RFC 1738 3.1 */
struct CommonInternetScheme{
char *user;
char *password;
char *host; /* FQDN, IPv4, or IPv6 address */
char *port; /* Can have default; must be supplied in decimal. */
char *url_path;
};
/* standard; RFC 1738 */
struct Url{
char *s; /* scheme */
/* char * or some sort of struct SchemeSpecificPart * */
void *ssp; /* scheme-specific-part */
};
struct Url *disassemble_url(char *url);
struct Url *free_url(struct Url *url);

66
Wip/id/id.c Normal file
View File

@@ -0,0 +1,66 @@
#include <limits.h> /* LOGIN_NAME_MAX */
#include <stdbool.h>
#include <stdio.h> /* fprintf(3) */
#include <stdlib.h> /* stderr, stdout */
#include <sysexits.h>
#include <unistd.h> /* getuid(2), geteuid(2), getopt(3) */
#include "usefulmacros.h"
int main(int argc, char *argv[]){
int c;
char mode;
bool n;
char name[LOGIN_NAME_MAX];
bool r;
uid_t euid;
uid_t uid;
NOARGVZERO(argv);
mode = 0;
n = false;
r = false;
while((c = getopt(argc, argv, "Gghnru")) != -1)
switch(c){
case 'G': case 'g': case 'u':
if(mode == 0){
mode = c;
break;
}
/* FALLTHROUGH */
case 'h': default: usage:
fprintf(stderr, "Usage: %s [-G]|[-g]|[-u] (-rn) (user)\n", argv[0]);
return EX_USAGE;
case 'n':
n = true;
break;
case 'r':
r = true;
break;
}
switch(mode){
case 0:
goto usage;
case 'G':
case 'g':
return EX_SOFTWARE;
case 'u':
euid = geteuid();
uid = getuid();
if(!n){
if(r || euid != uid)
fprintf(stdout, "%u\n", uid);
if(!r)
fprintf(stdout, "%u\n", euid);
}else
{}
/* Both busybox and GNU coreutils (according to straces) parse passwd(5)
* for this. TODO. */
break;
default:
return EX_SOFTWARE;
}
return EX_OK;
}

16
Wip/irc/irc.c Normal file
View File

@@ -0,0 +1,16 @@
#include <stdio.h>
#include <stdlib.h>
/* RFC 1459 1.2
* 9 characters + nul terminator */
static int nickname[9 + 1];
/* RFC 1459 1.3
* 200 characters + nul terminator */
static int channel[200 + 1];
/* RFC 1459 1.3
* channel names cannot contain these characters */
static int channel_restricted[] = { 0x07, ' ', ',', '\0' };

4
Wip/irc/irc.h Normal file
View File

@@ -0,0 +1,4 @@
#ifndef _IRC_H
# define _IRC_H
#endif /* ifndef _IRC_H */

139
Wip/irc/irc.sh Normal file
View File

@@ -0,0 +1,139 @@
#!/bin/sh
# irc; Deven Blake 2022; Public domain
# I stopped understanding this at 81 lines.
alias cat='cat -u'
alias sed='sed -u'
# defaults
DEFAULT_HOST="example.com"
PORT=6667
[ -n "$IRC_QUIT_MESSAGE" ] \
|| IRC_QUIT_MESSAGE="Bye bye!"
# defaults (standard-defined)
URI_FRAGMENT_DELIMITER='#' # RFC 3986
argv0="$0"
URL="$1"
usage(){
printf "Usage: %s [url]\n" "$argv0"
exit 1
}
one_character_per_line(){
sed 's/./&\n/g'
}
host_ex_url(){
# filter out scheme URI subcomponent
# filter out userinfo URI subcomponent
# filter out port
# filter out heirarchy path
# filter out query
# filter out fragment
printf "%s\n" "$URL" \
| sed 's/.*:\/\///' \
| sed 's/.*@//' \
| sed 's/:.*$//' \
| sed 's/\/.*$//' \
| sed 's/\?.*$//' \
| sed 's/#.*$//'
}
port_ex_url(){
# filter out scheme URI subcomponent
# filter out userinfo URI subcomponent
local_url="$(printf "%s\n" "$URL" \
| sed 's/.*:\/\///' \
| sed 's/.*@//')"
# check to ensure there Is a port in the URL
# this will also catch if we fucked up
if ! [ "$(printf "%s\n" "$local_url" \
| one_character_per_line \
| grep ':' \
| wc -l)" \
= 1 ]
then
# give up, gracefully
printf "%s\n" "$PORT"
return 0
fi
# filter out query URI subcomponent
# filter out heirarchy path
# filter out everything preceding the port
local_url="$(printf "%s\n" "$local_url" \
| sed 's/\?.*$//' \
| sed 's/\/.*$//' \
| sed 's/.*://')"
printf "%s\n" "$local_url"
}
username_ex_url(){
# only go if there's actually userinfo in the URL
# filter out scheme URI subcomponent
# filter out everything after userinfo URI subcomponent
# filter out password in userinfo, if present
printf "%s\n" "$URL" \
| grep '@' \
| sed 's/.*:\/\///' \
| sed 's/@.*$//' \
| sed 's/:.*$//'
}
[ -n "$URL" ] \
|| usage
[ -n "$IRC_NICK" ] \
|| IRC_NICK="$USER"
# check if URL matches /^irc:\/\//
if ! printf "%s\n" "$URL" | grep "^irc://" >/dev/null 2>&1; then
printf "%s: %s: URL incorrectly formatted or scheme not specified.\n" "$argv0" "$URL"
exit 1
fi
# easy; the fragment is the last part of the URI
CHANNEL="#$(printf "%s\n" "$URL" \
| sed 's/.*#//' )"
# not easy
PORT="$(port_ex_url)"
# slow, so don't rerun
a="$(username_ex_url)"
[ -z "$a" ] \
|| IRC_NICK="$a"
HOST="$(host_ex_url)"
[ -n "$HOST" ] \
|| HOST="$DEFAULT_HOST"
if ! TEMP="$(mktemp)" || ! TEMP_FIN="$(mktemp)"; then
printf "%s: mktemp: Could not make temporary file.\n" "$argv0"
exit 1
fi
# RFC 1459 section 4.1.2
printf "NICK %s\n" "$IRC_NICK" >"$TEMP"
# RFC 1459 section 4.1.3; USER <username> <hostname> <servername> <realname>
# not really important
printf "USER %s 0 0 :\n" "$IRC_NICK" >>"$TEMP"
# RFC 1459 section 4.2.1
printf "JOIN %s\n" "$CHANNEL" >>"$TEMP"
# RFC 1459 section 4.1.6
printf "QUIT :%s\n" "$IRC_QUIT_MESSAGE" >"$TEMP_FIN"
# RFC 1459 section 4.4.1
sed "s/^/PRIVMSG $CHANNEL :/g" \
| cat "$TEMP" /dev/stdin "$TEMP_FIN" \
| nc "$HOST" "$PORT"

24
Wip/it/LICENSE Normal file
View File

@@ -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 <https://unlicense.org>

4
Wip/it/Q.py Normal file
View File

@@ -0,0 +1,4 @@
from sys import exit
def main(buffer, argv):
return 0

67
Wip/it/README.md Normal file
View File

@@ -0,0 +1,67 @@
# it
*UNIX ed for a new age...*
Just kidding, no need to use this over ed.
This is just my take on a line editor, heavily inspired by ed.
For disambiguation it's suggested that this project be referred to as "ited", pronounced however one likes (suggested: "iht-ehd").
## Included commands
### !
Passes arguments to Python `subprocess.run`.
### buffer
This is where code relating to the Buffer class is kept but calling this from within the editor will allow you to view the current buffer's attributes.
### dot
Change the current position within the buffer.
### exit
Will exit via sys.exit rather than telling main.py to break out of the main loop. Functionally identical to `Q`.
### f
Displays or changes the filename associated with the current buffer.
### it
Launches a new instance of `it`.
It should be noted that quitting a nested instance of `it` through the usual means (`exit`, `q`, or `Q`) will exit all nested instances of `it` as well.
To return to a higher instance of `it`, send an EOF character via your terminal. In xterm this is CTRL+d.
### load\_module
Manually loads a module, whether or not it was already loaded.
### parse\_command
Used by `it`'s main Python module but calling this from within the editor will allow you to test the command argument splitting.
### Q
Quits.
### q
Quits, unless your current buffer is unsaved.
### saved
With no arguments given, flips the buffer's "saved" boolean attribute.
Otherwise, sets the buffer's "saved" attribute to the first argument or errors if multiple arguments given.
### version
Prints the versions of given modules.
If no modules are specified, prints the version of module "it".
## Making new commands
Making new commands is very easy.
Read `buffer.py` and `it.py` (<100 LOC total).

11
Wip/it/bang.py Normal file
View File

@@ -0,0 +1,11 @@
import subprocess
def main(buffer, command):
if len(command) == 1:
print("?")
else:
try:
print("[%d]" % subprocess.run(command[1:]).returncode)
except Exception as err:
print("%s" % str(err))
return buffer

74
Wip/it/buffer.py Normal file
View File

@@ -0,0 +1,74 @@
#!/usr/bin/env python3
import importlib
class Buffer: # all the information about the current file
def carat(self):
return self.index
def dollar(self):
return self.length() - 1 + self.index
# Rather than get the content as it's presented in the buffer object
# (as one big string), get it as a list.
def content_list(self):
return self.content.rstrip(self.delimiter).split(self.delimiter)
# Build a string with the same format as the buffer.content and set the
# buffer.content to that string, from the kind of list output by
# buffer.content_list().
# buffer.content_set_list(buffer.content_list()) is an expensive nop.
def content_set_list(self, content_as_list):
content = ""
for line in content_as_list:
content += line + self.delimiter
self.content = content
return None
# this is really bad because any module can call import_module_ just as
# easily as any other. so malicious modules that, say, take 'q' and
# make it upload a file to some external server before exiting would be
# super easy to make.
# the solution I see is OS-level permissions but this needs to be
# talked about like all the time if this tool gets popular
# [why would it?] lest some fool runs a zelda.sh script that changes
# ~/src/it/w.py and doesn't realize in time
def import_module_(self, name):
try:
self.modules[name] = importlib.import_module(name)
except (ModuleNotFoundError, TypeError) as err:
print(err)
return False
else:
return True
def length(self):
return self.content.count(self.delimiter)
def __init__(self):
self.content = "" # content of the file
self.delimiter = "\n" # line delimiter
self.env = {} # configuration dictionary
self.filename = "" # name of where we'll save the file
self.index = 0 # indexing of dot
self.dot = self.index - 1 # invalid position to start
self.modules = {} # see it.py
self.saved = 1 # is buffer saved?
def main(buffer, command):
if len(command) == 1:
command += list(vars(buffer))
for attrib in command[1:]:
if attrib in list(vars(buffer)):
val = vars(buffer)[attrib]
# so self.modules shows as <class 'dict'>
if not(type(val) is int or type(val) is str):
val = str(type(val))
# special case usually for self.delimiter
elif val == "\n":
val = "<newline>"
# only affects it if type(val) is int
else:
val = str(val)
print("%s:\t%s" % (attrib, val))
else:
print("No attribute: %s\n" % attrib, end='')
return buffer

10
Wip/it/config.py Normal file
View File

@@ -0,0 +1,10 @@
def main(buffer, command):
# hard-coded for consistency across multiple people's configs
config_delimiter = "\t"
for i in range(len(buffer.content_list())):
line = buffer.content_list()[i].split(config_delimiter)
if len(line) != 2:
print("%s: %d: Bad column quantity" % (command[0], i+buffer.index))
else:
buffer.env[line[0]] = line[1]
return buffer

20
Wip/it/dot.py Normal file
View File

@@ -0,0 +1,20 @@
def main(buffer, command):
if len(command) == 2 and (command[1].isdigit() or command[1] in {"^","$"}):
if command[1].isdigit():
dot = int(command[1])
elif command[1] == "^":
dot = buffer.carat()
elif command[1] == "$":
dot = buffer.dollar()
elif len(command) == 3 and command[1] in {"+","-"} and command[2].isdigit():
if command[1] == "+":
dot = buffer.dot + int(command[2])
elif command[1] == "-":
dot = buffer.dot - int(command[2])
if not("dot" in locals()) or dot < buffer.carat() or dot > buffer.dollar():
print("?")
else:
buffer.dot = dot
return buffer

4
Wip/it/exit.py Normal file
View File

@@ -0,0 +1,4 @@
import sys
def main(buffer, command):
sys.exit(0)

8
Wip/it/f.py Normal file
View File

@@ -0,0 +1,8 @@
def main(buffer, argv):
if len(argv) > 2:
print("?")
elif len(argv) == 1:
print(buffer.filename)
else:
buffer.filename = argv[1]
return buffer

13
Wip/it/get_command.py Normal file
View File

@@ -0,0 +1,13 @@
from parse_command import parse_command
def get_command(prompt):
try:
return parse_command(input(prompt))
except KeyboardInterrupt: # bastard behavior from ed
pass
except EOFError:
return 0
def main(buffer, command):
print("Command returned as %s" % get_command("Input command (won't be executed): "))
return buffer

3
Wip/it/hello_world.py Normal file
View File

@@ -0,0 +1,3 @@
def main(buffer, command):
print("Hello, world!")
return buffer

31
Wip/it/i.py Normal file
View File

@@ -0,0 +1,31 @@
def main(buffer, command):
if len(command) > 1:
print("?")
return buffer
i = []
while True:
try:
line = input()
# unintuitive behavior from ed
except KeyboardInterrupt:
print("?")
return buffer
except EOFError:
break
if line == ".":
break
i.append(line)
if buffer.dot < buffer.index:
buffer.content_set_list(i)
else:
buffer.content_set_list(
buffer.content_list()[:buffer.dot]
+ i
+ buffer.content_list()[buffer.dot:]
)
buffer.dot += len(i)
return buffer

38
Wip/it/it Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/env python3
import sys
from buffer import Buffer
from get_command import get_command
def version():
print("it.py line editor; ALPHA 2021")
return None
def main(buffer, supplied_command):
if supplied_command != [] and len(supplied_command) > 1:
command = supplied_command[1:]
else:
command = get_command("")
while True:
# EOFError in get_command(); ^D
if command == 0:
break
if command == []:
continue
if command[0] in buffer.modules.keys() or buffer.import_module_(command[0]):
buffer = buffer.modules[command[0]].main(buffer, command)
if type(buffer) is int:
break
command = get_command("")
return buffer
if __name__ == "__main__":
buffer = main(Buffer(), [])
if type(buffer) is int:
sys.exit(buffer)
else:
sys.exit(0)

8
Wip/it/load_module.py Normal file
View File

@@ -0,0 +1,8 @@
def main(buffer, command):
if len(command) == 1:
print("?")
else:
for module in command[1:]:
if buffer.import_module_(module):
print("Loaded %s" % module)
return buffer

7
Wip/it/p.py Normal file
View File

@@ -0,0 +1,7 @@
def main(buffer, command):
if len(command) < 1 or len(command) > 2:
if buffer.dot < buffer.index:
buffer.content = i
buffer.dot += len(i)
return buffer

65
Wip/it/parse_command.py Normal file
View File

@@ -0,0 +1,65 @@
#!/usr/bin/env python3
import sys
def parse_command(command):
casesensitive = True
escapes = {"\\"}
quotes = {"'", '"'}
spaces = {" ", "\t"}
command = command.strip()
in_quotes = 0
word = ""
parsed_command = []
for i in range(len(command)):
# if this char is a quote char
# , we're in quotes
if ((command[i] in quotes)
and in_quotes == 0
and (i == 0
or (i > 0 and not(command[i-1] in escapes)))):
in_quotes = command[i]
# if this char matches the char by which we're in quotes
# , we're not in quotes
elif (command[i] == in_quotes
and (i > 0 and not(command[i-1] in escapes))):
in_quotes = 0
# if this char is an arg delimiter
# and we're not in quotes
# and the last char isn't an escape
# , this word is an argument
elif (command[i] in spaces and in_quotes == 0
and (i > 0 and not(command[i-1] in escapes))):
parsed_command += [word]
word = ""
elif (not(command[i] in escapes) or (i == len(command) - 1)
or not(command[i+1] in spaces + quotes)):
word += command[i]
parsed_command += [word]
return [] if parsed_command == [''] else parsed_command
def main(*args):
while True:
try:
command = input()
except:
break
if command == ".":
break
command = parse_command(command)
for i in range(len(command)):
print("\t%d:\t%s" % (i, command[i]))
return 0 if len(args) != 2 else args[0]
if __name__ == "__main__":
sys.exit(main())

8
Wip/it/q.py Normal file
View File

@@ -0,0 +1,8 @@
from sys import exit
def main(buffer, argv):
if not(buffer.saved):
print("?")
else:
buffer = 0
return buffer

15
Wip/it/saved.py Normal file
View File

@@ -0,0 +1,15 @@
def main(buffer, command):
if len(command) > 2:
print("?")
elif len(command) == 2:
if command[1].isdigit():
buffer.saved = int(command[1])
elif command[1].lower() in {"true","false"}:
buffer.saved = command[1].lower == "true"
else:
print("?")
else:
buffer.saved = not(buffer.saved)
print("Buffer marked as %sSAVED" % ("" if buffer.saved else "NOT "))
return buffer

16
Wip/it/version.py Normal file
View File

@@ -0,0 +1,16 @@
def version():
print("it.py version querying; ALPHA 2021")
return None
def main(buffer, command):
if len(command) > 1:
fetching = command[1:]
else:
fetching = ["it"]
for module in fetching:
if module in list(buffer.modules) or buffer.import_module_(module):
try:
buffer.modules[module].version()
except AttributeError as err:
print(err)
return buffer

47
Wip/levenshtein.c Normal file
View File

@@ -0,0 +1,47 @@
#include <stdio.h>
#include <stddef.h>
#include <sysexits.h>
#include <unistd.h>
#include "putd.c"
/* this helped a LOT:
* https://medium.com/@ethannam/understanding-the-levenshtein-distance-equation-for-beginners-c4285a5604f0
*/
int
levenstein(char *a, char *b){
return 100;
size_t i;
size_t j;
int *m;
size_t s_a;
size_t s_b;
for(s_a = 0; a[s_a] != '\0'; ++s_a);
for(s_b = 0; b[s_b] != '\0'; ++s_b);
/* Levenshtein formula using 2d matrix */
int m[s_a][s_b];
for(i = 0; i < s_a; ++i) /* iterate over a */
for(j = 0; j < s_b; ++j) /* iterate over b */
//m[i][j]
;
}
int main(int argc, char *argv[]){
size_t i;
if(argc != 3){
write(1, "Usage: ", 7);
if(argv[0] != NULL){
for(i = 0; argv[0][i] != '\0'; ++i);
write(1, argv[0], i);
}else
write(1, "levenshtein", 11);
write(1, " [word] [word]\n", 15);
return EX_USAGE;
}
// putd(levenstein(argv[1], argv[2]));
putd(10);
return 0;
}

16
Wip/libcards/libcards.c Normal file
View File

@@ -0,0 +1,16 @@
#include "libcards.h"
int
card_color(int card){
return card < CARD_HEART_A ? -1 : card_rank(card) < CARD_SUIT_CLOVER;
}
int
card_rank(int card){ return card < CARD_HEART_A ? -1 : card % 0x10; }
int
card_suit(int card){
return card < CARD_HEART_A ? -1 : card / CARD_SUIT_HEART;
}

45
Wip/libcards/libcards.h Normal file
View File

@@ -0,0 +1,45 @@
enum{
CARD_SUIT_HEART = 0x1,
CARD_SUIT_TILE = 0x2,
CARD_SUIT_CLOVER = 0x3,
CARD_SUIT_PIKE = 0x4,
CARD_RANK_A = 0x00,
CARD_RANK_2, CARD_RANK_3, CARD_RANK_4,
CARD_RANK_5, CARD_RANK_6, CARD_RANK_7,
CARD_RANK_8, CARD_RANK_9, CARD_RANK_10,
CARD_RANK_J, CARD_RANK_Q, CARD_RANK_K,
CARD_RANK_JOKER /* = 0x0D */
CARD_HEART_A = 0x10,
CARD_HEART_2, CARD_HEART_3, CARD_HEART_4,
CARD_HEART_5, CARD_HEART_6, CARD_HEART_7,
CARD_HEART_8, CARD_HEART_9, CARD_HEART_10,
CARD_HEART_J, CARD_HEART_Q, CARD_HEART_K,
CARD_HEART_JOKER /* = 0x1D */,
CARD_TILE_A = 0x20,
CARD_TILE_2, CARD_TILE_3, CARD_TILE_4,
CARD_TILE_5, CARD_TILE_6, CARD_TILE_7,
CARD_TILE_8, CARD_TILE_9, CARD_TILE_10,
CARD_TILE_J, CARD_TILE_Q, CARD_TILE_K,
CARD_TILE_JOKER /* = 0x2D */
CARD_CLOVER_A = 0x30,
CARD_CLOVER_2, CARD_CLOVER_3, CARD_CLOVER_4,
CARD_CLOVER_5, CARD_CLOVER_6, CARD_CLOVER_7,
CARD_CLOVER_8, CARD_CLOVER_9, CARD_CLOVER_10,
CARD_CLOVER_J, CARD_CLOVER_Q, CARD_CLOVER_K,
CARD_CLOVER_JOKER /* = 0x3D */,
CARD_PIKE_A = 0x40,
CARD_PIKE_2, CARD_PIKE_3, CARD_PIKE_4,
CARD_PIKE_5, CARD_PIKE_6, CARD_PIKE_7,
CARD_PIKE_8, CARD_PIKE_9, CARD_PIKE_10,
CARD_PIKE_J, CARD_PIKE_Q, CARD_PIKE_K,
CARD_PIKE_JOKER /* = 0x4D */
}
int card_color(int card);
int card_rank(int card);
int card_suit(int card);

52
Wip/libshell/getpaths.3 Normal file
View File

@@ -0,0 +1,52 @@
.TH GETPATHS 3
.SH NAME
getpaths \- get an array of the current executable PATHs
.SH LIBRARY
libshell
.SH SYNOPSIS
.In stdlib.h
.In string.h
.In libshell.h
.Ft char **
.Fn getpaths void
.SH DESCRIPTION
.Fn getpaths
returns the system PATHs as an array of null-terminated strings ordered from highest to lowest priority.
The last address in the array is NULL.
The first address in the array, and the array address itself, should be passed to
.Xr free 3
to release the allocated storage when the returned array is no longer needed.
.SH EXAMPLES
To print the current PATHs, from highest to lowest priority:
.Bd -literal -offset indent
#include <stdlib.h>
#include <string.h>
#include <libshell.h>
int main(){
char **paths;
int i;
paths = getpaths();
if(paths == NULL)
exit(EXIT_FAILURE);
for(i = 0; paths[i] != NULL; ++i)
printf("%s\n", paths[i]);
free(*paths);
free(paths);
return EXIT_SUCCESS;
}
.Ed
.SH SEE ALSO
.Xr getenv 3
.SH STANDARDS
.Fn getpaths
is not part of any current standard.
.SH BUGS
Certainly existent but not yet known.

59
Wip/libshell/libshell.c Normal file
View File

@@ -0,0 +1,59 @@
#include "libshell.h"
char **
getpaths(void)
{
char *p;
char **q;
char *path;
size_t path_s;
char *path_temp;
char **paths;
size_t paths_s;
if((path_temp = getenv(PATH_NAME)) == NULL){
errno = ENOMEM; /* Cannot allocate memory */
return NULL;
}
/* How long is path? */
for(path_s = 0; path_temp[path_s] != '\0'; ++path_s);
/* path_s has the size of the path string, not including the null
* terminator */
/* getenv's return value mustn't be modified so copy it into memory we
* control */
if((path = malloc(sizeof(char) * (path_s + 1))) == NULL){
errno = ENOMEM; /* Cannot allocate memory */
return NULL;
}
memcpy(path, path_temp, path_s + 1);
path_temp = NULL;
path_s = 0; /* This shouldn't be necessary anymore */
/* How many paths in $PATH? */
for(paths_s = 1, p = path; *p != '\0'; paths_s += *p++ == PATH_DELIMITER);
if((paths = malloc(sizeof(char *) * (paths_s + 1))) == NULL){
free(path);
errno = ENOMEM; /* Cannot allocate memory */
return NULL;
}
/* Replace all instances of the path delimiter with 0, and then put the
* next path beginning into paths. */
/* This way we can get multiple strings out of one span of memory. */
for(*paths = p = path, q = paths + 1; *p != '\0';)
if(*p++ == PATH_DELIMITER){
*(p - 1) = '\0';
*q++ = p;
}
paths[path_s] = NULL;
/* Because paths[0] will always be path, we can just free(*paths) at
* the end and discard path */
path = NULL;
return paths;
}

11
Wip/libshell/libshell.h Normal file
View File

@@ -0,0 +1,11 @@
#include <errno.h>
#include <stdlib.h> /* getenv(3), malloc(3) */
#include <string.h> /* memcpy(3) */
/* For the shell variable $PATH */
#define PATH_NAME "PATH"
#define PATH_DELIMITER ':'
/* Returns a list of the current paths ordered from first to last priority.
* output must be freed and *output must be freed! */
char **getpaths(void);

View File

@@ -0,0 +1,21 @@
#include "libwakeonlan.h"
/* Returns a byte array of 6 0xFF and 16 repetitions of the 6-byte MAC. */
unsigned int*
magic_packet(unsigned int *mac){
size_t i;
size_t j;
int *retval;
if((retval = malloc(sizeof(unsigned int) * 6 + 6*16)) == NULL)
return NULL;
for(i = 0; i < 6; ++i)
retval[i] = 255;
for(i = 1; i < 16; ++i)
for(j = 0; j < 6; ++j)
retval[i*j] = mac[j];
return retval; /* must be freed */
}

View File

@@ -0,0 +1,4 @@
#include <stddef.h>
#include <stdlib.h>
unsigned int *magic_packet(unsigned int *mac);

24
Wip/lsd/LICENSE Normal file
View File

@@ -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 <http://unlicense.org/>

5
Wip/lsd/README.md Normal file
View File

@@ -0,0 +1,5 @@
# trilsd
*trinity's linux software distribution*
See `/dist/documentation/trilsd.7'.

112
Wip/lsd/dist/Makefile vendored Normal file
View File

@@ -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

65
Wip/lsd/dist/doc/trilsd.7 vendored Normal file
View File

@@ -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)

3
Wip/lsd/dist/mk.conf vendored Normal file
View File

@@ -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

2
Wip/nutshell/Makefile Normal file
View File

@@ -0,0 +1,2 @@
nutshell: nutshell.c nutshell.h nutshell_builtins.c
$(CC) $(CFLAGS) -o nutshell nutshell.c

103
Wip/nutshell/nutshell.c Normal file
View File

@@ -0,0 +1,103 @@
#include <ctype.h> /* isspace(3) */
#include <stddef.h> /* NULL */
#include <stdio.h> /* getc(3) */
#include <stdlib.h> /* getenv(3), rand(3), srand(3) */
#include <string.h> /* strcmp(3) */
#include <sys/wait.h> /* wait(2) */
#include <time.h> /* time(3) */
#include <unistd.h> /* fork(2), write(2) */
#include "nutshell.h"
#include "nutshell_builtins.c"
static int
parse_argv(int *buffer, char **argv, int argc_max){
int i;
int j;
int s;
for(i = 0, j = 0, s = 1; buffer[i] != '\0' && j < argc_max; ++i){
while(isspace(buffer[i])){
s = 1;
buffer[i++] = '\0';
}
if(s)
argv[j++] = buffer + i;
}
return j;
}
static int *
read_buffer(int *buf, size_t buf_s){
int i;
for(i = 0; ; ++i){
/* ..., '\0', buf_s */
/* This isn't perfect but is simple and doesn't matter for
* longer buffers that much. */
if(i == buf_s - 1 - 1){
buf[i] = '\0';
break;
}
buf[i] = getc(stdin);
if(buf[i] == EOF)
return NULL;
else if(buf[i] == '\n'){
buf[i + 1] = '\0';
break;
}
}
return buf;
}
static int
run(int *buf){
int argc;
static char *argv[ARGV_MAX];
int i;
/* get argv and argc */
for(i = 0; i < (sizeof argv) / (sizeof *argv); ++i){
if(argv[i] == NULL)
break;
argv[i] = NULL;
}
argc = parse_argv(buf, argv, (sizeof argv) / (sizeof *argv));
/* builtins get priority */
if((i = isbuiltin(argv[0])) != 0)
return builtins[i - 1].f(argc, argv);
if(state.jailed)
goto runerr;
runerr:
/* This is what busybox ash(1) does. */
return 127;
}
int main(int argc, char *argv[]){
static int buf[BUF_MAX];
static char prompt[] = DEFAULT_PROMPT;
builtin_init(0, empty_argv);
for(;;){
fprintf(stdout, "%s", prompt);
if(read_buffer(buf, (sizeof buf)/(sizeof *buf)) == NULL){
fprintf(stdout, "EOF\n");
state.status = 0;
break;
}
state.status = run(buf);
}
return state.status;
}

15
Wip/nutshell/nutshell.h Normal file
View File

@@ -0,0 +1,15 @@
/* conservative defaults */
#define ARGV_MAX 10
#define BUF_MAX 100
#define DEFAULT_PROMPT "^_^?: "
char *empty_argv[1] = { NULL };
struct {
int jailed;
int status;
}state = {
0,
0
};

View File

@@ -0,0 +1,104 @@
#define NETHACK_NAME "nethack"
int builtin_builtin (int, char **);
int builtin_escape (int, char **);
int builtin_init (int, char **);
int builtin_jail (int, char **);
int builtin_nethack (int, char **);
int builtin_reassure (int, char **);
int builtin_status (int, char **);
struct {
char *name;
int (*f)(int, char **);
}builtins[] = {
/* guaranteed to exist */
{"builtin", builtin_builtin},
{"init", builtin_init},
/* optional additions */
{"escape", builtin_escape},
{"jail", builtin_jail},
{"nethack", builtin_nethack},
{"status", builtin_status}
};
int
isbuiltin(char *s){
int i;
for(i = 0; i < (sizeof builtins) / (sizeof *builtins); ++i)
if(strcmp(builtins[i].name, s) == 0)
return i + 1;
return 0;
}
int
builtin_builtin(int argc, char **argv){
int i;
if(argc < 2){
fprintf(stderr, "needs argument(s)\n");
return 1;
}
++argv;
while(*argv != NULL)
if(!isbuiltin(*argv))
return 1;
return 0;
}
int
builtin_escape(int argc, char **argv){
char *s;
if((s = getenv("SHELL")) == NULL){
fprintf(stdout, "$SHELL seems to be empty. This is an OS error.\n");
}else if(fork() == 0)
execl(s, s, NULL);
else
wait(NULL);
return 0;
}
int
builtin_init(int argc, char **argv){
srand(time(NULL));
return 0;
}
int
builtin_jail(int argc, char **argv){
printf("%s\n", argv[1]);
if(argv[1] == NULL)
fprintf(stdout, "%d", state.jailed);
else if(strcmp(argv[1], "break") == 0 || strcmp(argv[1], "build") == 0)
state.jailed = (argv[1][1] - 'r') / ('u' - 'r'); /* cheap */
else
return 1;
return 0;
}
int
builtin_nethack(int argc, char **argv){
static char *nethack_name = NETHACK_NAME;
char *a[2];
if(fork() == 0){
a[0] = nethack_name;
a[1] = NULL;
execvp("nethack", a);
}else
wait(NULL);
return 0;
}
int
builtin_status(int argc, char **argv){
fprintf(stdout, "%d", state.status);
return 0;
}

2
Wip/playlist/playlist Normal file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
argv0="$0"; shift; "$argv0"_"$0" "$@"

View File

@@ -0,0 +1,24 @@
#!/bin/sh
while read -r resource
do case "$resource" in
*://*) case "$resource" in # remote
*.m3u) file="$(curl -LO -w '%{filename_effective}' \
"$resource")"
"$0" <"$file" >"$file".tar
printf '%s.tar\n' "$file"
;;
*) youtube-dl -f bestaudio "$resource" --id \
&& youtube-dl --get-id "$resource" \
| xargs printf '%s.*\n' \
|| curl -LO -w '%{filename_effective}' \
"$resource"
;;
esac ;;
*.m3u) "$0" <"$resource" >"$resource".tar
printf '%s.tar\n' "$resource"
;;
*) printf '%s\n' "$resource"
;;
esac
done | xargs tar c

20
Wip/psops/Makefile Normal file
View File

@@ -0,0 +1,20 @@
CFLAGS += -g -I../libpsargs
all: pscat
pscat: pscat.o ../libpsargs/libpsargs.o
$(CC) $(CFLAGS) -o $@ pscat.o ../libpsargs/libpsargs.o
pscat.o: pscat.c psops.c
$(CC) $(CFLAGS) -DPSCAT=1 -c -o $@ pscat.c
pspipe: pspipe.o ../libpsargs/libpsargs.o
$(CC) $(CFLAGS) -o $@ pspipe.o ../libpsargs/libpsargs.o
pspipe.o: pscat.c psops.c
$(CC) $(CFLAGS) -DPSPIPE=1 -c -o $@ pscat.c
../libpsargs/libpsargs.o:
$(MAKE) -C ../libpsargs
.PHONY: all

39
Wip/psops/pscat.1 Normal file
View File

@@ -0,0 +1,39 @@
.TH PSCAT 1
.SH NAME
pscat \- concatenate the output of processes
.SH SYNOPSIS
pscat
"["
.RB [ utility
.RB [ argument... ]]
"]" ...
.SH DESCRIPTION
Pscat executes multiple commands, one after the other.
This allows multiple processes to be piped as one to another program.
.SH DIAGNOSTICS
Pscat will print an error message and exit with the appropriate status from sysexits(3) if executed improperly.
Pscat will exit with the sum of the child processes' exit statuses if run correctly.
.SH BUGS
Pscat's exit status isn't useful when run correctly; there's no way to tell which process failed if one did.
This issue of ergonomics isn't obviously mendable as processes' standard outputs and standard errors are meant to both be conveyed.
If either could be ignored the individual exit statuses could simply be printed.
.PP
Pscat's function is redundant to the sh(1) construct
.RB { utility ; utility ;}
- this is a feature, not a bug.
.PP
pscat [ cat | cat ] will pipe "pscat [ cat" into "cat ]", which is a potentially unexpected result of a command.
.SH COPYRIGHT
Public domain.

33
Wip/psops/pscat.c Normal file
View File

@@ -0,0 +1,33 @@
#include <errno.h> /* errno */
#include <stdio.h> /* fprintf(3), stderr, "psops.c" */
#include <string.h> /* strerror(3) */
#include <sysexits.h> /* EX_OSERR, "psops.c" */
#include <unistd.h> /* execvp(3) */
#include <sys/types.h> /* <sys/wait.h> */
#include <sys/wait.h> /* wait(2) */
#include "libpsargs.h" /* corresponding_arg(3), "psops.c" */
static char *program_name = "pscat";
int
f(char **argv){
int child;
char **corr;
*(corr = corresponding_arg(argv)) = NULL;
switch(fork()){
case -1:
fprintf(stderr, "%s: %s\n", program_name, strerror(errno));
return EX_OSERR;
case 0: execvp(argv[1], argv+1);
default:
wait(&child);
argv = corr;
return *++argv == NULL
? WIFEXITED(child) * WEXITSTATUS(child)
: f(argv);
}
}
#include "psops.c"

20
Wip/psops/psops.c Normal file
View File

@@ -0,0 +1,20 @@
/* #include <stdio.h> /* fprintf(3), stderr */
#ifndef EX_USAGE
# define EX_USAGE 64 /* NetBSD sysexits(3) compat */
#endif
/* #include "libpsargs.h" /* check_arg(3) */
int main(int argc, char *argv[]){
if(argc != 0)
program_name = argv[0];
if(check_arg(++argv) == 0){
fprintf(stderr,
"Usage: %s \"[\" [utility [argument...]] \"]\" ...\n",
program_name
);
return EX_USAGE;
}else return f(argv);
}

53
Wip/psops/pspipe.c Normal file
View File

@@ -0,0 +1,53 @@
#include <errno.h> /* errno */
#include <stdio.h> /* fprintf(3), stderr, "psops.c" */
#include <string.h> /* strerror(3) */
#include <sysexits.h> /* EX_OSERR */
#include <unistd.h> /* execvp(3) */
#include <sys/types.h> /* <sys/wait.h> */
#include <sys/wait.h> /* wait(2) */
#include "libpsargs.h" /* corresponding_arg(3), "psops.c" */
static char *program_name = "pspipe";
/* At the start of the loop argv[0] is { '[', '\0' } and file descriptor 0 is
* the intended standard input */
int
f(char **argv){
static int child;
char **corr;
int fd[2];
int r;
*(corr = corresponding_arg(argv)) = NULL;
if(corr[1] != NULL){
if(pipe(fd) != 0){
fprintf(stderr,
"%s: %s: %s\n",
program_name, argv[1], strerror(errno)
);
return EX_OSERR;
}
if((r = fork()) == -1){
fprintf(stderr, "%s: %s\n",
program_name, strerror(errno)
);
return EX_OSERR;
}
if(r == 0)
dup2(fd[0], 0);
else
dup2(fd[1], 1);
close(fd[1]);
close(fd[0]);
if(r == 1)
execvp(argv[1], argv+1);
}
argv = corr;
return *++argv == NULL
? WEXITSTATUS(child)
: f(corr + 1);
}
#include "psops.c"

37
Wip/rss/pig.md Normal file
View File

@@ -0,0 +1,37 @@
# pig\_birth
Initializes the pig.
# pig\_feed
Refreshes all the feed in the pigpen.
# pig\_fetch
Fetches the feed for the pigpen.
Not intended to be called on its own.
# pig\_latin
Prints internal pig details for a given feed file.
# pig\_name
Prints the file name for a given pig feed.
# pig\_pen
Prints the location of the pigpen, which houses all stowed pig feed.
A given feed will be stored as `"$(pig_pen)/$(pig_name)`.
# pig\_recall
Prints the contents of a given feed URL.
If the URL isn't already stowed, stows it before printing.
# pig\_stow
Stows fetched feed in the pigpen.

19
Wip/rss/pig_birth Normal file
View File

@@ -0,0 +1,19 @@
#!/bin/sh
set -e
argv0="$0"
depend(){
if ! command -v "$1" >/dev/null 2>&1; then
printf "%s: %s: Could not find dependency.\n" "$argv0" "$1" \
1>&2
exit 69 # sysexits(3) EX_UNAVAILABLE
fi
return 0
}
depend curl
depend jq
depend xq
mkdir "$(pig_pen)"

7
Wip/rss/pig_feed Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
for file in "$(pig_pen)"/*; do
pig_latin "$file" \
| jq '.feed_url' \
| xargs pig_stow &
done

3
Wip/rss/pig_fetch Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
curl -so - -- "$1"

10
Wip/rss/pig_latin Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/sh
while str isvalue "$1"; do
case "$1" in
*xml)
xq '.feed.pig' <"$1" ;;
*json)
jq '.feed.pig' <"$1" ;;
esac
done

4
Wip/rss/pig_name Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
printf "%s\n" "$1" \
| tr -cd '[:alnum:]'

15
Wip/rss/pig_pen Executable file
View File

@@ -0,0 +1,15 @@
#!/bin/sh
set -e
str isvalue "$1" \
&& printf "Usage: %s\n" "$0" 1>&2 \
&& exit 64 \
|| str isvalue "$PIGPEN" \
&& printf "%s\n" "$PIGPEN" \
&& exit 0 \
|| str isvalue "$XDG_CONFIG_HOME" \
&& printf "%s\n" "$XDG_CONFIG_HOME" \
&& exit 0 \
|| printf "%s/.pigpen\n" "$HOME" \
&& exit 0 \
|| exit 1

7
Wip/rss/pig_recall Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
filename="$(pig_pen)/$(pig_name "$1")"
test -e "$filename" || pig_stow "$1"
cat "$filename"

18
Wip/rss/pig_stow Executable file
View File

@@ -0,0 +1,18 @@
#!/bin/sh
set -e
while str isvalue "$1"; do
pig_fetch "$1" | xq -x "$(
printf '.
* { feed: { pig: {
feed_url: "%b",
pet_sound: "oink",
stow_date: "%b",
version: "0"
} } }' "$1" "$(date '+%Y-%m-%dT%T')"\
| tr -d '[:space:]' \
)" >"$(pig_pen)/$(pig_name "$1")"
shift
done

182
Wip/rss/youtube Executable file
View File

@@ -0,0 +1,182 @@
#!/bin/sh
set -e
argv0="$0"
PIGPEN="$(pig_pen)"
latin(){
case "$1" in
*json) jq '.feed.pig' <"$1" ;;
*xml) xq '.feed.pig' <"$1" ;;
esac
}
list_channels(){
pscat \
[ sh -c "for file in \"$PIGPEN\"/*.xml; \
do xq '{(.feed.link[0].\"@href\"): .feed.title}' \"\$file\"; \
done 2>/dev/null" ] \
[ sh -c "for file in \"$PIGPEN\"/*.json; \
do jq '{(.feed.link[0].\"@href\"): .feed.title}' \"\$file\"; \
done 2>/dev/null" ] \
[ printf "\n" ] \
| sed \
-e '/{/d' \
-e '/}/d' \
-e 's/^ \"//g' \
-e 's/\": \"/ /g' \
-e 's/\,$//g' \
-e 's/\"$//g'
}
list_videos(){
file="$(printf "$PIGPEN"/$( \
list_channels \
| sed "/$1/q" \
| tail -n 1 \
| cut -f 1 \
| xargs pig_name \
)*)"
case "$file" in
*json)
jq \
'reduce .feed.entry[] as $item (
{};
. + { ($item.link."@href"): $item.title }
)' "$file"
;;
*xml)
xq \
'reduce .feed.entry[] as $item (
{};
. + { ($item.link."@href"): $item.title }
)' "$file"
;;
*)
printf "No file found!\n" 1>&2
true
;;
esac | sed \
-e '1d' \
-e '$d' \
-e 's/\": \"/ /g' \
-e 's/^ \"//g' \
-e 's/\,$//g' \
-e 's/\"$//g' # this is really hacky
}
stow(){
name="$PIGPEN/$(pig_name "$1")"
pig_fetch "$1" | xq "$(
date '+%Y-%m-%dT%T' \
| xargs printf '
. * { feed: { pig: {
feed_url: "%b",
pet_sound: "choo",
stow_date: "%b",
version: "0"
} } }' "$1" \
)" >"$name.json"
rm -f "$name.xml"
}
watch(){
youtube-dl -F "$1"
printf "Pick a format [22]: "
input="$(head -n 1 | tr -d '\n')"
str isalnum "$input" \
&& str isdigit $input \
|| input=22 \
&& youtube-dl -f $input "$1" -o - \
| mpv -
}
usage(){
printf "\
Usage: %s
list_channels
list_videos [channel name]
listen [video URL]
refresh (channel name...)
subscribe [channel URL...]
watch [video URL]
watch_latest [channel name]
" "$argv0" 1>&2
}
case "$1" in
list_channels)
! str isvalue "$2" \
|| usage
list_channels
;;
list_videos) # do something with youtube-dl?
list_videos "$2"
;;
listen)
str isvalue "$2" \
|| usage
while str isvalue "$2"
do youtube-dl "$2" -f bestaudio -o - \
| mpv -
shift
done
;;
refresh)
if ! str isvalue "$2"
then for file in "$PIGPEN"/*
do stow "$( \
latin "$file" \
| jq -r '.feed_url' \
)"
done
else
while str isvalue "$2"
do stow "$( \
latin "$( \
list_channels \
| grep "$2" \
| cut -f 2 \
)" | jq '.feed_url' \
)"
shift
done
fi
;;
subscribe)
str isvalue "$2" \
|| usage
while str isvalue "$2"
do stow "http://www.youtube.com/feeds/videos.xml?channel_id=$(
youtube-dl \
--get-filename \
--playlist-items 1 \
-o '%(channel_id)s' \
"$2" \
)"
shift
done
;;
watch) # needs work
str isvalue "$2" \
|| usage
while str isvalue "$2"
do watch "$2"
done
;;
watch_latest)
str isvalue "$2" \
|| usage
watch "$( \
list_videos "$2" \
| head -n 1 \
| cut -f 1 \
)"
;;
*) usage ;;
esac
exit 0

107
Wip/runlength.c Normal file
View File

@@ -0,0 +1,107 @@
#include <ctype.h> /* isdigit(3) */
#include <stdio.h> /* fprintf(3), getc(3), putc(3) */
#include <stdlib.h> /* stdin, stderr, stdout */
#include <sysexits.h> /* EX_DATAERR, EX_OK */
/* Unicode compatibility coming someday */
#define GETC getc
#define PUTC putc
#define NUMBER_TERMINATOR '*'
/* syntax error if a decoding file ends with [char][char] */
/* if(STRICT) just print it out */
#define STRICT 0
static int decode(FILE *input, FILE *output){
int c[2];
unsigned int num;
enum{NUMBER_PARSING = 1} state;
c[0] = EOF;
/* reading -> (current char == prev char)> number parsing -> reading */
while((c[1] = GETC(input)) != EOF)
if(state == NUMBER_PARSING){
if(isdigit(c[1]))
num = num * 10 + c[1] - '0';
else if(c[1] == NUMBER_TERMINATOR){
for(; num > 0; --num)
PUTC(c[0], output);
c[0] = EOF; c[1] = EOF;
state = 0;
}else
return EX_DATAERR;
}else if(c[1] == c[0]){
num = 0;
state = NUMBER_PARSING;
}else{
if(c[0] != EOF)
PUTC(c[0], output);
c[0] = c[1];
}
if(state == NUMBER_PARSING && !STRICT)
/* it doesn't make sense to put this in a loop */
{ PUTC(c[0], output); PUTC(c[0], output); }
else if(state == NUMBER_PARSING)
return EX_DATAERR;
else if(c[0] != EOF)
PUTC(c[0], output);
return EX_OK;
}
static int encode(FILE *input, FILE *output){
int c[2];
unsigned int num;
enum{COUNTING = 1} state;
/* It was more fun to use gotos than to use sane structure. */
for(c[0] = EOF, num = 2, state = 0; ;)
if((c[1] = GETC(input)) == EOF){
if(state == COUNTING)
goto dump;
else
goto place;
}else if(state == COUNTING){
if(c[1] != c[0]){
dump: PUTC(c[0], output);
fprintf(output,
"%d%c",
num, NUMBER_TERMINATOR
);
num = 2;
state = 0;
goto next;
}else
++num;
}else if(c[1] == c[0])
state = COUNTING;
else{ /* c[1] != c[0] */
if(c[0] != EOF) /* c[0] will be EOF at first */
place: PUTC(c[0], output);
next: if(c[1] == EOF)
return EX_OK;
c[0] = c[1];
}
}
int main(int argc, char *argv[]){
int r;
if(argc != 1){
fprintf(stderr,
"Usage: %s\n",
argv[0] == NULL ?
(f == decode ? "decode" : "encode")
: argv[0]
);
return EX_USAGE;
}
if((r = f(stdin, stdout)) == EX_DATAERR)
fprintf(stderr, "%s: syntax error.\n", argv[0]);
return r;
}

112
Wip/substitute.c Normal file
View File

@@ -0,0 +1,112 @@
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "liberror.h"
void
exhaust_buffer(char *b, size_t s){
size_t i;
for(i = 0; i < s; ++i)
if(b[i] != 0)
putc(b[i], stdout);
free(b);
return;
}
void
print_stdin(void){
char c;
while((c = getc(stdin)) != EOF)
putc(c, stdout);
return;
}
void
substitute(char *phrase, char *substitution, bool exit_on_first, char *name){
char *b = (char *)calloc(strlen(phrase)+1, sizeof(char));
size_t i;
if(b == NULL)
error(name, ALLOCATION_ERROR);
while((b[strlen(phrase)-1] = getc(stdin)) != EOF){
for(i = 0;
b[i] == phrase[i]
&& b[i] != 0
&& phrase[i] != 0;
++i);
if(i == strlen(phrase)){
fputs(substitution, stdout);
for(i = 0; i < strlen(phrase);)
b[i++] = 0;
if(exit_on_first){
exhaust_buffer(b, strlen(phrase)+1);
print_stdin();
}
}else
putc(*b, stdout);
/* There's a more efficient way to maintain a buffer here,
* where I keep an unordered string of chars and form an
* ordered string when I need to check against the phrase
* to match. However it's math-intensive, which sucks not just
* for a self-taught lamer but in general in regards to muh
* simplicity, and the math undercuts the performance gain
* from avoiding touching memory. Also, come on, you're never
* gonna have a phrase longer than 100 bytes! Who cares?! */
for(i = 0; i < strlen(phrase); ++i)
b[i] = b[i+1];
}
exhaust_buffer(b, strlen(phrase)+1);
}
void
usage(char *name){
fprintf(stdout, "Usage: %s (-fhr) [phrase] [substitution]\n", name);
exit(1);
}
int main(int argc, char *argv[]){
extern char *optarg;
extern int optind;
bool exit_on_first = 0;
char c;
char *argv0 = argv[0];
bool regex_mode = 0;
while((c = getopt(argc, argv, "fhr")) != -1){
switch(c){
/* -f exists because there exist uses of `sed 's/foo/bar/'`
* without the trailing `g` for global substitution that
* would be borked if made global. Perhaps there are other ways
* to do so that mean that this option doesn't need to be
* implemented, but it's kind of easy to just add so
* whatever. */
case 'f': exit_on_first = 1;
case 'h': usage(argv0);
/* By default regex is not parsed; this is because regular
* expressions are not known to the GENERAL user. The kind of
* user that uses this utility /does/ know regex, but the kind
* of user this utility targets does not, so don't implement
* potentially undesirable functionality by default.
* If you know regex you know how to look up a manpage. */
case 'r':
regex_mode = 1;
break;
case '?': default: usage(argv0);
}
}
argc -= optind;
argv += optind;
if(argc < 2 || argc > 3)
usage(argv0);
if(regex_mode == 0)
substitute(argv[0], argv[1], exit_on_first, argv0);
else
{ printf("Not implemented.\n"); exit(1); }
// substitute_regex(argv[0], argv[1], exit_on_first, argv0);
return 0;
}

13
Wip/sysexits/Makefile Normal file
View File

@@ -0,0 +1,13 @@
TARGETS = sysexits sysexits.h
CFLAGS = -I..
all: $(TARGETS)
clean:
rm -f $(TARGETS)
%: %.c
$(CC) $(CFLAGS) -o $@ $@.c
sysexits.h: sysexits
./sysexits >sysexits.h

182
Wip/sysexits/sysexits.c Normal file
View File

@@ -0,0 +1,182 @@
#include <stdio.h>
#include <unistd.h>
#include "arraylen.h"
/* Thanks to u/smcameron on Reddit. */
#define TAB_WIDTH 8
/* Changing ENUM to DEFINE will make this output the traditional BSD header
* verbatim, without copyright notice. I don't have any idea if that's a
* copyright violation, but let's keep this as ENUM to skirt by that little
* technicality.
* I implemented sysexits(3) in the enum method before reading the BSD 4.0
* source to see how they did it. */
#define ENUM 1
static char *program_name = "sysexits";
static const char comment_prefix[] = "/* ";
static const char comment_prefix_ongoing[] = " * ";
static const char comment_suffix[] = " */\n";
static const char header_prefix[] =
"#ifndef _SYSEXITS_H\n"
"#\tdefine _SYSEXITS_H\n"
"enum{\n"
;
/* ASSUMPTIONS:
* - This array is always organized.
* - All characters in descriptions are one space wide.
* - The only whitespace in descriptions is ASCII_SP. */
static const struct {
char *desc;
char *name;
int status;
}sysexits[] = {
/* sysexit descriptions copied from FreeBSD's sysexits(3). */
{ "All is well.", /* except this one */
"EX_OK", 0 },
{ "The command was used incorrectly, e.g., with the wrong number of"
" arguments, a bad flag, a bad syntax in a parameter, or whatever.",
"EX_USAGE", 64 },
{ "The input data was incorrect in some way. This should only be used"
" for user's data and not system files.",
"EX_DATAERR", 65 },
{ "An input file (not a system file) did not exist or was not readable."
" This could also include errors like \"No message\" to a mailer (if it"
" cared to catch it).",
"EX_NOINPUT", 66 },
{ "The user specified did not exist. This might be used for mail"
" addresses or remote logins.",
"EX_NOUSER", 67 },
{ "The host specified did not exist. This is used in mail addresses or"
" network requests.",
"EX_NOHOST", 68 },
{ "A service is unavailable. This can occur if a support program or"
" file does not exist. This can also be used as a catchall message"
" when something you wanted to do does not work, but you do not know"
" why.",
"EX_UNAVAILABLE", 69 },
{ "An internal software error has been detected. This should be limited"
" to non-operating system related errors as possible.",
"EX_SOFTWARE", 70 },
{ "An operating system error has been detected. This is intended to be"
" used for such things as \"cannot fork\", \"cannot create pipe\", or"
" the like. It includes things like getuid returning a user that does"
" not exist in the passwd file.",
"EX_OSERR", 71 },
{ "Some system file (e.g., /etc/passwd, /var/run/utx.active, etc.) does"
" not exist, cannot be opened, or has some sort of error (e.g., syntax"
" error).",
"EX_OSFILE", 72 },
{ "A (user specified) output file cannot be created.",
"EX_CANTCREAT", 73 },
{ "An error occurred while doing I/O on some file.",
"EX_IOERR", 74 },
{ "Temporary failure, indicating something that is not really an error."
" In sendmail, this means that a mailer (e.g.) could not create a"
" connection, and the request should be reattempted later.",
"EX_TEMPFAIL", 75 },
{ "The remote system returned something that was \"not possible\" during a"
" protocol exchange.",
"EX_PROTOCOL", 76 },
{ "You did not have sufficient permission to perform the operation."
" This is not intended for file system problems, which should use"
" EX_NOINPUT or EX_CANTCREAT, but rather for higher level"
" permissions.",
"EX_NOPERM", 77 },
{ "Something was found in an unconfigured or misconfigured state.",
"EX_CONFIG", 78 }
};
static const char header_suffix[] =
"};\n"
"#endif /* ifndef _SYSEXITS_H */\n"
;
static size_t i;
static int findbyint(int status){
for(i = 0; i < ARRAYLEN(sysexits); ++i)
if(sysexits[i].status == status)
return i;
return -1;
}
static void output_comment(int fd, int indentation, int width, char *comment){
size_t word_start;
size_t line_start;
for(i = 0, line_start = 0, word_start = 0; ; ++i)
switch(comment[i]){
case '\0':
while( i - line_start
+ ARRAYLEN(comment_suffix)
+ indentation * TAB_WIDTH
> width){
i = word_start - 2; /* - current char, - space */
write(
fd, comment_prefix_ongoing,
ARRAYLEN(comment_prefix_ongoing)
);
write(fd, comment + line_start, i - line_start);
i += 2; /* + space, + next word char */
write(fd, "\n", 1);
}
write(fd, comment + line_start, i - line_start);
write(fd, comment_suffix, ARRAYLEN(comment_suffix));
break;
}
return;
}
static void output_header(void){
write(1, header_prefix, ARRAYLEN(header_prefix) - 1);
for(i = 0; i < ARRAYLEN(sysexits); ++i){
//output_comment(1, 1 * TAB_WIDTH, 80, sysexits[i].desc);
#ifdef ENUM
fprintf(stdout, "\t%s = %d%s",
sysexits[i].name,
sysexits[i].status,
i < ARRAYLEN(sysexits) - 1 ? ",\n" : "\n"
);
#endif /* ifdef ENUM */
#ifdef DEFINE
fprintf(stdout, "#\tdefine %s %d\n",
sysexits[i].name,
sysexits[i].status
);
#endif /* ifdef DEFINE */
}
fflush(stdout);
write(1, header_suffix, ARRAYLEN(header_suffix) - 1);
}
int main(int argc, char *argv[]){
if(argv[0] == NULL){
argv[0] = program_name;
++argc;
}
output_header();
return 0;
}

152
Wip/tail.c Normal file
View File

@@ -0,0 +1,152 @@
#include <ctype.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "args.h"
#include "libcharin.h"
#include "libstris.h"
#define DEFAULT_LENGTH 10
#define OFLOW(STR) (STR[strlen(STR)-1] != '\n')
#ifndef PAGE_SIZE
# ifndef PAGESIZE
# define PAGE_SIZE 1024
# else
# define PAGE_SIZE PAGESIZE
# endif
#endif
/*
TODO
* fix limits.h stuff; if limits.h isn't on the system define
reasonable limits in its place
* don't use unsafe string functions
* fix bugs
*/
void
tail(FILE *input, FILE *output, int length){
bool loop = 1;
char *lines[length];
size_t ls[length];
int i;
int filelines = 0;
size_t offset = 0;
for(i = 0; i < length; i++){
ls[i] = PAGE_SIZE;
lines[i] = (char *)calloc(ls[i], sizeof(char));
}
i = 0;
while(fgets(lines[i] + offset, ls[i], input)){
if(OFLOW(lines[i])){
offset += ls[i] - 1;
ls[i] += PAGE_SIZE;
/* should be more resilient */
if(realloc(lines[i], ls[i]) == NULL){
fprintf(stderr, "tail: Couldn't re-allocate memory (%d bytes)\n", ls[i] * sizeof(char));
exit(1);
}
continue;
}
offset = 0;
++filelines;
i = (i + 1) % length;
}
for(i = filelines % length; loop || i != filelines % length; i = (i + 1) % length){
if(loop && i == filelines % length)
loop = 0;
printf("%s", lines[i]);
}
/* glitch here when `tail`ing normal files */
for(i = 0; i < length; i++){
free(lines[i]);
}
return;
}
void
usage(char *name){
fprintf(stderr, "Usage: %s [-ht] [-n integer] [file...]\n", name);
exit(1);
}
int
main(int argc, char *argv[]){
char **argsv = getargsv(argc, argv);
char *flags = getflags(argc, argv);
char mode[3] = "rb";
char filepath[NAME_MAX+PATH_MAX];
char *lengthstr;
size_t fplen = NAME_MAX+PATH_MAX;
FILE *input;
FILE *output = stdout;
int argsc = getargsc(argc, argv);
int i;
int length = DEFAULT_LENGTH;
size_t s;
if(charin(flags, 'h'))
usage(argv[0]);
if(charin(flags, 'n')){
lengthstr = getflag(argc, argv, 'n');
if(!strisint(lengthstr) || *lengthstr == '\0')
usage(argv[0]);
else
length = atoi(lengthstr);
}
if(charin(flags, 't'))
/* Explicitly open files as text rather than as binary.
* this changes "rb" to "r". Should have no effect on
* POSIX systems but may change CRLF to just LF with
* MS Windows. I don't know why anyone would need this
* but it's here for those that do. */
mode[1] = '\0';
if(argsc == 0)
tail(stdin, output, length);
else
for(i = 1; i < argsc; ++i){
if(i > 1)
fprintf(output, "\n");
if(!strcmp(argv[i], "-")){
realpath(argv[i], filepath);
input = fopen(argv[i], "r");
if(input == NULL){
fprintf(stderr, "%s: %s: Could not open file for reading\n", argv[0], filepath);
exit(1);
}
}else{
input = stdin;
/* probably safe but could be vulnerable */
/* just making filepath[] = "<stdin>" */
s = strlen("<stdin>") + 1; /* minimum size for filepath */
if(fplen >= s)
strcpy(filepath, "<stdin>");
else if(realloc(filepath, s) == NULL)
fprintf(stderr, "%s: Failed to reallocate path string, using <stdin>\n", argv[0]);
}
fprintf(output, "==> %s <==\n", filepath);
tail(input, output, length);
if(input != stdin && fclose(input) != 0){
fprintf(stderr, "%s: %s: Could not close file. Exiting...\n", argv[0], filepath);
exit(1);
}
}
return 0;
}

41
Wip/tekubi/Makefile Normal file
View File

@@ -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

89
Wip/tekubi/main.ino Normal file
View File

@@ -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 <SPI.h>
#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();
}

17
Wip/ti83/Makefile Normal file
View File

@@ -0,0 +1,17 @@
UNZIP = tar xf
LBLRW_UPSTREAM = https://www.ticalc.org/pub/83plus/asm/programs/lblrw.zip
all: Schedule Zonk
.PHONY: Zonk
Zonk: Zonk.8xp
.PHONY: Schedule
Schedule: LblRW.8xp Schedule.8xp
LblRW.8xp: lblrw.zip
$(UNZIP) lblrw.zip LblRW.8xp
lblrw.zip:
curl -O "$(LBLRW_UPSTREAM)"

11
Wip/ti83/README.md Normal file
View File

@@ -0,0 +1,11 @@
## Schedule
A schedule app for the TI-83/84(+).
### Dependencies
- [LBLWR](https://www.ticalc.org/archives/files/fileinfo/470/47097.html) from [Zeda Thomas](https://github.com/Zeda)
## Zonk
A dungeon simulator.

79
Wip/ti83/schedule.src Normal file
View File

@@ -0,0 +1,79 @@
//Menu
Lbl M
0→Z
Menu("SCHEDULE","VIEW SCHEDULE",A,"EDIT SCHEDULE",B,"QUIT",C
Stop
//View
Lbl A
ClrHome
For(A,1,8
"!D:→Str1
A
Asm(prgmLBLRW
Output(A,1,Ans
End
0
While Ans≠21
getKey
If Ans≠0
Output(8,1,"2ND TO QUIT
End
Goto M
//Edit
Lbl B
ClrHome
Output(1,1,"1-8 TO EDIT
Output(2,1,"OTHERS TO QUIT
0→A
0
While Ans=0
getKey
If Ans=72
7→A
If Ans=73
8→A
If Ans=82
4→A
If Ans=83
5→A
If Ans=84
6→A
If Ans=92
1→A
If Ans=93
2→A
If Ans=94
3→A
End
If A=0
Goto M
ClrHome
Disp "ENTER NEW DATA
Input "",Str1
"D:"+Str1→Str1
A
Asm(prgmLBLRW
ClrHome
Disp "DATA CHANGED!
While Ans≠21
getKey
End
Goto M
//Quit
Lbl C
ClrHome
Stop
//Data
Lbl D
PERIOD ONE
PERIOD TWO
PERIOD THREE
PERIOD FOUR
PERIOD FIVE
PERIOD SIX
PERIOD SEVEN
PERIOD EIGHT

266
Wip/ti83/zonk.src Normal file
View File

@@ -0,0 +1,266 @@
//Initial setup
Disp "NOW LOADING
0→B
0→D
0→E
randInt(0,50)→G
10→H
100→R
0→T
ClrHome
Disp "----------------","ZONK FOR TI-84+","CREATED BY","DEVEN BLAKE 2018","----------------","ENTER A NAME,","MORTAL
Input "> ",Str0
ClrHome
Disp Str0,"PREPARE TO DIE!
Pause
ClrHome
//Scenario chooser
Lbl A
If R=0
Goto Z
randInt(1,10)→D
D+4→E
R-1→R
If remainder(100-R,5)=0 and G>4 and G<99
Goto G
Disp "ROOM",100-R,"HAS
If D=1
Disp "A GOBLIN
If D=2
Disp "AN IMP
If D=3
Disp "A THIEF
If D=4
Disp "A VAMPIRE
If D=5
Disp "A NINJA
If D=6
Disp "ELVIS PRESLEY
If D=7
Disp "YOUR CHILDHOOD","BULLY
If D=8
Disp "A POLITICIAN
If D≥9
Disp "A NAZI
If D=10
Disp "…ZOMBIE!
Pause
If D=3 or D=5 or D=8
Then
Disp "SNEAK ATTACK!!!!"," -01 HP
H-1→H
Pause
End
If H≤1
Goto F
//Battle System
Lbl B
0->B
Disp "YOUR MOVE,",Str0
Input "> ",Str1
If Str1="ATTACK" or Str1="A
1→B
If Str1="MAGIC" or Str1="M
2→B
If Str1="CONFRONT" or Str1="C
3→B
If Str1="RUN" or Str1="R
4→B
If B=0
Disp "ATTACK OR A","MAGIC OR M","CONFRONT OR C","RUN OR R
If B=0
Goto B
//Effect Processor
If B=1
Then
If D<3 or D=6 or D=9
Then
E-1→E
Disp "DID 1 DMG
End
If D=3 or remainder(D,5)=0
Then
E-2→E
Disp "DID 2 DMG
End
If D=4
Then
E-3→E
Disp "DID 3 DMG
End
If D=7 or D=8
Then
0→E
Disp "WOWZERS!
End
End
If B=2
Then
If D=1
Then
E-2→E
Disp "DID 2 DMG
End
If remainder(D,2)=0 and D≠8
Disp "LOL NOTHING
If D=3 or D=7
Then
E-4→E
Disp "DID 4 DMG
End
If D=5
Then
E-5→E
Disp "DID 5 DMG
End
If D=9
Then
0→E
Disp "WOWZERS!
End
End
If B=3
Then
If D<3
Disp "LOL NOTHING
If remainder(D,3)=0 or D=8
Then
0→E
Disp "WOWZERS!
End
If D=4
Then
E-1→E
Disp "DID 1 DMG
End
If remainder(D,5)=0
0→H
If D=7
Then
E-5→E
Disp "DID 5 DMG
End
End
If B=4
Then
If D<4 or D=7
Disp "LOL NOTHING
If remainder(D,2)=0 and D≠2 and D≠10
Then
0→E
Disp "WOWZERS!
End
If remainder(D,5)=0 or D=9
0→H
End
Pause
//Battle Processor
If E>0
Then
If D=1 and G>1
Then
G-2→G
Disp "THEY TOOK 2 GOLD
End
If D=2 and G>0
Then
G-1→G
Disp "THEY TOOK 1 GOLD
End
If T=0 and G≠0 and D=3
Then
G→T
0→G
Disp "TOOK ALL GOLD!
End
If D=4
Then
H-1→H
Disp "THEY SUCKED","YOUR BLOOD","EH EH EHH
End
If D=5
H-1→H
If D=6
Then
G+1→G
H-1→H
Disp "DID DRUGS","GOT CASH
End
If D=7
Then
H-1→H
Disp "TOOK 1 DMG
End
If D=8
Then
H-2→H
Disp "THEY SLEAZED YOU
End
If D>8
Then
If G>3
G-4→G
H-2→H
If D≠10
Disp "UGH NAZIS","YOU'D THINK","WE WON THAT WAR
End
If D=10
Then
H-1→H
Disp "BASICALLY JUST","A ZOMBIE
End
End
If H<1
Goto F
If E<1
T+G→G
If E<1
0→T
If E<1
G+10→G
Pause
//Battle outcome
If E>0
Disp "ENEMY ALIVE
Disp "HEALTH:",H
Disp "GOLD:",G
If E>0
Disp "ENEMY HEALTH:",E
Pause
If T≠0
Disp "THIEF'S LOOT:",T
If E<1
Goto A
Goto B
//Death
Lbl F
Disp "GAME OVER, DUDE
Stop
//Shop
Lbl G
Disp "----------------","STORE OF STORES!","----------------"," 5 GOLD => 1 HP","----------------","BUY
Input Str2
If Str2="Y"
Then
G-5→G
H+1→H
End
If G<5 or Str2≠"Y
Goto A
Goto G
//Win
Lbl Z
Disp "----------------"," YOU WON!","----------------
Pause
Disp "I NEVER EXPECTED","SOMEONE TO","ACTUALLY WIN","THIS GAME,","THANKS FOR","PLAYING"
Pause
ClrHome
Disp "THANKS,",Str0
Stop

16
Wip/todo/design.txt Normal file
View File

@@ -0,0 +1,16 @@
todod - todo daemon
todoctl - todo control
todoctl add [name] [job]
todoctl del/rm/remove [name]
todoctl move/mv [name] {under,above} [name]
/etc/todo.list - todo data
todo stack
top "next job" (above "job after next job")
"job after next job" (under "next job", above "last job")
bottom "last job"
the purpose is to have a job scheduler so you don't have to job && job and wait
and hope for the best. maybe there should also be retry settings. this is
similar to an init system in terms of design but should be simpler and not
handle dependency trees or anything like that

3
Wip/toki/README.txt Normal file
View File

@@ -0,0 +1,3 @@
- move executables somewhere in path
- `$ toki_update` to fetch dictionary
- `$ toki_sitelen` to tokiponize

5
Wip/toki/toki_sitelen Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
set -e
toki_ucsur "$@" | utf8

2
Wip/unicode/1.expected Normal file
View File

@@ -0,0 +1,2 @@
0000000 41 e2 89 a2 ce 91 2e
0000007

3
Wip/unicode/1.test Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
printf '%s\n%s\n%s\n%s\n' U+0041 U+0391 U+002E | ./utf 8 | od -t x1

2
Wip/unicode/2.expected Normal file
View File

@@ -0,0 +1,2 @@
0000000 ed 95 9c ea b5 ad ec 96 b4
0000009

3
Wip/unicode/2.test Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
printf '%s\n%s\n%s\n' U+D55C U+AD6D U+C5B4 | ./utf 8 | od -t x1

2
Wip/unicode/3.expected Normal file
View File

@@ -0,0 +1,2 @@
0000000 e6 97 a5 e6 9c ac e8 aa 9e
0000009

3
Wip/unicode/3.test Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
printf '%s\n%s\n%s\n' U+65E5 U+672C U+8A9E | ./utf 8 | od -t x1

1
Wip/unicode/HACKING Normal file
View File

@@ -0,0 +1 @@
Tests are from RFC3629, section 7.

15
Wip/unicode/Makefile Normal file
View File

@@ -0,0 +1,15 @@
test: utf
sh ../testing/test.sh
utf: utf.o libunicode.o
$(CC) -g -o utf libunicode.o utf.o
libunicode.o:
utf.o: libunicode.h utf.c
$(CC) -I../ascii -c -g -o utf.o utf.c
clean:
rm -f *.o utf
.PHONY: clean test

23
Wip/unicode/libunicode.c Normal file
View File

@@ -0,0 +1,23 @@
#include "libunicode.h"
utf32_t utf8(utf32_t c){
unsigned char n; /* 4 - number of bytes - 1 */
utf8_t r;
if(c > UTF8_MAX) /* return 0 if c exceeds max */
c = 0;
switch(n = (c >= 0x010000) + (c >= 0x0800) + (c >= 0x0080)){
case 3: r = 0xF0 + ((c >> 18) & 0x07); /* 11110xxx */
case 2: r = (r << 8) + (n == 2
? 0xE0 + ((c >> 12) & 0x0F) /* 1110xxxx */
: 0x50 + ((c >> 12) & 0x3F)); /* 10xxxxxx */
case 1: r = (r << 8) + (n == 1
? 0xC0 + ((c >> 6) & 0x1F) /* 110xxxxx */
: 0x50 + ((c >> 6) & 0x3F)); /* 10xxxxxx */
case 0: r = (r << 8) + (n == 0
? (c & 0x7F) /* 0xxxxxxx */
: 0x50 + ((c >> 6) & 0x3F)); /* 10xxxxxx */
}
return r;
}

Some files were not shown because too many files have changed in this diff Show More