1
0

Compare commits

...

13 Commits

Author SHA1 Message Date
DTB
e90d844ff4 2025-04-24 2025-04-24 19:58:09 -06:00
DTB
cba16ff731 convert neovim config to lua 2025-04-18 09:54:56 -06:00
DTB
d3cc5416ab convert nvim config to lua 2025-04-18 09:54:10 -06:00
DTB
f14330ee0f 2025-04-18 2025-04-18 09:53:43 -06:00
DTB
12bd97447b 2025-04-05 2025-04-05 18:18:35 -06:00
DTB
5ca407f1d8 2025-04-01 2025-04-01 19:01:22 -06:00
DTB
6d8d0d8c2d just some comments 2025-03-27 16:32:38 -06:00
DTB
24cb04160a make maintainable in a week 2025-03-27 02:48:51 -06:00
DTB
adbaf11d71 move io and keyval to libio and libkeyval 2025-03-27 02:39:23 -06:00
DTB
db13c085c8 better separation of modules 2025-03-27 02:34:39 -06:00
DTB
591f58d70a status mvp 2025-03-27 02:08:07 -06:00
DTB
9846c7ad27 backlog of changes from the uconsole 2025-03-20 10:04:48 -06:00
DTB
55bb27a1de lots of stuff 2025-03-20 10:04:48 -06:00
73 changed files with 1945 additions and 784 deletions

View File

@@ -15,6 +15,7 @@
* nybbles 4--|4--|4--|4--|4--|4--|
* bits 111111111111111111111111 */
#include <complex.h>
#if __STDC_VERSION__ >= 199901L
/* C99 type definitions */
# include <stdint.h>
@@ -42,6 +43,7 @@ struct Intel4004_State {
Nybble acc; /* Accumulator */
Nybble reg[16]; /* R0 through RF */
Word pc[4]; /* PC0 through PC3 */
Word *cc; /* Current PC */
Byte *rom;
Byte *ram;
};
@@ -117,11 +119,38 @@ enum Intel4004_Instruction {
/* INVALID 0xFF 0b 1111 1111 */
};
#define INTEL4004_THIS_OP (state->rom[*state->cc])
#define INTEL4004_NEXT_OP (state->rom[*state->cc + 1])
#define INTEL4004_INC_OP do{ ++*state->cc; }while(0)
#define INTEL4004_INC2_OP do{ *state->cc += 2; }while(0)
/* <http://e4004.szyc.org/>-style naming */
#define INTEL4004_PL (*state->cc & 0x00F)
#define INTEL4004_PM ((*state->cc & 0x0F0) >> 4)
#define INTEL4004_PH ((*state->cc & 0xF00) >> 8)
/* Also see the Intel MCS-4 Assembly Language Programming Manual (1973). */
/* From the datasheet. */
void Intel4004_RESET(struct Intel4004_State *state){
Nybble i;
state->carry = 0;
state->test = 0;
state->acc = 0;
for(i = 0; i <= (sizeof state->reg) / (sizeof *state->reg); ++i)
state->reg[i] = 0;
for(i = 0; i <= (sizeof state->pc) / (sizeof *state->pc); ++i)
state->pc[i] = 0;
state->cc = &state->pc[0];
return;
}
/* Does nothing. */
void Intel4004_NOP(struct Intel4004_State *state){ /* 0b 0000 0000 */
++*state->pc;
INTEL4004_INC_OP;
return;
}
@@ -141,16 +170,16 @@ void Intel4004_NOP(struct Intel4004_State *state){ /* 0b 0000 0000 */
* If *state->pc & 0x08, a one test flag satisfies the condition. */
void Intel4004_JCN(struct Intel4004_State *state){ /* 0b 0001 CCCC */
*state->pc =
!INTEL4004_JCN_COND_ISINVERT(state->rom[*state->pc])
&& ( (INTEL4004_JCN_COND_ISACCZERO(state->rom[*state->pc])
*state->cc =
!INTEL4004_JCN_COND_ISINVERT(INTEL4004_THIS_OP)
&& ( (INTEL4004_JCN_COND_ISACCZERO(INTEL4004_THIS_OP)
&& state->acc == 0)
|| (INTEL4004_JCN_COND_ISCARRYON(state->rom[*state->pc])
|| (INTEL4004_JCN_COND_ISCARRYON(INTEL4004_THIS_OP)
&& state->carry == 1)
|| (INTEL4004_JCN_COND_ISTESTON(state->rom[*state->pc])
|| (INTEL4004_JCN_COND_ISTESTON(INTEL4004_THIS_OP)
&& state->test == 1))
? state->rom[*state->pc + 1]
: *state->pc + 2;
? state->rom[*state->cc + 1]
: *state->cc + 2;
return;
}
@@ -166,14 +195,13 @@ void Intel4004_JCN(struct Intel4004_State *state){ /* 0b 0001 CCCC */
/* Fetches an immediate byte from ROM. */
void Intel4004_FIM(struct Intel4004_State *state){ /* 0b 0010 RRR0 */
state->reg[INTEL4004_REGPAIR(state->rom[*state->pc])]
= HIGH_NYBBLE(state->rom[*state->pc + 1]);
state->reg[INTEL4004_REGPAIR(INTEL4004_THIS_OP)]
= HIGH_NYBBLE(INTEL4004_NEXT_OP);
state->reg[INTEL4004_REGPAIR(state->rom[*state->pc]) + 1]
= LOW_NYBBLE(state->rom[*state->pc + 1]);
*state->pc += 2;
state->reg[INTEL4004_REGPAIR(INTEL4004_THIS_OP) + 1]
= LOW_NYBBLE(INTEL4004_NEXT_OP);
INTEL4004_INC2_OP;
return;
}
@@ -182,3 +210,37 @@ void Intel4004_SRC(struct Intel4004_State *state){ /* 0b 0010 RRR1 */
void Intel4004_FIN(struct Intel4004_State *state){ /* 0b 0011 RRR0 */
}
/* Loads the immediate value in the low nybble of the opcode into the
* accumulator. */
void Intel4004_LDM(struct Intel4004_State *state){ /* 0b 1101 DDDD */
state->acc = LOW_NYBBLE(INTEL4004_THIS_OP);
INTEL4004_INC_OP;
return;
}
void Intel4004_BBL(struct Intel4004_State *state){ /* 0b 1100 DDDD */
/* <http://e4004.szyc.org/> lists 0b 1100 RRRR, most likely as a typo. I found
* 0b 1100 DDDD on the Intel 4004 datasheet. */
return Intel4004_LDM(state);
}
/* Clears the carry bit. */
void Intel4004_CLC(struct Intel4004_State *state){ /* 0b 1111 0001 */
state->carry = 0;
INTEL4004_INC_OP;
return;
}
/* Clears both the accumulator and the carry bit. */
void Intel4004_CLB(struct Intel4004_State *state){ /* 0b 1111 0000 */
state->acc = 0;
return Intel4004_CLC(state);
}

73
Wip/bitch/gtk4.c Normal file
View File

@@ -0,0 +1,73 @@
#include <gtk/gtk.h>
#define BUF 100
static GtkApplication *app;
static void activate(GtkApplication *app, gpointer user_data);
static void button_pressed(GtkWidget *button, gpointer data);
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;
}
int setup(){
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);
return status;
}

42
Wip/bitch/motif.c Normal file
View File

@@ -0,0 +1,42 @@
#include <Xm/Xm.h>
#include <Xm/PushB.h>
static XtAppContext app_context;
static void activate(void);
static void button_pressed(
Widget w, XtPointer client_data, XmPushButtonCallbackStruct *cbs
);
void setup(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);
}

65
Wip/bitswap/bitswap.c Normal file
View File

@@ -0,0 +1,65 @@
#include <stdio.h> /* fgetc(3), fprintf(3), fputc(3), stderr, stdin, stdout,
* EOF */
#include <sysexits.h> /* EX_OK, EX_USAGE */
#include <unistd.h> /* getopt(3) */
/* untested */
int
usage(char *argv0) {
(void)fprintf(stderr, "Usage: %s\n", argv0);
return EX_USAGE;
}
int main(int argc, char *argv[]){
int c;
{
int c;
while ((c = getopt(argc, argv, "")) != -1) {
switch (c) {
default: return usage(argv[0]);
}
}
}
#if 0
// Swapping algorithm: For example, say c is 0b0101_0101 */
// /* <<< <<<< */
// c <<= 7; /* Now 0b010_1010_1000_0000 */
// /* ^ >^ */
// c |= (c & (1 << 8)) >> 2; /* Now 0b010_1010_1000_0000 */
// /* ^> >>^ */
// c |= (c & (1 << 9)) >> 4; /* Now 0b010_1010_1010_0000 */
// /* ^>> >>>^ */
// c |= (c & (1 << 10)) >> 6; /* Now 0b010_1010_1010_0000 */
// /* ^>>> >>>> ^ */
// c |= (c & (1 << 11)) >> 8; /* Now 0b010_1010_1010_1000 */
// /* ^ >>>> >>>> >^ */
// c |= (c & (1 << 12)) >> 10; /* Now 0b010_1010_1010_1000 */
// /* ^> >>>> >>>> >>^ */
// c |= (c & (1 << 13)) >> 12; /* Now 0b010_1010_1010_1010 */
// /* ^>> >>>> >>>> >>>^ */
// c |= (c & (1 << 14)) >> 14; /* Now 0b010_1010_1010_1010 */
// /* & 0b000_0000_1111_1111 */
// c &= 0xFF; /* Now 0b1010_1010 */
#endif
{
int c;
int i;
while ((c = fgetc(stdin)) != EOF) {
for (c <<= 7, i = 8; i <= 14; ++i)
{ c |= (c & (1 << i)) >> ((i - 7) * 2); }
if (fputc(c, stdout) == EOF)
{ perror(argv[0]); return EX_IOERR; }
}
if (ferror(stdin) != 0) { perror(argv[0]); return EX_IOERR; }
}
return EX_OK;
}

View File

@@ -1,55 +0,0 @@
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'); }

View File

@@ -1,17 +0,0 @@
#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 */

View File

@@ -1,53 +0,0 @@
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;
}

View File

@@ -1,8 +0,0 @@
#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 */

View File

@@ -1,12 +1,26 @@
#include <stdio.h>
#include <stdio.h> /* fprintf(3), stderr */
#include <stdlib.h>
#include <unistd.h> /* getopt(3) */
/* 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. */
static int lines = 10; /* POSIX.1 */
static char *program_name = "head";
int main(int argc, char *argv[]){
char *argv0 = argv[0];
size_t i;
int c;
extern char *optarg;
extern int opterr, optind, optopt;
if(argc > 0)
program_name = argv[0];
while((c = getopt(argc, argv, "n:")) != -1)
switch(c){
case 'n':
break;
default:
#ifdef IGIT /* parse -[digit] options */
#endif /* ifdef IGIT */
usage: fprintf(stderr, "Usage: %s (-n [lines]) (file...)\n",
program_name);
return EX_USAGE;
}

View File

@@ -9,3 +9,5 @@ def main(buffer, command):
except Exception as err:
print("%s" % str(err))
return buffer
bang = main

View File

@@ -3,10 +3,7 @@ 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:]
@@ -21,7 +18,8 @@ def main(buffer, supplied_command):
if command == []:
continue
if command[0] in buffer.modules.keys() or buffer.import_module_(command[0]):
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

View File

@@ -3,57 +3,59 @@
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;
{
char *path_temp;
size_t path_s;
if((path_temp = getenv(PATH_NAME)) == NULL)
goto bail;
/* 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 *path) * (path_s + 1))) == NULL)
goto bail;
memcpy(path, path_temp, path_s + 1);
}
/* 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 */
{
char *p;
char **q;
size_t paths_s;
/* 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);
/* How many paths in $PATH? */
for(paths_s = 1, p = path; *p != '\0'; paths_s += *p++ == PATH_DELIMITER);
if((paths = malloc((sizeof *paths) * (paths_s + 1))) == NULL)
goto bail1;
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;
}
/* 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;
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;
bail1: free(path);
bail: errno = ENOMEM; /* Cannot allocate memory */
return NULL;
}

102
Wip/lsd/Makefile Normal file
View File

@@ -0,0 +1,102 @@
include hyperlinks.mk
all: fhs learn
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"
$(PREFIX)/usr/src/linux: fhs
git clone "$(LINUX_UPSTREAM_GIT)" "$(PREFIX)/usr/src/linux.tmp"
mv "$(PREFIX)/usr/src/linux.tmp" "$(PREFIX)/usr/src/linux"
$(PREFIX)/usr/src/musl: fhs
git clone "$(MUSL_UPSTREAM_GIT)" "$(PREFIX)/usr/src/musl.tmp"
mv "$(PREFIX)/usr/src/musl.tmp" "$(PREFIX)/usr/src/musl"
musl: $(PREFIX)/usr/src/musl
cd "$(PREFIX)/usr/src/musl"
./configure --prefix="$(PREFIX)"
$(MAKE) install
.PHONY: all

4
Wip/lsd/hyperlinks.mk Normal file
View File

@@ -0,0 +1,4 @@
GCC_UPSTREAM_GIT=git://gcc.gnu.org/git/gcc.git
LINUX_UPSTREAM_GIT=git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
MUSL_UPSTREAM_GIT=git://git.musl-libc.org/musl
PKGSRC_UPSTREAM_HTTPS=https://cdn.netbsd.org/pub/pkgsrc/current/pkgsrc.tar.xz

65
Wip/lsd/trilsd.7 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)

8
Wip/rss/Cargo.toml Normal file
View File

@@ -0,0 +1,8 @@
[package]
name = "rss"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -1,37 +0,0 @@
# 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.

View File

@@ -1,19 +0,0 @@
#!/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)"

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,15 +0,0 @@
#!/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

View File

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

View File

@@ -1,18 +0,0 @@
#!/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

9
Wip/rss/src/main.rs Normal file
View File

@@ -0,0 +1,9 @@
use json;
fn feed() {
}
fn stow(title: String) {
}
fn main() {
}

View File

@@ -1,182 +0,0 @@
#!/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

View File

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

View File

@@ -1,6 +1,5 @@
#include <stdio.h>
#include <unistd.h>
#include "arraylen.h"
/* Thanks to u/smcameron on Reddit. */
@@ -12,7 +11,7 @@
* 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
#define DEFINE 1
static char *program_name = "sysexits";

21
Wip/sysexits/sysexits.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef _SYSEXITS_H
# define _SYSEXITS_H
enum{
EX_OK = 0,
EX_USAGE = 64,
EX_DATAERR = 65,
EX_NOINPUT = 66,
EX_NOUSER = 67,
EX_NOHOST = 68,
EX_UNAVAILABLE = 69,
EX_SOFTWARE = 70,
EX_OSERR = 71,
EX_OSFILE = 72,
EX_CANTCREAT = 73,
EX_IOERR = 74,
EX_TEMPFAIL = 75,
EX_PROTOCOL = 76,
EX_NOPERM = 77,
EX_CONFIG = 78
};
#endif /* ifndef _SYSEXITS_H */

View File

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

View File

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

View File

@@ -1,23 +1,22 @@
Comic Book Archives (CB7, CBR, CBZ)
<http://justsolve.archiveteam.org/wiki/Comic_Book_Archive>
<https://en.wikipedia.org/wiki/Comic_book_archive>
A Comic Book Archive is just an archive with a bunch of sequentially-named
images in it which collate ASCIIbetically to the order in which they should be
read. Each image corresponds to a page presented by a comic book reader and a
Comic Book Archive represents a digital comic book.
No guarantees can be made regarding image format, image names (though you can
expect them to match [:digit:]*\..*; that is, a bunch of numbers followed by a
file extension), archive attributes (compression or metadata), or what is in
archives besides the images. In fact, when a comic book only has one image, the
most common type of file in a comic book archive may not be an image at all.
No guarantees can be made regarding image format, image names, archive
attributes (compression or metadata), or what is in archives besides the
images. In fact, when a comic book only has one image, the most common type of
file in a comic book archive may not be an image at all.
The extension corresponds to what type of archive is being used. I haven't seen
an extension that hasn't fit within DOS 8.3, which makes sense as amateur
skiddies and repackers mostly use Windows.
<http://justsolve.archiveteam.org/wiki/Comic_Book_Archive>
<https://en.wikipedia.org/wiki/Comic_book_archive>
Here's a table of Comic Book Archive types. I can't imagine this list is
comprehensive but I can't find more on-line.
____________________
@@ -32,10 +31,12 @@ comprehensive but I can't find more on-line.
I normalize the files I get to the following settings:
ARCHIVE: PKzip. DEFLATE algorithm. No other configuration.
ARCHIVE: PKzip. DEFLATE algorithm. No other configuration and no
subdirectories. ($ zip -jZ DEFLATE)
CONTENTS: ONLY images. Whatever encoding in which I found them.
Sequential naming starting from one, with leading zeroes to ensure file
names are all the same length.
names are all the same length. e.g. 5 pages are 1-5.ext, but 15 are
01-15.ext
<https://en.wikipedia.org/wiki/7-Zip>
7-Zip is free and open source. There are a number of implementations and you

View File

@@ -1,6 +1,6 @@
#!/bin/sh
set -e
set -ex
usage(){
printf 'Usage: %s [files...]\n' "$0"
@@ -22,9 +22,10 @@ else trap 'rm -rf "$d"; trap - EXIT; exit' EXIT INT HUP
fi
while test -n "$1"; do
unrar x -op"$d" "$1"
zip -jZ deflate "$1".cbz "$d"/*
rm "$d"/*
# unrar x -op"$d" "$1"
bsdtar xf "$1" -C "$d"
zip -jrZ deflate "$1".cbz "$d"/*
rm -r "$d"/*
shift
done

View File

@@ -10,49 +10,79 @@ usage(){
test -n "$2" \
|| usage
d="$(mktemp -d || printf '%s/.cbzcat' "$HOME/")"
trap 'rm -rf "$d"; trap - EXIT; exit' EXIT INT HUP
mkdir -p "$d"/x
d="$(mktemp -d || printf '%s/.cbzcat\n' "$HOME/")"
if test -n "$DEBUG"; then
printf 'Using temporary directory %s\n' "$d"
set -x
else
trap 'rm -rf "$d"; trap - EXIT; exit' EXIT INT HUP
fi
i=1 # index
il=1 # index length in digits
parallel \
test -e {} \
::: "$@" \
|| usage
for f in "$@"; do
test -e "$f" \
|| usage
parallel --bar \
unzip -qqd "$d/"{#} {} \
::: "$@"
unzip -d "$d"/x "$f"
# num is created by the shell (parallel in this case) before the pipeline is
# run, so we have to compensate for it already being in the directory when the
# files are listed
parallel \
rm -f {}/*.xml \; \
ls {} \
\| grep -v \
-e '^num$' \
\| wc -l \
\>{}/num \; \
printf '0\\n' \
'>>'{}/prevs \; \
::: "$d"/*
rm -f "$d"/x/*.xml
parallel \
test {1/} -lt {2/} \
'&&' dd \
'<'{1}/num \
'>>'{2}/prevs \
'2>'/dev/null \
'||' true \
::: "$d"/* \
::: "$d"/*
for g in "$d"/x/*; do
# if there aren't enough leading zeroes
if ! printf '%s' "$i" \
| wc -c \
| xargs test "$il" =; then
for h in "$d"/*
do test "$h" = "$d"/x \
|| printf '%s\n' "$h" \
| sed 's|[^/]*$|0&|' \
| xargs mv "$h"
done
# update index digit length
il="$(printf '1 + %s\n' "$il" | bc)"
fi
parallel \
\<{}/prevs \
sed 's/\\$/ + /' \
\| tr -d '\n' \
\| sed 's/ + \\$//' \
\| bc \
\>{}/sum \
::: "$d"/*
# move file to indexed position
printf '%s\n' "$g" \
| sed 's|^.*\.||' \
| xargs printf '%s/%s%s\n' "$d" "$i". \
| xargs mv "$g"
false
# increment i
i="$(printf '1 + %s\n' "$i" | bc)"
done
done
parallel \
ls {}/../ \; \
parallel -I [] --arg-sep :::: \
test [] -lt {} \
'&&' '<'[]/num xargs \
printf '%s + ' \
:::: {}/../* \
\| sed 's| + $||' \
\| bc \
\>{}/prevs \
::: "$d"/*
rm -r "$d"/x
zip -Z deflate out.cbz "$d"/*
mkdir "$d"/0
false
parallel --dry-run sh -c "\
for dir in "
zip -Z deflate out.cbz "$d"/0/*
rm -r "$d"

View File

@@ -27,19 +27,12 @@ CFLAGS = \
LDFLAGS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
dmenubar: config.h dmenubar.o drw.h drw.o util.o
@echo dmenu build options:
@echo "CFLAGS = $(CFLAGS)"
@echo "LDFLAGS = $(LDFLAGS)"
@echo "CC = $(CC)"
dmenubar: dmenubar.o drw.h drw.o util.o
$(CC) -o $@ dmenubar.o drw.o util.o $(LDFLAGS)
.c.o:
$(CC) -c $(CFLAGS) $<
config.h:
cp config.def.h $@
clean:
rm -f dmenubar *.o

View File

@@ -1,75 +1,76 @@
/* See LICENSE file for copyright and license details. */
/* This is a hack I did years ago. Fork dmenu and start from there if you can.
* ~ trinity */
#include <locale.h> /* setlocale(3), LC_CTYPE */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strlen(3) */
#include <stdio.h> /* fprintf(3), stderr */
#include <sysexits.h> /* EX_USAGE */
#include <unistd.h> /* getopt(3) */
#include <X11/Xlib.h>
#include <X11/Xlib.h> /* XSupportsLocale(3), Display, Window */
#include <X11/Xutil.h>
#ifdef XINERAMA
# include <X11/extensions/Xinerama.h>
#endif
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
#include <X11/Xft/Xft.h> /* XftColor */
#include "drw.h" /* drw_clr_create(3), drw_create(3), drw_fontset_create(3),
* drw_fontset_getwidth(3), drw_free(3), drw_map(3),
* drw_resize(3), drw_setscheme(3), drw_rect(3), drw_text(3),
* Drw */
/* chars to be allocated for the text displayed in the bar */
#define BUFSIZE 1024
enum { Scheme, SchemeLast }; /* color schemes */
/* enumerated because Suckless has SchemeNorm, SchemeSel, etc.
* should be made into like one char *Scheme[2] */
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define MAX(A, B) ((A) > (B) ? (A) : (B))
static int bh;
static XClassHint ch = {"dmenubar", "dmenubar"};
static Display *dpy;
static Drw *drw;
static char *embed;
static int inputw = 0;
static int lrpad; /* sum of left and right padding */
static int mh;
static int mon = -1;
static int mw;
static Window parentwin;
static Window root;
static Clr *scheme[SchemeLast];
static int screen;
static Window win;
#define BREAK_ON_EOF 0
#define bool char
static struct {
bool topbar; /* -b */
char *bg_hex; /* -B */
bool break_on_eof; /* -e */
char *fg_hex; /* -F */
int mon; /* -m */
char *embed; /* -w */
} args;
#undef bool
/* -f option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = {
"monospace:size=10"
};
#define topbar_default 1
static char *bg_hex_default = "#005577";
#define break_on_eof_default 0
static char *fg_hex_default = "#EEEEEE";
#define mon_default -1
#define embed_default NULL
static const char *colors[SchemeLast][2] = {
/* fg, bg */
[Scheme] = { "#eeeeee", "#005577" }
/* default X11 font or font set */
static const char *fonts[] = { /* drw_fontset_create(3) wants const char ** */
"monospace:size=10" /* -f overrides this */
};
int
main(int argc, char *argv[]){
int bh;
XftColor bg;
int c;
Display *dpy;
Drw *drw;
unsigned int du;
Window dw;
Window *dws;
XftColor fg;
int i;
int j;
int lrpad; /* sum of left and right padding */
int mh;
int mw;
extern char *optarg;
Window parentwin;
Window root;
int screen;
XSetWindowAttributes swa;
char text[BUFSIZE];
int topbar; /* 0=bottom 1=top */
Window w;
XWindowAttributes wa;
Window win;
int x;
int y;
#ifdef XINERAMA
@@ -78,110 +79,147 @@ main(int argc, char *argv[]){
int a, di, n, area = 0;
#endif
topbar = 1;
args.topbar = topbar_default;
args.bg_hex = bg_hex_default;
args.break_on_eof = break_on_eof_default;
args.fg_hex = fg_hex_default;
args.mon = mon_default;
args.embed = embed_default;
while((c = getopt(argc, argv, ":bf:m:B:F:w:")) != -1)
switch(c){
case 'b':
topbar = 0;
args.topbar = !args.topbar;
break;
case 'e':
args.break_on_eof = !args.break_on_eof;
break;
case 'B': if(optarg){
colors[Scheme][ColBg] = optarg;
args.bg_hex = optarg;
break;
}case 'f': if(optarg){
fonts[0] = optarg;
break;
}case 'F': if(optarg){
colors[Scheme][ColFg] = optarg;
args.fg_hex = optarg;
break;
}case 'm': if(optarg){
mon = atoi(optarg);
args.mon = atoi(optarg);
break;
}case 'w': if(optarg){
embed = optarg;
args.embed = optarg;
break;
}default: /* optarg==0 falls through */
fprintf(stderr,
"Usage: %s (-b) (-B [background color])"
"Usage: %s (-be) (-B [background color])"
"(-f [font]) (-F foreground color)\n"
"\t(-m [monitor]) (-w [windowid)\n",
argv[0]);
return EX_USAGE;
}
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
if(setlocale(LC_CTYPE, "") == NULL || !XSupportsLocale())
fprintf(stderr, "%s: No locale support.\n", argv[0]);
if (!(dpy = XOpenDisplay(NULL)))
die("cannot open display");
if((dpy = XOpenDisplay(NULL)) == NULL){
fprintf(stderr, "%s: Cannot open X display.\n", argv[0]);
return EX_UNAVAILABLE;
}
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
if (!embed || !(parentwin = strtol(embed, NULL, 0)))
if (args.embed == NULL || !(parentwin = strtol(args.embed, NULL, 0)))
parentwin = root;
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx",
parentwin);
if (!XGetWindowAttributes(dpy, parentwin, &wa)){
fprintf(stderr, "%s: Could not get embedding window "
"attributes: 0x%lx", argv[0], parentwin);
return EX_UNAVAILABLE;
}
drw = drw_create(dpy, screen, root, wa.width, wa.height);
if (!drw_fontset_create(drw, fonts, (sizeof fonts) / (sizeof *fonts)))
die("no fonts could be loaded.");
if (!drw_fontset_create(drw, fonts, (sizeof fonts) / (sizeof *fonts))){
fprintf(stderr, "%s: No fonts could be loaded.\n", argv[0]);
return EX_UNAVAILABLE;
}
lrpad = drw->fonts->h;
/* ??? */
#ifdef __OpenBSD__
if (pledge("stdio rpath", NULL) == -1)
die("pledge");
if(pledge("stdio rpath", NULL) == -1){
fprintf(stderr, "%s: Could not pledge(2).\n", argv[0]);
return EX_UNAVAILABLE;
}
#endif
/* init appearance */
for (j = 0; j < SchemeLast; j++)
scheme[j] = drw_scm_create(drw, colors[j], 2);
drw_clr_create(drw, &bg, args.bg_hex);
drw_clr_create(drw, &fg, args.fg_hex);
/* calculate menu geometry */
bh = drw->fonts->h + 2;
mh = bh;
#ifdef XINERAMA
# define INTERSECT(x, y, w, h, r) (\
MAX(0, \
MIN((x) + (w), (r).x_org + (r).width) \
- MAX((x), (r).x_org)) \
* MAX(0, \
MIN((y) + (h), (r).y_org + (r).height) \
- MAX((y), (r).y_org))\
)
i = 0;
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
if(parentwin == root && (info = XineramaQueryScreens(dpy, &n))){
XGetInputFocus(dpy, &w, &di);
if (mon >= 0 && mon < n)
i = mon;
else if (w != root && w != PointerRoot && w != None) {
/* find top-level window containing current input focus */
do {
if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
if(args.mon >= 0 && args.mon < n)
i = args.mon;
else if(w != root && w != PointerRoot && w != None){
/* find top-level window containing current input focus
*/
do{
if( XQueryTree(dpy, (pw = w), &dw,
&w, &dws, &du)
&& dws)
XFree(dws);
} while (w != root && w != pw);
/* find xinerama screen with which the window intersects most */
if (XGetWindowAttributes(dpy, pw, &wa))
for (j = 0; j < n; j++)
if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
}while(w != root && w != pw);
/* find xinerama screen with which the window
* intersects most */
if(XGetWindowAttributes(dpy, pw, &wa))
for(j = 0; j < n; j++)
if( (a = INTERSECT(wa.x,
wa.y, wa.width,
wa.height,
info[j]))
> area){
area = a;
i = j;
}
}
/* no focused window is on screen, so use pointer location instead */
if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
for (i = 0; i < n; i++)
if (INTERSECT(x, y, 1, 1, info[i]))
if( args.mon < 0
&& !area
&& XQueryPointer(dpy, root, &dw, &dw, &x, &y,
&di, &di, &du))
for(i = 0; i < n; i++)
if(INTERSECT(x, y, 1, 1, info[i]))
break;
x = info[i].x_org;
y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
y = info[i].y_org + (args.topbar ? 0 : info[i].height - mh);
mw = info[i].width;
XFree(info);
} else
#endif
#endif /* ifdef XINERAMA */
{
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx",
parentwin);
if(!XGetWindowAttributes(dpy, parentwin, &wa)){
fprintf(stderr,
"%s: could not get embedding window"
"attributes: 0x%lx\n",
argv[0], parentwin);
return EX_UNAVAILABLE; /* appropriate sysexit? */
}
x = 0;
y = topbar ? 0 : wa.height - mh;
y = args.topbar ? 0 : wa.height - mh;
mw = wa.width;
}
inputw = MIN(inputw, mw/3);
/* create menu window */
swa.override_redirect = True;
swa.background_pixel = scheme[Scheme][ColBg].pixel;
swa.background_pixel = bg.pixel;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
CopyFromParent, CopyFromParent, CopyFromParent,
@@ -190,7 +228,7 @@ main(int argc, char *argv[]){
XMapRaised(dpy, win);
if (embed) {
if (args.embed != NULL) {
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
for (i = 0; i < du && dws[i] != win; ++i)
@@ -199,6 +237,7 @@ main(int argc, char *argv[]){
}
}
drw_resize(drw, mw, mh);
drw_setscheme(drw, fg, bg);
text[0] = '\0';
do{
@@ -207,7 +246,6 @@ main(int argc, char *argv[]){
if(text[i] == '\n')
text[i] = '\0';
drw_setscheme(drw, scheme[Scheme]);
drw_rect(drw, 0, 0, mw, mh, 1, 1);
if(*text != '\0')
@@ -221,11 +259,9 @@ main(int argc, char *argv[]){
drw_map(drw, win, 0, 0, mw, mh);
}while(
fgets(text, (sizeof text) / (sizeof *text), stdin) != NULL
|| !BREAK_ON_EOF
|| !args.break_on_eof
);
for (i = 0; i < SchemeLast; i++)
free(scheme[i]);
drw_free(drw);
XSync(dpy, False);
XCloseDisplay(dpy);

View File

@@ -1,12 +1,16 @@
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <stdarg.h> /* va_start(3), va_end(3), va_list */
#include <stdio.h> /* fputc(3), perror(3) */
#include <stdlib.h> /* calloc(3), exit(3) */
#include <string.h> /* strlen(3) */
#include <X11/Xlib.h> /* Display */
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
#define UTF_INVALID 0xFFFD
#define UTF_SIZ 4
@@ -16,6 +20,34 @@ static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
void
die(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
fputc(' ', stderr);
perror(NULL);
} else {
fputc('\n', stderr);
}
exit(1);
}
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if (!(p = calloc(nmemb, size)))
die("calloc:");
return p;
}
static long
utf8decodebyte(const char c, size_t *i)
{
@@ -194,7 +226,7 @@ drw_fontset_free(Fnt *font)
}
void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
drw_clr_create(Drw *drw, XftColor *dest, const char *clrname)
{
if (!drw || !dest || !clrname)
return;
@@ -205,23 +237,6 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
die("error, cannot allocate color '%s'", clrname);
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
size_t i;
Clr *ret;
/* need at least two colors for a scheme */
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
return NULL;
for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i]);
return ret;
}
void
drw_setfontset(Drw *drw, Fnt *set)
{
@@ -230,18 +245,20 @@ drw_setfontset(Drw *drw, Fnt *set)
}
void
drw_setscheme(Drw *drw, Clr *scm)
drw_setscheme(Drw *drw, XftColor fg, XftColor bg)
{
if (drw)
drw->scheme = scm;
if (drw) {
drw->bg = bg;
drw->fg = fg;
}
}
void
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
{
if (!drw || !drw->scheme)
if (!drw || !drw->bg || !drw->fg)
return;
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
XSetForeground(drw->dpy, drw->gc, invert ? drw->bg.pixel : drw->fg.pixel);
if (filled)
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
else
@@ -266,13 +283,13 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
XftResult result;
int charexists = 0;
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
if (!drw || (render && (!drw->bg || !drw->fg)) || !text || !drw->fonts)
return 0;
if (!render) {
w = ~w;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XSetForeground(drw->dpy, drw->gc, (invert ? drw->fg : drw->bg).pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
@@ -322,7 +339,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
XftDrawStringUtf8(d, &(invert ? drw->bg : drw->fg),
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
}
x += ew;

View File

@@ -16,14 +16,16 @@ enum { ColFg, ColBg }; /* Clr scheme index */
typedef XftColor Clr;
typedef struct {
unsigned int w, h;
XftColor bg;
Display *dpy;
int screen;
Window root;
Drawable drawable;
GC gc;
Clr *scheme;
XftColor fg;
Fnt *fonts;
GC gc;
unsigned int h;
Window root;
int screen;
unsigned int w;
} Drw;
/* Drawable abstraction */
@@ -47,7 +49,7 @@ void drw_cur_free(Drw *drw, Cur *cursor);
/* Drawing context manipulation */
void drw_setfontset(Drw *drw, Fnt *set);
void drw_setscheme(Drw *drw, Clr *scm);
void drw_setscheme(Drw *drw, XftColor fg, XftColor bg);
/* Drawing functions */
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);

View File

@@ -1,11 +1,11 @@
from json import dumps, loads
bookmarks = "bookmarks.json"
bookmarks_filename = "bookmarks.json"
def load():
with open(bookmarks) as f:
with open(bookmarks_filename) as f:
return loads(f.read())
def store(b):
with open(bookmarks + ".new", 'w') as f:
with open(bookmarks_filename + ".new", 'w') as f:
return f.write(dumps(b))

View File

@@ -1,6 +1,6 @@
/.ignore verbatim
/test ignore
#llllmmmm11234567892123456789312345678941234567895123456789612345678971234567890
#llllmmmm1123456789212345678931234567894123456789512345678961234567897123456789
# vim: syntax=:ts=8
@@ -1050,6 +1050,312 @@ pre { /* DRY who? */
}
/blah/2025-04-24.html
: XDG_RUNTIME_DIR=/tmp/$(id -u)-runtime-dir causes pipewire to crash
So PipeWire wasn't working for inscrutable reasons. Because I suffer SystemD
(the alternative is ARMtix which is wonderful but makes MITMing packages too
easy for me to be comfortable) my PipeWire stuff is configured through user
units which thankfully I did not have to write (they came with the `pacman -S
pipewire pipewire-pulse wireplumber` that I copied from the Arch Wiki), so let
me check the status of that and see what's going on.
$ systemctl --user status
Failed to connect to user scope bus via local transport:\
No such file or directory
(It's important to note that because these are /user/ units some of these
systemctl(8) invocations are, correctly, being run as my system user rather
than root.)
I'd like to explain UNIX error handling. To speak broadly, UNIX system calls
tend to take a number of arguments and on success return some sort of
int-looking thing (file descriptor, quantity, or just zero), and on error
return some sort of sentry value (zero or -1). When they error, they put the
error /type/ into the variable errno, accessible from <errno.h>. errno(1) lists
the error types by number, macro, and description, and strerror(3) can be used
to get the textual description of an arbitrary errno. An errno of 0 means no
error has occurred.
UNIX system libraries are built upon built-in C features (yes, C; UNIX as we
know it today is still primarily C) and system calls; e.g. <stdio.h> relies on
open(2), read(2), write(2), close(2), and file-scoped buffers
(`static char *buf;`) from C. Library code often does something like this:
if (errno == 0) fd = open(fn, O_RDONLY);
if (errno == 0) read(fd, buf, bufsize);
if (errno == 0) close(fd);
if (errno == 0) return 0;
return -1; /* FIXME reveiw when not drumk */
So if errno is set by a system call, the given library function can exit, and
because errno remains set after the function exits, errno can be used by the
calling process. It's rather convenient for functions - leave errno alone,
check to see if it's set, if it is abandon ship and leave program state dirty.
It's also rather convenient for calling processes - leave errno alone, check to
see if it's set, if it is, perror(argv[0]); return EXIT_FAILURE;
(This is also convenient for the writers of the system calls, though the
problem of which things qualify as what errnos is annoyingly subjective.)
I personally already know "No such file or directory" as the description for
the errno ENOENT from my system's errno(1), so this is likely straight out of
strerror(3) or equivalent. But what system call caused this error? I'll use
strace(1).
$ alias p
alias p='bat' # in my .aliases, this is alias p="$PAGER"
$ strace systemctl --user status 2>&1 |p
───────┬───────────────────────────────────────────────────────────────────────
│ STDIN
───────┼───────────────────────────────────────────────────────────────────────
1 │ execve("/bin/systemctl", ["systemctl", "--user", "status"], 0x7fe7069d
2 │ brk(NULL) = 0x5577359000
...
292 │ connect(3, {sa_family=AF_UNIX, sun_path="/tmp/1000-runtime-dir/systemd
/private"}, 37) = -1 ENOENT (No such file or directory)
293 │ close(3) = 0
294 │ ioctl(1, TCGETS, 0x7fc8f59ea0) = -1 ENOTTY (Inappropriate ioc
295 │ newfstatat(AT_FDCWD, "/dev/null", {st_mode=S_IFCHR|0666, st_rdev=maked
296 │ fstat(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
297 │ fstat(2, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
298 │ ioctl(2, TCGETS, 0x7fc8f59f40) = -1 ENOTTY (Inappropriate ioc
299 │ writev(2, [{iov_base="", iov_len=0}, {iov_base="Failed to connect to u
│ en=0}, {iov_base="\n", iov_len=1}], 4Failed to connect to user scope b
│ y
300 │ ) = 83
301 │ exit_group(1) = ?
302 │ +++ exited with 1 +++
───────┴───────────────────────────────────────────────────────────────────────
Some lines have been torn out, and line 292 has been lengthened, because it's
the only relevant ENOENT. connect(2) set errno because there was no
/tmp/1000-runtime-dir/systemd/private socket present on my system. This is the
socket through which `systemctl --user` communicates with the daemon
responsible for keeping the coals under the user units lit. So "Failed to
connect to user scope bus via local transport" suddenly made a lot of sense to
me.
/tmp/1000-runtime-dir was my $XDG_RUNTIME_DIR, set in my $HOME/.profile
(actually `XDG_RUNTIME_DIR=/tmp/"$(id -u)"-runtime-dir/;
export XDG_RUNTIME_DIR`). This didn't stick out to me or anything because why
would it? I'd been running UNIXes for years and it had worked fine on all of
them.
A conversation with Perplexity.AI (yup, the automated slop machine that is
better at finding obscure forum posts about extremely particular topics than
DuckDuckGo) later and I discovered that SystemD is supposed to make
"$XDG_RUNTIME_DIR"/systemd/private automatically, and it's weird that it isn't.
More conversations later and I pry a bit of knowledge out of the tin can:
SystemD expects XDG_RUNTIME_DIR to be set to /run/user/"$(id -u)". It won't
create "$XDG_RUNTIME_DIR"/systemd/private otherwise.
Wait, what?
I changed my $HOME/.profile and rebooted.
All of a sudden `systemctl --user status` just worked. Audio did as well.
/blah/2025-04-18.html
: X without the WM
I use a netbook for /only/ SShing into this CM4 uConsole. The netbook runs
NetBSD/i386 and my usual behavior is something like
sanichi$ ssh laika.lan
laika$ tmux
which works well for me, except for fancy UTF-8 TUI programs, which look ugly,
because the NetBSD tty(4) supports ASCII only (as far as I know, though I did
check the manual).
I don't want windows or decorations, I don't want clocks or status bars, I just
want tmux in a terminal window. I'm going to achieve this using xinit(1) (which
comes with the full NetBSD system) and xdotool(1).
# pkgin install xdotool
This command assumes the use of pkgsrc; adapt it to other package managers if
need be. I don't know much about modular-xorg so you may need to futz a bit to
find xinit(1).
$ cd; vi .xinitrc
And here's the entire .xinitrc:
xdotool search --sync --class xterm windowsize 100% 100% & exec xterm
Not bad for 80B, eh? Let's chart it out:
xdotool ; xdotool(1) - command-line X11 automation tool
search ; Find a certain window.
--sync ; Wait until it's found.
--class xterm ; It calls itself "xterm". When you find it,
windowsize ; resize it.
100% ; Make it fill the view horizontally.
100% ; Make it fill the view vertically.
& ; Don't wait for this command to finish before
; starting the next one.
exec ; Start this next program in the X server, and
; when it finishes, close the X server.
xterm ; xterm(1) - terminal emulator for X
I can exit X by either sending an EOF (that's ^D) from xterm(1) or, if it
freezes, switching to ttyE0 and sending a ^C to the running X server.
I initially passed xterm(1) `-e tmux` to start tmux, but I've found I still
prefer to SSh into laika before starting tmux, so all my terminals are remote
(one for mail, one for writing, one for debugging, one for man pages).
I did add `xrdb -load ~/.Xresources` before the xdotool(1)/xterm(1) line, so
xterm(1) would load with my preferred color scheme which I've already
configured (also see X(7)). I thought this might be automatic, but on here it's
not.
I'm finishing this blah post on my netbook running NetBSD/i386 and an X11
server, in which xterm(1) is running, in which ssh(1) is running, connected to
my uConsole across the room, on which tmux(1) is running, in which nvim(1) is
running. The UTF-8 is beautiful and bat(1) (a guilty pleasure of mine) looks
good.
If I was going to use this computer for anything more than terminals, I'd just
use a window manager. I thought about using sxhkd(1) for this task but it
ultimately proved to be unnecessary.
I added the following to my $ENV (see sh(1)):
# Don't start X if I'm on a framebuffer kick or am in tmux(1) (or screen(1)).
if test -z "$NO_WM" && ! test "$TERM" = screen
then case "$0" in
-*) startx ;; # Do start X if I'm in a login shell
# (see bash(1)).
esac
fi
Which seems to work well. If it failed dreadfully I could reboot and login as
root.
I don't have much more to say. Don't be scared of X - in conjunction with
xinit(1) and startx(1) it's quite easy to use. Don't be scared of Wayland
either - it may not yet run well on NetBSD, but if you get a chance to try it,
you might really like it.
/blah/2025-04-05.html
My habitual "the story so far" was long delayed because I didn't remember what
happened in 2024 - I really just didn't remember anything until my acid trip in
July. I don't know if it's out of trauma or shame or a combination of both.
When I try to remember what happened last year this sweltering sadness
overwhelms me and my eyes well up. Otherwise it seems like just another
forgotten nightmare.
: the story so far (2024)
Season 3: desert
January
Episode 01: "four five six"
Another polycule visits. Trinity finds it hard to balance work and
life.
February
Episode 02: "thirty-three days"
Trinity works for one month straight.
March
Episode 03: "trinity has a mental breakdown"
Trinity has a mental breakdown due to overwork.
April
Episode 04: "toki pona"
The gang goes to a toki pona meetup.
Episode 05: "bicycle day"
Trinity takes two days off to try acid but [...] and [...] worry it'll
have a bad trip.
May
Episode 06: "three's a crowd"
[...] leaves to get [...]. [...] comes back with [...] and Trinity
can't watch a movie without them making out near it.
June
Episode 07: "a match made in hell"
Trinity trains a new coworker.
July
Episode 08: "moxie"
[...] and [...] find a place that sells Moxie.
Episode 09: "suicide is painless"
Trinity contemplates suicide.
Episode 10: "nuture"
Trinity takes 100ug of lysergic acid diethylamine. [...] quits.
Episode 11: "a day off"
Trinity enjoys a day off from work.
Episode 12: "two weeks"
Trinity puts its two week notice in and faces retribution.
August
Episode 13: "a softer world"
Trinity starts a new job.
September
Episode 14: "prog rock"
Trinity goes to a concert with a friend.
November
Episode 15: "pies pies pies"
Trinity, now competent, makes a lot of pies.
Episode 16: "thanksgiving"
Trinity and [...] survive Thanksgiving at [...].
December
Episode 17: "noted"
Trinity gets a notebook.
Episode 18: "yule"
The gang goes to Yule at [...]'s parents' and gets drunk.
Episode 19: "the birds"
Trinity's lost notebook falls out of the sky. Trinity struggles to
think of Christmas presents for everyone.
/blah/2025-04-01.html
: openbsd server
i'm using caddy instead of relayd,httpd,acme because i like an easy config for
web shit and i loathe tls stuff
/etc/caddy/Caddyfile
|
| # lightly modified default
| {
| http_port 8080
| https_port 8443
| admin unix//var/caddy/admin.sock|0220
| }
|
| trinity.moe {
| root * /srv/trinity.moe
| file_server
| }
|
| www.trinity.moe {
| redir https://trinity.moe{uri}
| }
cool and all, right? except caddy can't bind to low ports on openbsd, because
caddy isn't running as root (which is a security issue) and openbsd can't let
non-root processes bind to low ports like linux can. so we've bound to high
ports. let's fix this in pf(4)
/etc/pf.conf
| # [ defaults included, but i'm not copying them over here ]
| pass in on any proto tcp from any to any port 80 rdr-to 127.0.0.1 port 8080
| pass in on any proto tcp from any to any port 443 rdr-to 127.0.0.1 port 8443
okay cool
for a while trinity.moe was hosted on the same machine as feeling.murderu.us,
as of today that is no longer the case (i still own murderu.us and everything,
i just wanted a personal vps for other things too)
maybe there will be more blah posts but probably not
/blah/2024-12-01.html
: vaporware i looked forward to

View File

@@ -1 +1,3 @@
CFLAGS += -g
libpsargs.o:

View File

@@ -1,4 +1,10 @@
all: lowercase-ascii uppercase-ascii
all: lowercase uppercase
lowercase: lowercase-ascii
mv lowercase-ascii lowercase
uppercase: uppercase-ascii
mv uppercase-ascii uppercase
lowercase-ascii: case.c case-ascii.h
$(CC) -DCONV=TOLOWER -include case-ascii.h -o lowercase-ascii case.c

View File

@@ -6,24 +6,19 @@ lowercase \(en make text lowercase
.SH SYNOPSIS
lowercase (-f)
lowercase
.SH DESCRIPTION
Lowercase prints text from standard input to standard output as lowercase.
.SH DIAGNOSTICS
Lowercase will print an error message and exit with the appropriate status from sysexits(3) if it attempts
to process a glyph outside the supported encoding range; this is to not inadverdently mangle multi-byte
characters. The -f option exists to override this and process every character anyway.
Lowercase prints text from standard input to standard output as lowercase. It
passes through text it can't convert.
.SH BUGS
Lowercase is not Unicode aware unless it's compiled with the USE_ICU flag, which requires libicu.
This isn't tested to any extent.
Lowercase is not Unicode aware.
.PP
Lowercase is redundant to usages of tr(1) among other POSIX-specified utilities.
Lowercase is redundant to usages of tr(1) among other POSIX-specified
utilities.
.SH HISTORY

View File

@@ -70,13 +70,13 @@ get_memory_usage() {
PUBLIC_IP="$(ifpublic)"
printbar() {
printf "%b" "$(get_current_desktop)"
# printf "%b" "$(get_current_desktop)"
printf "%b" $($DATE)
printf "%b" "$DELIMITER"
printf "%b" "BAT: $(battery)"
printf "%b" "$DELIMITER"
printf "%b" "CPU: $(get_cpu_temp)"
printf "%b" "$DELIMITER"
# printf "%b" "CPU: $(get_cpu_temp)"
# printf "%b" "$DELIMITER"
printf "%b" "PuIP: $PUBLIC_IP"
#printf "%b" "$DELIMITER"
#printf "%b" "MEM: $(get_memory_usage)"

139
niceties/openbsd Normal file
View File

@@ -0,0 +1,139 @@
#!/bin/sh
set -e
# found this here... may auto install openbsd... may not... who knows
prog(){ while test -n "$!" # ask your doctor about progesterone
do if ! command -v "$1" >/dev/null
then printf '%s: %s command not found. Please install it.\n' \
"$0" "$1" 1>&2
false
fi done }
prog curl
if ! prog signify
then if prog signify-openbsd
then alias signify=signify-openbsd
else false
fi fi
OBSD="$HOME"/OpenBSD
REL=7.5
SREL="$(printf '%s\n' "$REL" | tr -d .)"
test -n "$ARCH" \
|| case "$(uname -m)" in
# aarch64) ARCH=arm64 ;;
amd64) ARCH=amd64 ;;
# arm64) ARCH=arm64 ;;
i386) ARCH=i386 ;;
# *) ARCH=riscv64 ;;
*) ARCH=arm64 ;;
esac
test -n "$MIRROR" \
|| MIRROR=ftp://mirrors.mit.edu/pub/OpenBSD
case "$ARCH" in
amd64) QEMU=x86_64 ;;
i386) QEMU=i386 ;;
*) QEMU=aarch64 ;;
esac
printf '%s: enter a public SSH key for accessing the virtual machine.\n:: ' "$0"
PUBSSH="$(head -n 1)"
printf "\
%s: Setting up a virtualized OpenBSD %s (%s) instance from the mirror %s.
%s: Control+C to cancel. Waiting 10s to continue...
" "$0" "$REL" "$ARCH" "$MIRROR" \
"$0" 1>&2
sleep 10
# <https://www.skreutz.com/posts/autoinstall-openbsd-on-qemu/>
mkdir -p "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH"
curl -O --output-dir "$OBSD"/mirror/pub/OpenBSD/"$REL"/ \
https://ftp.openbsd.org/pub/OpenBSD/"$REL"/openbsd-"$SREL"-base.pub
for f in SHA256.sig bsd bsd.mp bsd.rd pxeboot \
base"$SREL".tgz comp"$SREL".tgz man"$SREL".tgz
do curl -O --output-dir "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH" \
"$MIRROR"/"$REL"/"$ARCH"/"$f"
done
signify -C -p "$OBSD"/mirror/pub/OpenBSD/"$REL"/openbsd-"$SREL"-base.pub \
-x "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH"/SHA256.sig \
-- bsd* pxeboot *"$SREL".tgz
printf "\
%s: Using the following autoinstall(8) install.conf:
Change the default console to com0 = yes
Which speed should com0 use = 115200
System hostname = openbsd
Password for root = *************
Allow root ssh login = no
Setup a user = puffy
Password for user = *************
Public ssh key for user = %s
What timezone are you in = UTC
Location of sets = http
HTTP Server = 10.33.2.1
Unable to connect using https. Use http instead = yes
URL to autopartitioning template for disklabel = http://10.33.2.1/disklabel
Set name(s) = site%s.tgz
Checksum test for site%s.tgz failed. Continue anyway = yes
Unverified sets: site%s.tgz. Continue without verification = yes
" "$0" "$PUBSSH" "$SREL" "$SREL" "$SREL" \
| tee -a /dev/stderr \
| sed -e 1d -e 's:^\t::g' \
>"$OBSD"/mirror/install.conf
printf "\
%s: Using the following disklabel(8) template:
/ 8G
swap 256M
" "$0" \
| tee -a /dev/stderr \
| sed -e 1d -e 's:^\t::g' \
>"$OBSD"/mirror/disklabel
mkdir -p site
printf "\
#!/bin/sh
printf 'https://cdn.openbsd.org/pub/OpenBSD\n' \
>/etc/installurl
printf 'permit keepenv nopass :wheel\n' \
>>/etc/doas.conf
" >"$OBSD"/site/install.site
chmod +x "$OBSD"/site/install.site
tar -C site czf "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH"/site"$SREL".tgz
# probably not necessary
#ls -l "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH" >"$OBSD"/index.txt
mkdir -p tftp/etc
ln "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH"/pxeboot "$OBSD"/tftp/auto_install
ln "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH"/bsd.rd "$OBSD"/tftp/bsd.rd
printf "\
stty com0 115200
set tty com0
boot tftp:/bsd.rd
" >"$OBSD"/tftp/etc/boot.conf
qemu-img create -f qcow2 "$OBSD"/hd0.qcow2 9G
chmod +x
python3 -m http.server --directory "$OBSD"/mirror --bind 127.0.0.1 8080 &
qemu-system-"$QEMU" \
-drive file=\"\$OBSD\"/hd0.qcow2,media=disk,if=virtio \
-device e1000,netdev=n1 \
-m 512M \
-netdev user,id=n1,hostname=openbsd-vm,tftp-server-name=10.0.2.1,tftp=tftp,bootfile=auto_install,hostfwd=tcp::2222-:22,guestfwd=tcp:10.0.2.1:80-cmd:socat STDIO TCP4:127.0.0.1:8080 \
-nographic &
printf "\
%s: ssh into puffy@127.0.0.1:2222 to connect.
%s: press Enter to quit.
" "$0" "$0" 1>&2
head -n 1

View File

@@ -4,7 +4,7 @@
# Not a great use of disk...
dd 2>/dev/null \
| sed \
-e 's/l/w/g' \
-e 's/r/w/g' \
-e 's/smaww/smol/g' \
-e 's/wove/wuv/g'
-e s/l/w/g \
-e s/r/w/g \
-e s/smaww/smol/g \
-e s/wove/wuv/g

View File

@@ -52,7 +52,7 @@ case "$1" in
-) "$0" r -"$2" ;;
a*)
str isvalue $2 && ! str isvalue $3 && str isdigit "$2" \
test -n $2 && ! str isvalue $3 && str isdigit "$2" \
|| usage
"$0".$VOLUME_SYSTEM "$@"
;;

119
npc.rs Normal file
View File

@@ -0,0 +1,119 @@
/*
* Copyright (c) 2023 DTB <trinity@trinity.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
use std::{
env::args,
io::{ stdin, stdout, Error, Read, Write },
process::ExitCode
};
extern crate getopt;
use getopt::{ Opt, Parser };
extern crate sysexits;
use sysexits::{ EX_OK, EX_OSERR, EX_USAGE };
fn oserr(s: &str, e: Error) -> ExitCode {
eprintln!("{}: {}", s, e);
ExitCode::from(EX_OSERR as u8)
}
fn usage(s: &str) -> ExitCode {
eprintln!("Usage: {} (-aet)", s);
ExitCode::from(EX_USAGE as u8)
}
fn main() -> ExitCode {
let argv = args().collect::<Vec<String>>();
let input = stdin();
let mut output = stdout().lock();
let mut opts = Parser::new(&argv, "7et");
let mut ascii = false;
let mut showend = false;
let mut showtab = false;
loop {
match opts.next() {
None => break,
Some(o) =>
match o {
Ok(Opt('7', None)) => ascii = true,
Ok(Opt('e', None)) => showend = true,
Ok(Opt('t', None)) => showtab = true,
_ => { return usage(&argv[0]); }
}
}
}
/* cat -v emulation */
if ascii {
let mut c: u8 = 0;
for r in input.bytes() {
match r {
Ok(v) => { c = v; },
Err(e) => { return oserr(&argv[0], e); }
}
/* If a given byte isn't expressable in ASCII, print "M-[char]",
* where char is the chosen representation of the byte with its
* high bit set to 0. */
if c & 0x80 /* 0b 1000 0000 */ != 0 { print!("M-"); }
c ^= 0x80;
/* ASCII DEL is represented as ^? */
if c == 0x7f as u8 {
if let Err(e) = output.write_all(b"^?") {
return oserr(&argv[0], e);
}
break;
}
if c == '\n' as u8 && showend {
if let Err(e) = output.write_all(b"$") {
return oserr(&argv[0], e);
}
}
/* ASCII visual characters are shown literally. */
if c >= ' ' as u8 || c == '\n' as u8
|| (!showtab && c == '\t' as u8) {
if let Err(e) = output.write_all(&[c]) {
return oserr(&argv[0], e);
}
}
/* Otherwise, characters are shown as their control code, with NUL
* being ^@ and successive characters shown as "^" catenated with
* successive visual characters past "@". */
else {
c += '@' as u8;
if let Err(e) = output.write_all(b"^") {
return oserr(&argv[0], e);
}
if let Err(e) = output.write_all(&[c]) {
return oserr(&argv[0], e);
}
}
}
} else {
eprintln!("not implemented");
}
ExitCode::from(EX_OK as u8)
}

View File

@@ -1,6 +1,6 @@
#include <fcntl.h> /* open(2), O_RDONLY */
#include <stdio.h> /* fprintf(3), perror(3) */
#if !defined EX_OK || !defined EX_OSERR || !defined EX_USAGE
#if !defined EX_OSERR || !defined EX_USAGE
# include <sysexits.h>
#endif
#include <unistd.h> /* dup(2), dup2(2), fork(2), STDIN_FILENO */

View File

@@ -1,14 +1,5 @@
TARGETS = roll
all: $(TARGETS)
CFLAGS += -g
roll: roll.c
.PHONY: clean
clean:
rm -f $(TARGETS)
sane: roll.c ../include/sysexits.h
$(CC) -DDONT_USE_SYSTEM_SYSEXITS -o roll roll.c
roll: %.c
$(CC) -o $@ $@.c
.PHONY: all clean sane
rm roll.c

View File

@@ -1,3 +0,0 @@
#!/bin/sh
exec rot 13

4
status/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.o
order.c
settings.c
status

28
status/Makefile Normal file
View File

@@ -0,0 +1,28 @@
CFLAGS += -g
.PHONY: run
run: status
./status
.PHONY: cleanall
cleanall: clean
rm -f order.c settings.c
.PHONY: clean
clean:
rm -f status *.o
status: status.c order.c libio.o libkeyval.o
time $(CC) $(CFLAGS) -o $@ $@.c libio.o libkeyval.o
order.c: order.def.c
- cp -v order.def.c $@
libio.o: libio.c libio.h
$(CC) $(CFLAGS) -c -o $@ libio.c
libkeyval.o: libkeyval.c libkeyval.h settings.c
$(CC) $(CFLAGS) -c -o $@ libkeyval.c
settings.c: settings.def.c
- cp -v settings.def.c $@

13
status/README Normal file
View File

@@ -0,0 +1,13 @@
__ ___ __ ___ _ _ __
/ _// // // // // // _/ STATUS
_'. / // _ // / / // /_'. how's your day going?
/__/ /_//_//_//_/ /__/ /__/ 2025 DTB. Public Domain.
build: $ make
libio.c, libio.h: libio, a wrapper around I/O functions for status(1)
libkeyval.c, libkeyval.h: libkeyval, a key/value system for status(1)
*.def.c: the default for foo.c, a configuration file #included
directly in a source-file
mod_*.c: modules to be #included directly in status.h
status.c: main() and boilerplate

19
status/libio.c Normal file
View File

@@ -0,0 +1,19 @@
/* 2025 DTB. Public Domain. */
#undef NDEBUG /* LOAD-BEARING ASSERTS! */
#include <assert.h> /* assert(3) */
#include <errno.h> /* errno */
#include <stdio.h> /* fputs(3), stdout, NULL */
#include "libio.h"
/* output */
static char *hold = NULL;
void
drop(void) { hold = NULL; }
void
out(char *s) {
if (hold != NULL)
{ errno = 0; fputs(hold, stdout); assert(errno == 0); }
hold = s;
}

8
status/libio.h Normal file
View File

@@ -0,0 +1,8 @@
/* 2025 DTB. Public Domain. */
/* libio is a microscopic library that exists to separate less relevant code
* from status(1). It should not be used in critical applications for lack of
* recoverability (as opposed to <stdio.h> on its own). */
void drop(void); /* Set the buffer to NULL. */
void out(char *s); /* Print the buffer if not NULL and replace it with s. */

68
status/libkeyval.c Normal file
View File

@@ -0,0 +1,68 @@
/* 2025 DTB. Public domain. */
#undef NDEBUG /* LOAD-BEARING ASSERTS! */
#include <assert.h> /* assert(3) */
#include <stdlib.h> /* atoi(3) */
#include <string.h> /* strcmp(3) */
#include "libkeyval.h"
static struct State state = { 0 };
void
cpy(char *key) {
state.settings[state.setting_last].key = key;
state.settings[state.setting_last].val = get(key);
assert(++state.setting_last < state_settings_size);
}
void
del(char *key) {
size_t i;
for (i = idx(key); i < state.setting_last; ++i) {
state.settings[i].key = state.settings[i + 1].key;
state.settings[i].val = state.settings[i + 1].val;
}
--state.setting_last;
}
char *
get(char *key) { return state.settings[idx(key)].val; }
int
getd(char *key) { return atoi(get(key)); }
size_t
idx(char *key) {
size_t r;
for (r = 0; state.settings[r].key != NULL
&& strcmp(state.settings[r].key, key) != 0;
++r);
return (state.settings[r].key == NULL) ? state.setting_last : r;
}
void
keyval_init(void) {
/* Unnecessary, but means a wrong state.setting_last won't blow up. */
(void)memset(&state.settings[state.setting_last],
state_settings_size - state.setting_last, '\0');
#include "settings.c"
}
size_t
ren(char *key, char *new) {
size_t i;
if ((i = idx(key)) != state.setting_last)
{ state.settings[i].key = new; }
return i;
}
size_t
set(char *key, char *val) {
size_t i;
i = idx(key);
state.settings[i].key = key;
state.settings[i].val = val;
if (i == state.setting_last)
{ assert(++state.setting_last < state_settings_size); }
return i;
}

29
status/libkeyval.h Normal file
View File

@@ -0,0 +1,29 @@
/* 2025 DTB. Public domain. */
/* libkeyval is a key/value store library to be used for nonessential
* applications due to lack of recoverability (errors fail assert(3)).
* libkeyval deals with pointers and pointers only, and an effort has been made
* to reflect the simplicity of the procedure in the code itself. */
/* keyval store */
#ifndef state_settings_size
# define state_settings_size 100
#endif
struct State {
size_t setting_last;
struct Setting { char *key; char *val; } settings[state_settings_size];
};
void cpy(char *key); /* Duplicate the setting key. */
void del(char *key); /* Delete the first instance of key in settings. */
char * get(char *key); /* Get the corresponding val to key in settings. */
int getd(char *key); /* get() that returns a decimal number if key was a
* number, or 0. */
void keyval_init(void); /* Sanitize the settings store. */
size_t idx(char *key); /* Returns the index of key if in settings, or
* state.setting_last. */
size_t ren(char *key, char *dst); /* Rename the first instance of key in
* settings. */
size_t set(char *key, char *val); /* Set the first instance of key in
* settings. */

5
status/mod_static.c Normal file
View File

@@ -0,0 +1,5 @@
// #include "io.h" /* out(3) */
// #include "keyval.h" /* get(3) */
void
mod_static(char *s) { out(s); out(get("separator")); }

35
status/mod_time.c Normal file
View File

@@ -0,0 +1,35 @@
/* 2025 DTB. Public Domain. */
// #undef NDEBUG /* LOAD BEARING ASSERTS */
// #include <assert.h> /* assert(3) */
// #include <stdlib.h> /* setenv(3), unsetenv(3), NULL */
// #include <time.h> /* localtime(3), strftime(3), time(2), tzset(3), time_t,
// * struct tm */
// #include "io.h" /* out(3) */
// #include "keyval.h" /* get(3) */
#ifndef mod_time_bufsize
# define mod_time_bufsize 100
#endif
void
set_timezone(char *zone) {
if (zone == NULL) { assert(unsetenv("TZ") == 0); }
else { assert(setenv("TZ", zone, 1) == 0); }
tzset();
}
void
mod_time(char *fmt) {
static char buf[mod_time_bufsize];
struct tm *tm;
static time_t t = 0;
static tick_t last_tick = 0;
if (ticker == 0) { t = time(NULL); }
else if (ticker != last_tick) { t += slept; }
last_tick = ticker;
assert((tm = localtime(&t)) != NULL);
assert(strftime(buf, sizeof(buf) / sizeof(*buf), fmt, tm) != 0);
out(buf);
out(get("separator"));
}

52
status/order.def.c Normal file
View File

@@ -0,0 +1,52 @@
/* This is a C source file #included at global scope in status.c. There are a
* number of useful functions defined in status.c and #included headers to try
* to make iteration a little more convenient. */
/* Environment
* getenv(key) gets the value of an environment variable
* setenv(key, val, overwrite) sets key to val in the environment, overwriting
* val if key was already defined and overwrite is 0
* set_timezone(val) sets TZ to val in the environment, then calls tzset(3) to
* set appropriate timezone values. if val is NULL, it clears the TZ val,
* which restores the timezone to the system local time
* get(key) gets the val corresponding to key in settings
* set(key, val) sets the val corresponding to key in settings
* idx(key) returns the index of key in settings
* del(key) deletes the first instance of key in settings
* cpy(key) creates an identical instance to key in settings
* ren(key, dst) renames key to dst in settings
* keyval_init() cleans the settings in case of a glitch */
/* I/O
* out(s) holds s and prints what it was previously holding, if it wasn't NULL
* drop() sets out()'s held value to NULL */
/* Modules
* mod_static(s) outputs s and then the separator val, unless mod_static() is
* called as the last function in order
* mod_time(fmt) outputs the time for the current time zone in the strftime(3)
* fmt */
void
order() {
/* there are a couple good ways to print without the separator. the
* best is to use out() to write directly to the output buffer */
out("utc"); /* => "utc" */
/* but another way is to use status_static to write a message and
* separator, then use drop() to recall the last thing written (always
* the separator in status_* functions) */
mod_static(" "); drop(); /* => " " */
set_timezone("");
mod_time("%Y-%m-%dT%H:%M"); /* => "2025-03-27T00:00 // " */
/* and another way is to use the weird key-val system */
cpy("separator"); /* duplicate setting */
set("separator", " "); /* overwrite first setting */
set_timezone(NULL);
mod_static("local"); /* use first setting */
del("separator"); /* delete the first, restoring the second */
mod_time("%Y-%m-%dT%H:%M");
drop();
/* => "local 2025-03-26T18:00" */
/* all => "utc 2025-03-27T00:00 // local 2025-03-26T18:00" */
}

2
status/settings.def.c Normal file
View File

@@ -0,0 +1,2 @@
set("interval_seconds", "1");
set("separator", " // ");

32
status/status.c Normal file
View File

@@ -0,0 +1,32 @@
#undef NDEBUG /* LOAD-BEARING ASSERTS! */
#include <assert.h> /* "mod_time.c" */
#include <limits.h> /* UCHAR_MAX */
#include <stdlib.h> /* "mod_time.c" */
#include <time.h> /* "mod_time.c" */
#include <unistd.h> /* sleep(3) */
#include "libio.h" /* drop(3), out(3), "mod_static.c" */
#include "libkeyval.h" /* cpy(3), del(3), get(3), keyval_init(3), set(3),
* "mod_static.c" */
#define ever (;;)
unsigned int slept = 0;
typedef unsigned char tick_t;
#define TICK_MAX UCHAR_MAX
tick_t ticker = 0;
#include "mod_static.c"
#include "mod_time.c"
#include "order.c"
int main(int argc, char *argv) {
keyval_init();
for ever {
order(); drop(); out("\n");
slept = sleep(getd("interval_seconds"));
ticker = ++ticker % TICK_MAX;
}
}

View File

@@ -11,6 +11,7 @@ TARGETS = \
$(HOME)/.config/sway/config \
$(HOME)/.env \
$(HOME)/.gitconfig \
$(HOME)/.ircrc \
$(HOME)/.nethackrc \
$(HOME)/.profile \
$(HOME)/.vimrc \
@@ -37,6 +38,10 @@ $(HOME)/.config/helix/config.toml: helix/config.toml
mkdir -p $(HOME)/.config/helix
ln -s helix/config.toml $@
$(HOME)/.config/helix/languages.toml: helix/languages.toml
mkdir -p $(HOME)/.config/helix
ln -s helix/config.toml $@
$(HOME)/.config/helix/themes/trinity.toml: helix/trinity.toml
mkdir -p $(HOME)/.config/helix/themes
ln -s helix/trinity.toml $@
@@ -67,6 +72,9 @@ $(HOME)/.env: sh/env
$(HOME)/.gitconfig: git/gitconfig
cp git/gitconfig $@
$(HOME)/.ircrc: ircII/ircrc
ln -s ircII/ircrc $@
$(HOME)/.nethackrc: nethack/nethackrc
ln -s nethack/nethackrc $@

View File

@@ -1,9 +1,9 @@
[[language]]
file-types = ["c"]
indent.unit = "\t"
indent.tab-width = 8
language-id = "C"
name = "C"
indent.tab-width = 4
language-id = "c"
name = "c"
roots = ["Makefile"]
scope = "source.c"

1
trinitystuff/ircII/ircrc Normal file
View File

@@ -0,0 +1 @@
channel #subgeneral,#media

View File

@@ -0,0 +1,26 @@
vim.cmd.colorscheme("torte");
vim.cmd.syntax("on");
vim.cmd([[
set mouse=
set noautoindent
set nocp
set noexpandtab
set noim
set nois
set nowrap
call plug#begin('~/.vim/plugged')
Plug 'Olical/conjure'
Plug 'atweiden/vim-fennel'
call plug#end()
]]);
vim.opt.bg = "dark";
vim.opt.colorcolumn = "80";
vim.opt.nu = true;
vim.opt.relativenumber = true;
vim.opt.rnu = true;
vim.opt.ruler = true;
vim.opt.tabstop = 8;
vim.opt.tf = true;
vim.opt.title = true;
vim.opt.vb = true;

View File

@@ -1,19 +0,0 @@
colorscheme torte
set bg=dark
set colorcolumn=80
set mouse=
set noautoindent
set nocp
set noexpandtab
set noim
set nois
set nu
set relativenumber
set rnu
set ruler
set tabstop=8
set tf
set title
set vb
set nowrap
syntax on

View File

@@ -1,22 +1,59 @@
#!/bin/sh
ls3(){
ls -1hlA --color=auto "$@";
}
#alias awk=nawk # not packaged for chimera
alias cls=clear
alias cp='cp -iv'
alias doas="$SUDO"
alias e="$EDITOR"
alias ls='lsd -1A --long --icon never'
if command -v lsd >/dev/null
then alias ls='lsd -1A --long --icon never'
else alias ls=ls3
fi
# shim for NetBSD X200 Tablet, Raspberry Pi 4B+
alias mpv='LIBGL_ALWAYS_SOFTWARE=1 mpv --vo=x11'
alias mpv='mpv --vo=x11'
alias mullvad="curl https://am.i.mullvad.net/connected"
alias mv='mv -iv'
# workaround for Arch Linux ARM 2025-03
alias nicotine="PYTHONPATH=/usr/lib/python3.11/site-packages/ nicotine"
alias obsd1='doas virsh net-start --network default'
alias obsd-1='doas virsh net-destroy --network default'
alias obsd2='\
doas qemu-system-aarch64 \
-enable-kvm -M virt -cpu host -m 1.5G \
-bios "$HOME"/Machines/QEMU_EFI.fd \
-device virtio-rng-device \
-device virtio-net,netdev=n0 \
-netdev bridge,id=n0,br=virbr0 \
-nographic \
-drive file="$HOME"/Machines/obsd.qcow2,media=disk,if=virtio \
'
alias obsd3='ssh 192.168.122.76'
# -nic user,model=virtio-net-pci \
alias p='ping 1.1.1.1'
alias secret="$SUDO mount /secret"
alias usecret="$SUDO umount /secret"
alias sensors='watch sensors'
alias sudo="$SUDO"
# please use responsibly
alias torrent="TORSOCKS_ALLOW_INBOUND=1 torsocks -d aria2c --disable-ipv6 --enable-dht=false"
alias units='units --history /dev/null'
alias v="$VISUAL"
# BEWARE -- injectable
# (though unauthorized $EDITOR $VISUAL modification is a problem on its own)
alias vidir="doas env EDITOR='$EDITOR' VISUAL='$VISUAL' vidir"
alias vidir="doas env VISUAL='$VISUAL' vidir"
alias winxp='
weisu qemu-system-x86_64 \
-M pc -cpu qemu64 -m 1G \
-rtc base=localtime \
-device VGA,vgamem_mb=64 \
-device rtl8139,netdev=n0 \
-netdev bridge,id=n0,br=virbr0 \
-usb -device usb-tablet \
-monitor stdio \
-hda "$HOME"/Machines/winxp.qcow2 \
'
alias youtube-dl=yt-dlp
alias yay=paru

View File

@@ -1,40 +1,61 @@
#!/bin/sh
BROWSER=netsurf-gtk; export BROWSER
CARGO_MOMMYS_LITTLE=cat/catgirl/girl/kitten/kitty/lass/lassie; export CARGO_MOMMYS_LITTLE
test -f /usr/lib/plan9 && PLAN9=/usr/lib/plan9
test -f /usr/local/plan9 && PLAN9=/usr/local/plan9
export PLAN9
EDITOR="$PLAN9/bin/sam -d"; export EDITOR
IRCNAME=dtb; export IRCNAME
IRCSERVER=feeling.murderu.us; export IRCSERVER
LIBGL_ALWAYS_SOFTWARE=1; export LIBGL_ALWAYS_SOFTWARE # Raspberry Pi shim
MANPATH="$MANPATH:/usr/pkg/man"
MOZ_ENABLE_WAYLAND=1; export MOZ_ENABLE_WAYLAND
if command -v bat >/dev/null
then PAGER=bat
elif command -v less >/dev/null
then PAGER=less
else
PAGER=more
fi
export PAGER
PATH="\
/bin:\
/sbin:\
/usr/bin:\
/usr/games:\
/usr/sbin:\
/usr/local/bin:\
/usr/local/sbin:\
/usr/X11R7/bin:\
/usr/pkg/bin:\
/usr/pkg/sbin:\
/usr/pkg/qt5/bin:\
/usr/X11R7/bin:\
/usr/local/bin:\
/usr/local/sbin:\
$HOME/bin/:\
$HOME/.local/bin:\
$HOME/src/dist:\
$PLAN9/bin:\
$PATH"; export PATH
PAGER=less; export PAGER
TERMINAL=urxvt; export TERMINAL
"; export PATH
TERMINAL=foot; export TERMINAL
UNITS_SYSTEM=si; export UNITS_SYSTEM
if command -v hx >/dev/null
if command -v nvim >/dev/null
then VISUAL=nvim
elif command -v vim >/dev/null
then VISUAL=vim
elif command -v hx >/dev/null
then VISUAL=hx
elif command -v vi >/dev/null
then VISUAL=vi
elif command -v kak >/dev/null
then VISUAL=kak
else
VISUAL=vi
fi
export VISUAL
WALLPAPER="$HOME/Pictures/Wallpapers/ghibli_wars.jpg"; export WALLPAPER
XDG_RUNTIME_DIR="/tmp/$(id -u)-runtime-dir"; export XDG_RUNTIME_DIR
# lowest to highest priority
command -v sudo >/dev/null 2>&1 && SUDO="sudo" && export SUDO
command -v doas >/dev/null 2>&1 && SUDO="doas" && export SUDO
command -v sudo >/dev/null 2>&1 && SUDO=sudo && export SUDO
command -v doas >/dev/null 2>&1 && SUDO=doas && export SUDO
ENV=$HOME/.env; export ENV
. $ENV
ENV="$HOME"/.env; export ENV
. "$ENV"

View File

@@ -13,9 +13,13 @@ bar {
}
font Unscii:size=12
position top
status_command while date +'%Y-%m-%dT%H:%M:%S'; do sleep 1; done
status_command bar
}
#bindsym Print exec grim
#bindsym XF86AudioLowerVolume exec pactl set-sink-volume @DEFAULT_SINK@
#bindsym XF86AudioRaiseVolume exec pactl set-sink-volume @DEFAULT_SINK@
bindsym $mod+1 workspace number 1
bindsym $mod+Shift+1 move container to workspace number 1
bindsym $mod+2 workspace number 2
@@ -37,8 +41,12 @@ mode "resize" {
bindsym Return mode "default"
}
bindsym $mod+Shift+r reload
bindsym $mod+Shift+i exec rpi-backlight on
bindsym $mod+Shift+o exec rpi-backlight off
bindsym $mod+d exec followtrail | wofi --show dmenu | xargs swaymsg exec --
#bindsym $mod+d exec followtrail | wofi --show dmenu | xargs swaymsg exec --
#bindsym $mod+d exec dmenu-wl_run -i
bindsym $mod+d exec rofi -show drun
bindsym $mod+f fullscreen
bindsym $mod+h focus left
bindsym $mod+Shift+h move left
@@ -53,6 +61,8 @@ bindsym $mod+Return exec foot
bindsym $mod+b splith
bindsym $mod+Shift+b exec $BROWSER
bindsym $mod+v splitv
bindsym XF86MonBrightnessDown exec rpi-backlight down
bindsym XF86MonBrightnessUp exec rpi-backlight up
bindsym $mod+space focus mode_toggle
bindsym $mod+Shift+space floating toggle
@@ -68,4 +78,11 @@ input "type:keyboard" {
xkb_options ctrl:nocaps
}
# ClockworkPi uConsole
output DSI-1 transform 90
# output DSI-1 disable
# output HDMI-A-1
include /etc/sway/config.d/*
exec mako

122
walk/walk.rs Normal file
View File

@@ -0,0 +1,122 @@
/*
* Copyright (c) 2024 DTB <trinity@trinity.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*
* This file incorporates work covered by the following copyright and permission
* notice:
*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use std::{
env::{args, current_dir},
fs::{read_dir, DirEntry},
path::Path,
};
extern crate getopt;
use getopt::{Opt, Parser};
extern crate sysexits;
use sysexits::{EX_SOFTWARE, EX_USAGE};
enum Terminator {
USER,
NUL,
NEWL,
ASV,
}
/* Recursively walks d, yielding all contained files and folders. */
fn walk(d: &Path, l: i8) -> impl Iterator<Item = DirEntry> {
assert!(d.is_dir());
// TODO: read_dir(d)??
for entry in read_dir(d)? {
let e = entry?;
yield e;
if e.is_dir() {
for f in walk(e.path(), l - 1)? {
yield f;
}
}
}
}
fn usage(s: &str) -> ExitCode {
eprintln!("Usage: {} (-0n) (-d [delimiter]) (-l [levels])", s);
ExitCode::from(EX_USAGE as u8)
}
fn main() -> ExitCode {
let argv = args().collect::<Vec<String>>();
let mut opts = Parser::new(&argv, "0d:l:nq");
let mut levels: i8 = -1;
let mut t: (Terminator, Option<String>) = (ASV, None);
loop {
match opts.next() {
None => break,
Some(opt) => match opt {
Ok(Opt('0', None)) => t = (NUL, None),
Ok(Opt('n', None)) => t = (NEWL, None),
Ok(Opt('d', Some(arg))) => t = (USER, arg),
Ok(Opt('l', Some(arg))) => match arg.parse::<u8>() {
Ok(l) => levels = l,
_ => {
return usage(&argv[0]);
}
},
_ => {
return usage(&argv[0]);
}
},
}
}
/* t.2 can only be Some if t.1 is USER */
assert_eq!(t.1 == USER, !t.2.is_none());
// if(*argv == NULL)
// argv = dot;
//
// {
// int retval;
//
// for(retval = 0; *argv != NULL; ++argv)
// if((retval = walk(*argv, levels, verbosity >= 2 ? argv0 : NULL))
// != EX_OK){
// if(verbosity >= 1)
// fprintf(stderr, "%s: %s: %s\n",
// argv0, *argv, strerror(errno));
// return retval;
// }
// }
EX_OK as u8
}