ref: 4ac3a0224ed9d54818f858fba69c8e94f38f2c12
author: Romano <[email protected]>
date: Tue Aug 13 01:53:34 EDT 2024
9front: add patches, both good and bad
--- /dev/null
+++ b/9front/2235c398fa9e7b48e0c84cda05c6994a14736e55.patch
@@ -1,0 +1,215 @@
+From: Romano <[email protected]>
+Date: Tue, 13 Aug 2024 05:33:53 +0000
+Subject: [PATCH] newuser:
+
+* make bin subdirs for all archs, as well as rc
+* make lib/drawterm user dir for drawterm-specific config
+** add lib/drawterm/default for default config
+* change console prompt to con#
+* update man page newuser source to match, and doc changes
+---
+diff c32dabd4853888f62f09a6d3f8e0deed4077b6a7 2235c398fa9e7b48e0c84cda05c6994a14736e55
+--- a/sys/lib/newuser
++++ b/sys/lib/newuser
+@@ -1,5 +1,4 @@
+ #!/bin/rc
+-
+ user=`{cat /dev/user}
+ home=/usr/$user
+ if(test -f $home/lib/profile){
+@@ -8,10 +7,10 @@
+ }
+ cd $home
+ x='$'
+-mkdir bin bin/rc bin/mips bin/386 bin/amd64 bin/power bin/arm bin/arm64
+-mkdir lib tmp
++mkdir bin/^('' rc spim arm arm64 amd64 386 power power64 mips)
++mkdir lib lib/drawterm tmp
+ chmod +t tmp
+-bind -qc /n/other/usr/$user/tmp $home/tmp
++if(test -d /n/other/usr/$user/tmp) bind -qc /n/other/usr/$user/tmp $home/tmp
+ bind -c $home/tmp /tmp
+ mail -c
+ auth/cron -c
+@@ -22,38 +21,41 @@
+ font=/lib/font/bit/vga/unicode.font
+ switch($x^service){
+ case terminal
+- webcookies
+- webfs
+- plumber
+ echo -n accelerated > '#m/mousectl'
+ echo -n 'res 3' > '#m/mousectl'
+ prompt=('term% ' ' ')
+ fn term%{ $x^* }
++ webcookies
++ webfs
++ plumber
+ rio
+ case cpu
+- bind /mnt/term/dev/cons /dev/cons
+- bind -q /mnt/term/dev/consctl /dev/consctl
+- >[2] /dev/null {
+- cp /dev/sysname /mnt/term/dev/label
+- if(wsys=`{cat /mnt/term/env/wsys} && ~ $x^#wsys 1) {
+- wsys=/mnt/term^$x^wsys
+- }
+- if not {
+- wsys=()
+- }
+- }
+- bind -a /mnt/term/dev /dev
++ # if rcpu or drawterm:
++ if(test -d /mnt/term/dev){
++ bind /mnt/term/dev/cons /dev/cons
++ bind -q /mnt/term/dev/consctl /dev/consctl
++ >[2] /dev/null {
++ cp /dev/sysname /mnt/term/dev/label
++ if(wsys=`{cat /mnt/term/env/wsys} && ~ $x^#wsys 1)
++ wsys=/mnt/term^$x^wsys
++ if not
++ wsys=()
++ }
++ bind -a /mnt/term/dev /dev
++ }
+ prompt=('cpu% ' ' ')
+ fn cpu%{ $x^* }
+- if(! test -e /mnt/term/dev/wsys){
+- # call from drawterm
+- if(test -e /mnt/term/dev/secstore){
+- auth/factotum -n
+- read -m /mnt/term/dev/secstore >/mnt/factotum/ctl
+- echo >/mnt/term/dev/secstore
+- }
+- if not
+- auth/factotum
++
++ # if drawterm, load profile based on incoming sysname:
++ if(test -d /mnt/term/cmd){
++ dtsys=`{cat /mnt/term/dev/sysname}
++ if(! test -f $x^home/lib/drawterm/^$x^dtsys)
++ dtsys=default
++ . $x^home/lib/drawterm/^$x^dtsys
++ }
++
++ # otherwise start the typical programs
++ if not if(! test -e /mnt/term/dev/wsys){
+ webcookies
+ webfs
+ plumber
+@@ -60,9 +62,25 @@
+ rio
+ }
+ case con
+- prompt=('cpu% ' ' ')
++ prompt=('con# ' ' ')
+ }
+ !
++
++cat > lib/drawterm/default <<!
++if(test -e /mnt/term/dev/secstore){
++ auth/factotum -n
++ read -m /mnt/term/dev/secstore >/mnt/factotum/ctl
++ echo >/mnt/term/dev/secstore
++}
++if not auth/factotum
++
++webcookies
++webfs
++plumber
++rio
++
++!
++
+ cat > lib/plumbing <<!
+ # to update: cp $$home/lib/plumbing /mnt/plumb/rules
+
+--- a/sys/man/8/newuser
++++ b/sys/man/8/newuser
+@@ -63,49 +63,61 @@
+ looks like this:
+ .IP
+ .EX
+-bind -a $home/bin/rc /bin
+-bind -a $home/bin/$cputype /bin
+-bind -c tmp /tmp
+-font = /lib/font/bit/pelm/euro.9.font
++bind -qa $home/bin/rc /bin
++bind -qa $home/bin/$cputype /bin
++font=/lib/font/bit/vga/unicode.font
+ switch($service){
+ case terminal
+- plumber
+- upas/fs
+ echo -n accelerated > '#m/mousectl'
+ echo -n 'res 3' > '#m/mousectl'
+ prompt=('term% ' ' ')
+ fn term%{ $* }
+- exec rio
++ webcookies
++ webfs
++ plumber
++ rio
+ case cpu
+- if (test -e /mnt/term/mnt/wsys) {
+- # rio already running
+- wsys = /mnt/term^`{cat /mnt/term/env/wsys}
+- bind -a /mnt/term/mnt/wsys /dev
+- echo -n $sysname > /dev/label
++ # if rcpu or drawterm:
++ if(test -d /mnt/term/dev){
++ bind /mnt/term/dev/cons /dev/cons
++ bind -q /mnt/term/dev/consctl /dev/consctl
++ >[2] /dev/null {
++ cp /dev/sysname /mnt/term/dev/label
++ if(wsys=`{cat /mnt/term/env/wsys} && ~ $#wsys 1)
++ wsys=/mnt/term^$wsys
++ if not
++ wsys=()
++ }
++ bind -a /mnt/term/dev /dev
+ }
+- bind /mnt/term/dev/cons /dev/cons
+- bind /mnt/term/dev/consctl /dev/consctl
+- bind -a /mnt/term/dev /dev
+ prompt=('cpu% ' ' ')
+ fn cpu%{ $* }
+- upas/fs
+- news
+- if (! test -e /mnt/term/mnt/wsys) {
+- # cpu call from drawterm
+- font=/lib/font/bit/pelm/latin1.8.font
+- auth/factotum
++
++ # if drawterm, load profile based on incoming sysname:
++ if(test -d /mnt/term/cmd){
++ dtsys=`{cat /mnt/term/dev/sysname}
++ if(! test -f $home/lib/drawterm/^$dtsys)
++ dtsys=default
++ . $home/lib/drawterm/^$dtsys
++ }
++
++ # otherwise start the typical programs
++ if not if(! test -e /mnt/term/dev/wsys){
++ webcookies
++ webfs
+ plumber
+- exec rio
++ rio
+ }
+ case con
+- prompt=('cpu% ' ' ')
+- news
++ prompt=('con# ' ' ')
+ }
+ .EE
+ .PP
+ Sites may make changes to
+ .B /sys/lib/newuser
+-that reflect the properties of the local environment.
++that reflect the properties of the local environment, as well as drawterm-specific
++loading changes under
++.B /usr/$user/lib/drawterm .
+ .SH "SEE ALSO"
+ .IR passwd (1),
+ .IR rio (1),
--- /dev/null
+++ b/9front/23b40c5aa93bb205423c8c40d02eef825011b215.patch
@@ -1,0 +1,17 @@
+From: Romano <[email protected]>
+Date: Thu, 11 Jul 2024 05:53:38 +0000
+Subject: [PATCH] add a couple items
+
+---
+diff c17447a0c0bc8211015c87261abe57ed46ffe0ca 23b40c5aa93bb205423c8c40d02eef825011b215
+--- a/lib/keyboard
++++ b/lib/keyboard
+@@ -548,6 +548,8 @@
+ 22C2 CA ⋂ n-ary intersection
+ 22C3 CU ⋃ n-ary union
+ 22C4 lz ⋄ diamond operator
++22D8 3< ⋘ very much less than
++22D9 3> ⋙ very much greater than
+ 22DC =< ⋜ equal to or less than
+ 22DD => ⋝ equal to or greater than
+ 22E6 <!~ ⋦ less than but not equivalent to
--- /dev/null
+++ b/9front/4b1f1c6fff2f186fe19bb2199dd963eb30e1ecd3.patch
@@ -1,0 +1,22 @@
+From: Romano <[email protected]>
+Date: Mon, 10 Jun 2024 04:42:52 +0000
+Subject: [PATCH] dhcpd(8): typos
+
+---
+diff 79455f36cf2b7fff2d789e014afe1df0e8b871cd 4b1f1c6fff2f186fe19bb2199dd963eb30e1ecd3
+--- a/sys/man/8/dhcpd
++++ b/sys/man/8/dhcpd
+@@ -334,11 +334,11 @@
+ (see
+ .IR regexp (6))
+ that is matched against the requested file name
+-and the second column contains a subsitution.
++and the second column contains a substitution.
+ Lines starting with
+ .B #
+ are ignored.
+-Occurances in the resulting filename of
++Occurrences in the resulting filename of
+ .BR %I ,
+ .B %C
+ or
--- /dev/null
+++ b/9front/559725a4c1048cb88e44cbb7a15d1c7990d2e465.patch
@@ -1,0 +1,180 @@
+From: Romano <[email protected]>
+Date: Sun, 30 Jun 2024 06:30:18 +0000
+Subject: [PATCH] merge 9front
+
+---
+diff 2350b084010b853275b822dddc3385d6ea876030 559725a4c1048cb88e44cbb7a15d1c7990d2e465
+--- a/sys/src/cmd/rio/dat.h
++++ b/sys/src/cmd/rio/dat.h
+@@ -46,11 +46,11 @@
+
+ enum
+ {
+- Selborder = 4, /* border of selected window */
+- Unselborder = 1, /* border of unselected window */
+- Scrollwid = 12, /* width of scroll bar */
+- Scrollgap = 4, /* gap right of scroll bar */
+- BIG = 3, /* factor by which window dimension can exceed screen */
++ Minselborder = 4, /* minimum border of selected window */
++ Minunselborder = 1, /* minimum border of unselected window */
++ Minscrollwid = 12, /* minimum width of scroll bar */
++ Minscrollgap = 4, /* minimum gap right of scroll bar */
++ BIG = 3, /* factor by which window dimension can exceed screen */
+ TRUE = 1,
+ FALSE = 0,
+ };
+@@ -341,3 +341,8 @@
+ int messagesize; /* negotiated in 9P version setup */
+ int shiftdown;
+ int debug;
++int Borderwid; /* border width of window */
++int Selborder; /* border of selected window */
++int Unselborder; /* border of unselected window */
++int Scrollwid; /* width of scroll bar */
++int Scrollgap; /* gap right of scroll bar */
+--- a/sys/src/cmd/rio/data.c
++++ b/sys/src/cmd/rio/data.c
+@@ -185,6 +185,16 @@
+ };
+
+ void
++fontinit(void)
++{
++ Borderwid = ceil(stringwidth(font, "0") / 4) > Borderwidth ? ceil(stringwidth(font, "0") / 4) : Borderwidth;
++ Selborder = ceil(stringwidth(font, "0") / 2) > Minselborder ? ceil(stringwidth(font, "0") / 2) : Minselborder;
++ Unselborder = ceil(stringwidth(font, "0") / 8) > Minunselborder ? ceil(stringwidth(font, "0") / 8) : Minunselborder;
++ Scrollwid = ceil(stringwidth(font, "0") * 1.5) > Minscrollwid ? ceil(stringwidth(font, "0") * 1.5) : Minscrollwid;
++ Scrollgap = ceil(stringwidth(font, "0") / 2) > Minscrollgap ? ceil(stringwidth(font, "0") / 2) : Minscrollgap;
++}
++
++void
+ iconinit(void)
+ {
+ background = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x777777FF);
+--- a/sys/src/cmd/rio/fns.h
++++ b/sys/src/cmd/rio/fns.h
+@@ -16,6 +16,7 @@
+ void error(char*);
+ void killprocs(void);
+ int shutdown(void*, char*);
++void fontinit(void);
+ void iconinit(void);
+ void *erealloc(void*, uint);
+ void *emalloc(uint);
+--- a/sys/src/cmd/rio/rio.c
++++ b/sys/src/cmd/rio/rio.c
+@@ -182,6 +182,7 @@
+ fprint(2, "rio: can't open display: %r\n");
+ exits("display open");
+ }
++ fontinit();
+ iconinit();
+
+ exitchan = chancreate(sizeof(int), 0);
+@@ -951,10 +952,10 @@
+ }
+ if(col != nil){
+ r = canonrect(r);
+- drawedge(&b[0], col, Rect(r.min.x, r.min.y, r.min.x+Borderwidth, r.max.y));
+- drawedge(&b[1], col, Rect(r.min.x+Borderwidth, r.min.y, r.max.x-Borderwidth, r.min.y+Borderwidth));
+- drawedge(&b[2], col, Rect(r.max.x-Borderwidth, r.min.y, r.max.x, r.max.y));
+- drawedge(&b[3], col, Rect(r.min.x+Borderwidth, r.max.y-Borderwidth, r.max.x-Borderwidth, r.max.y));
++ drawedge(&b[0], col, Rect(r.min.x, r.min.y, r.min.x+Borderwid, r.max.y));
++ drawedge(&b[1], col, Rect(r.min.x+Borderwid, r.min.y, r.max.x-Borderwid, r.min.y+Borderwid));
++ drawedge(&b[2], col, Rect(r.max.x-Borderwid, r.min.y, r.max.x, r.max.y));
++ drawedge(&b[3], col, Rect(r.min.x+Borderwid, r.max.y-Borderwid, r.max.x-Borderwid, r.max.y));
+ }
+ lastcol = col;
+ }
+--- a/sys/src/cmd/rio/wctl.c
++++ b/sys/src/cmd/rio/wctl.c
+@@ -100,13 +100,13 @@
+ * that includes the border on each side with an extra pixel
+ * so that the text is still drawn
+ */
+- if(Dx(r) < 100 || Dy(r) < 2*(Borderwidth+1)+font->height)
++ if(Dx(r) < 100 || Dy(r) < 2*(Borderwid+Unselborder)+font->height)
+ return 0;
+ /* window must be on screen */
+ if(!rectXrect(screen->r, r))
+ return 0;
+ /* must have some screen and border visible so we can move it out of the way */
+- if(rectinrect(screen->r, insetrect(r, Borderwidth)))
++ if(rectinrect(screen->r, insetrect(r, Borderwid)))
+ return 0;
+ return 1;
+ }
+@@ -148,8 +148,8 @@
+ static int i = 0;
+ int minx, miny, dx, dy;
+
+- dx = min(600, Dx(screen->r) - 2*Borderwidth);
+- dy = min(400, Dy(screen->r) - 2*Borderwidth);
++ dx = min(600, Dx(screen->r) - 2*Borderwid);
++ dy = min(400, Dy(screen->r) - 2*Borderwid);
+ minx = 32 + 16*i;
+ miny = 32 + 16*i;
+ i++;
+--- a/sys/src/cmd/rio/wind.c
++++ b/sys/src/cmd/rio/wind.c
+@@ -353,7 +353,7 @@
+
+ w->i = i;
+ w->mc.image = i;
+- r = insetrect(i->r, Selborder+1);
++ r = insetrect(i->r, Selborder+Unselborder);
+ w->scrollr = r;
+ w->scrollr.max.x = r.min.x+Scrollwid;
+ w->lastsr = ZR;
+@@ -1249,7 +1249,7 @@
+
+ w = emalloc(sizeof(Window));
+ w->screenr = i->r;
+- r = insetrect(i->r, Selborder+1);
++ r = insetrect(i->r,Selborder+Unselborder);
+ w->i = i;
+ w->mc = *mc;
+ w->ck = ck;
+--- a/sys/src/cmd/upas/send/message.c
++++ b/sys/src/cmd/upas/send/message.c
+@@ -1,6 +1,7 @@
+ #include "common.h"
+ #include "send.h"
+ #include <regexp.h>
++#include <ctype.h>
+ #include "../smtp/smtp.h"
+ #include "../smtp/rfc822.tab.h"
+
+@@ -18,6 +19,23 @@
+ static String* getstring(Node *p);
+ static String* getaddr(Node *p);
+
++char *
++userfrom(char *cp)
++{
++ char *s;
++ int n;
++
++ if((n = strlen(cp)) > 4 && cp[n-1] == '>'){
++ if((s = strrchr(cp, '<')) != nil && s != cp && isspace(s[-1])) {
++ s++;
++ cp[n-1] = '\0';
++ strcpy(cp, s);
++ }
++ }
++
++ return cp;
++}
++
+ int
+ default_from(message *mp)
+ {
+@@ -32,7 +50,7 @@
+ return -1;
+ }
+ if(cp && *cp)
+- s_append(mp->sender, cp);
++ s_append(mp->sender, userfrom(cp));
+ else
+ s_append(mp->sender, lp);
+ free(cp);
--- /dev/null
+++ b/9front/675bcd62992e59002c834ef445d515b346f4374d.patch
@@ -1,0 +1,181 @@
+From: Romano <[email protected]>
+Date: Fri, 12 Jul 2024 19:24:48 +0000
+Subject: [PATCH] rc: do not share certain special vars; fix $status bug for most cases
+
+
+Certain special vars (namely $*, $pid, $apid, and $status)
+are used internally and should not be set after a child
+returns.
+
+There has been a long-standing bug where checking the value
+of $status with ~ overwrites the value of $status. $status
+is now restored in most cases, other than running it
+as a standalone built-in command.
+
+Man page for rc is updated
+---
+diff 7637f8f5fd6490d07ba64bcf404321028e698ed9 675bcd62992e59002c834ef445d515b346f4374d
+--- a/sys/src/cmd/rc/code.c
++++ b/sys/src/cmd/rc/code.c
+@@ -275,6 +275,8 @@
+ codeswitch(t, eflag);
+ break;
+ case TWIDDLE:
++ if(c0 && c0->type=='$' && c0->child[0] && (c0->child[0]->type==WORD && strcmp(c0->child[0]->str, "status")==0))
++ emitf(Xstashstatus);
+ emitf(Xmark);
+ noglobs(c1, 1);
+ outcode(c1, eflag);
+--- a/sys/src/cmd/rc/exec.c
++++ b/sys/src/cmd/rc/exec.c
+@@ -282,6 +282,16 @@
+ dotrap();
+ }
+ }
++
++void
++unstashstatus(void)
++{
++ var *oldstatus = vlook("status-");
++ if(oldstatus->val && oldstatus->val->word){
++ setstatus(oldstatus->val->word);
++ }
++}
++
+ /*
+ * Opcode routines
+ * Arguments on stack (...)
+@@ -415,6 +425,7 @@
+ void
+ Xifnot(void)
+ {
++ unstashstatus();
+ if(ifnot)
+ runq->pc++;
+ else
+@@ -597,7 +608,9 @@
+ void
+ Xtrue(void)
+ {
+- if(truestatus()) runq->pc++;
++ int stat = truestatus();
++ unstashstatus();
++ if(stat) runq->pc++;
+ else runq->pc = runq->code[runq->pc].i;
+ }
+
+@@ -605,7 +618,9 @@
+ Xif(void)
+ {
+ ifnot = 1;
+- if(truestatus()) runq->pc++;
++ int stat = truestatus();
++ unstashstatus();
++ if(stat) runq->pc++;
+ else runq->pc = runq->code[runq->pc].i;
+ }
+
+@@ -661,6 +676,12 @@
+ }
+ poplist();
+ poplist();
++}
++
++void
++Xstashstatus(void)
++{
++ setvar("status-", Newword(estrdup(getstatus()), (word *)0));
+ }
+
+ void
+--- a/sys/src/cmd/rc/exec.h
++++ b/sys/src/cmd/rc/exec.h
+@@ -4,7 +4,7 @@
+ extern void Xappend(void), Xasync(void), Xbackq(void), Xbang(void), Xclose(void);
+ extern void Xconc(void), Xcount(void), Xdelfn(void), Xdol(void), Xqw(void), Xdup(void);
+ extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void);
+-extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void), Xhere(void), Xhereq(void);
++extern void Xjump(void), Xmark(void), Xmatch(void), Xstashstatus(void), Xpipe(void), Xread(void), Xhere(void), Xhereq(void);
+ extern void Xrdwr(void), Xsrcline(void);
+ extern void Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void);
+ extern void Xtrue(void), Xword(void), Xwrite(void), Xpipefd(void), Xcase(void);
+--- a/sys/src/cmd/rc/pfnc.c
++++ b/sys/src/cmd/rc/pfnc.c
+@@ -30,6 +30,7 @@
+ Xword, "Xword",
+ Xwrite, "Xwrite",
+ Xmatch, "Xmatch",
++ Xstashstatus, "Xstashstatus",
+ Xcase, "Xcase",
+ Xconc, "Xconc",
+ Xassign, "Xassign",
+--- a/sys/src/cmd/rc/plan9.c
++++ b/sys/src/cmd/rc/plan9.c
+@@ -144,7 +144,12 @@
+ if(n <= 0)
+ break;
+ for(i = 0; i<n; i++){
+- if(ent[i].length<=0 || strncmp(ent[i].name, "fn#", 3)==0)
++ if(ent[i].length<=0
++ || strncmp(ent[i].name, "fn#", 3)==0
++ || strcmp(ent[i].name,"*")==0
++ || strcmp(ent[i].name,"apid")==0
++ || strcmp(ent[i].name,"pid")==0
++ || strcmp(ent[i].name,"status")==0)
+ continue;
+ if((fd = Open(Env(ent[i].name, 0), 0))>=0){
+ io *f = openiofd(fd);
+--- a/sys/src/cmd/rc/test/updenvall.file
++++ b/sys/src/cmd/rc/test/updenvall.file
+@@ -78,3 +78,40 @@
+ echo d
+ }
+ ' '/env/fn#a is echo d'
++
++echo testing special vars
++*=b
++echo -n a > /env/'*'
++ok $"* 'b' '* not set'
++echo -n $"pid >/tmp/pid.rc.test
++rc -c ''
++ok $"pid `{cat /tmp/pid.rc.test} 'pid not set'
++rm /tmp/pid.rc.test
++echo -n `{apid=foobar; echo $apid} >/dev/null
++ok $"apid '' 'apid not set'
++echo -n foo > /env/status
++ok $"status '' 'status not set'
++status=foo
++~ $status foo
++ok $"status '' 'naked ~ sets status to '''''
++status=`{echo foo}
++ok $"status foo 'backtick sets status'
++if(~ $status foo)
++ ok $"status foo '$status'
++if(! ~ $status a)
++ ok $"status foo '$status for ! ~'
++if(~ $status a)
++ ;
++if not
++ ok $status foo '$status for if not'
++if(~ $"status foo)
++ ok $"status foo '$"status'
++if(echo a | grep -s a || ls)
++ ok $"status foo '||'
++while(! ~ $status foo)
++ status=bar
++ok $status foo 'after while not match'
++while(~ $status foo)
++ status=bar;
++ok $status bar 'after while match'
++status=''
+--- a/sys/src/cmd/rc/test/updenvall.rc
++++ b/sys/src/cmd/rc/test/updenvall.rc
+@@ -9,7 +9,7 @@
+ shift
+ desc=$1
+ if(~ $"actual $"expected) echo ok $desc
+- if not echo 'not ok '^$"desc^', got '$"actual
++ if not echo 'NOT OK '^$"desc^', got '$"actual
+ }
+
+ # now let's run the test with our build
--- /dev/null
+++ b/9front/7637f8f5fd6490d07ba64bcf404321028e698ed9.patch
@@ -1,0 +1,29 @@
+From: Romano <[email protected]>
+Date: Thu, 11 Jul 2024 05:56:24 +0000
+Subject: [PATCH] make "" use a fn that will then work with built-ins
+
+ currently "" does not work with built-ins, so re-running
+ built-ins might not have the desired effect (e.g., setting
+ environment variables, cd). This updates "" to be defined
+ internally as a function, which then update the parent
+ environment after being called.
+---
+diff 23b40c5aa93bb205423c8c40d02eef825011b215 7637f8f5fd6490d07ba64bcf404321028e698ed9
+--- a/rc/bin/""
++++ b/rc/bin/""
+@@ -1,5 +1,5 @@
+-#!/bin/rc
+-
++#!/bin/rc -b
++fn "" {
+ PROMPT='[^ ]*(%|;)+[ ]+'
+
+ _x = `{" $* | tail -1}
+@@ -10,4 +10,6 @@
+
+ echo ' ' $_x >[1=2]
+ _x=`{ echo -n 'eval '''; echo $_x | sed 's/^'$PROMPT'//; s/''/''''/g; s/$/''/'}
+-rc -c $"_x
++eval $"_x
++}
++"" $*
--- /dev/null
+++ b/9front/863b4ae53732ddeaf96dc23b0e9924651f2b4090.patch
@@ -1,0 +1,56 @@
+From: Romano <[email protected]>
+Date: Fri, 17 May 2024 08:08:34 +0000
+Subject: [PATCH] upas/send: parse e-mail descriptions like marshal
+
+
+/sys/src/cmd/upas/marshal/marshal.c:/^printfrom parses an e-mail with a
+description (e.g., "A Name <[email protected]>") and sets the from to
+just the e-mail address portion. This does the same for upas/send so that
+upasname='A name <[email protected]>' can be used to both set the From:
+in marshal with a description and to match the correct from in upas/send
+for sending via smtp.
+---
+diff e51d4aa069548de51d0e88a6d621d278e9138cd0 863b4ae53732ddeaf96dc23b0e9924651f2b4090
+--- a/sys/src/cmd/upas/send/message.c
++++ b/sys/src/cmd/upas/send/message.c
+@@ -1,6 +1,7 @@
+ #include "common.h"
+ #include "send.h"
+ #include <regexp.h>
++#include <ctype.h>
+ #include "../smtp/smtp.h"
+ #include "../smtp/rfc822.tab.h"
+
+@@ -18,6 +19,23 @@
+ static String* getstring(Node *p);
+ static String* getaddr(Node *p);
+
++char *
++userfrom(char *cp)
++{
++ char *s;
++ int n;
++
++ if((n = strlen(cp)) > 4 && cp[n-1] == '>'){
++ if((s = strrchr(cp, '<')) != nil && s != cp && isspace(s[-1])) {
++ s++;
++ cp[n-1] = '\0';
++ strcpy(cp, s);
++ }
++ }
++
++ return cp;
++}
++
+ int
+ default_from(message *mp)
+ {
+@@ -32,7 +50,7 @@
+ return -1;
+ }
+ if(cp && *cp)
+- s_append(mp->sender, cp);
++ s_append(mp->sender, userfrom(cp));
+ else
+ s_append(mp->sender, lp);
+ free(cp);
--- /dev/null
+++ b/9front/8a64e5171aad8bb0201a61e7df3046892ee6617f.patch
@@ -1,0 +1,17 @@
+From: Romano <[email protected]>
+Date: Wed, 03 Jul 2024 20:13:04 +0000
+Subject: [PATCH] avl: update example to use correct sig
+
+---
+diff f12775c520326e2c300a3346a7deb1a777a9e4f6 8a64e5171aad8bb0201a61e7df3046892ee6617f
+--- a/sys/man/2/avl
++++ b/sys/man/2/avl
+@@ -113,7 +113,7 @@
+ Node *h, n;
+
+ n.key = key;
+- h = (Node*)avllookup(t, &n);
++ h = (Node*)avllookup(t, &n, 0);
+ return h ? h->val : -1;
+ }
+ \fI\&...\fP
--- /dev/null
+++ b/9front/a94b1f5e58acf73619445c7c4f5eaa8c9e04dda5.patch
@@ -1,0 +1,180 @@
+From: Romano <[email protected]>
+Date: Thu, 20 Jun 2024 04:08:13 +0000
+Subject: [PATCH] merge
+
+---
+diff 107a7ba9717429ae34294d9afa804b5271157ab0 a94b1f5e58acf73619445c7c4f5eaa8c9e04dda5
+--- a/sys/src/cmd/rio/dat.h
++++ b/sys/src/cmd/rio/dat.h
+@@ -46,11 +46,11 @@
+
+ enum
+ {
+- Selborder = 4, /* border of selected window */
+- Unselborder = 1, /* border of unselected window */
+- Scrollwid = 12, /* width of scroll bar */
+- Scrollgap = 4, /* gap right of scroll bar */
+- BIG = 3, /* factor by which window dimension can exceed screen */
++ Minselborder = 4, /* minimum border of selected window */
++ Minunselborder = 1, /* minimum border of unselected window */
++ Minscrollwid = 12, /* minimum width of scroll bar */
++ Minscrollgap = 4, /* minimum gap right of scroll bar */
++ BIG = 3, /* factor by which window dimension can exceed screen */
+ TRUE = 1,
+ FALSE = 0,
+ };
+@@ -341,3 +341,8 @@
+ int messagesize; /* negotiated in 9P version setup */
+ int shiftdown;
+ int debug;
++int Borderwid; /* border width of window */
++int Selborder; /* border of selected window */
++int Unselborder; /* border of unselected window */
++int Scrollwid; /* width of scroll bar */
++int Scrollgap; /* gap right of scroll bar */
+--- a/sys/src/cmd/rio/data.c
++++ b/sys/src/cmd/rio/data.c
+@@ -185,6 +185,16 @@
+ };
+
+ void
++fontinit(void)
++{
++ Borderwid = ceil(stringwidth(font, "0") / 4) > Borderwidth ? ceil(stringwidth(font, "0") / 4) : Borderwidth;
++ Selborder = ceil(stringwidth(font, "0") / 2) > Minselborder ? ceil(stringwidth(font, "0") / 2) : Minselborder;
++ Unselborder = ceil(stringwidth(font, "0") / 8) > Minunselborder ? ceil(stringwidth(font, "0") / 8) : Minunselborder;
++ Scrollwid = ceil(stringwidth(font, "0") * 1.5) > Minscrollwid ? ceil(stringwidth(font, "0") * 1.5) : Minscrollwid;
++ Scrollgap = ceil(stringwidth(font, "0") / 2) > Minscrollgap ? ceil(stringwidth(font, "0") / 2) : Minscrollgap;
++}
++
++void
+ iconinit(void)
+ {
+ background = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x777777FF);
+--- a/sys/src/cmd/rio/fns.h
++++ b/sys/src/cmd/rio/fns.h
+@@ -16,6 +16,7 @@
+ void error(char*);
+ void killprocs(void);
+ int shutdown(void*, char*);
++void fontinit(void);
+ void iconinit(void);
+ void *erealloc(void*, uint);
+ void *emalloc(uint);
+--- a/sys/src/cmd/rio/rio.c
++++ b/sys/src/cmd/rio/rio.c
+@@ -182,6 +182,7 @@
+ fprint(2, "rio: can't open display: %r\n");
+ exits("display open");
+ }
++ fontinit();
+ iconinit();
+
+ exitchan = chancreate(sizeof(int), 0);
+@@ -951,10 +952,10 @@
+ }
+ if(col != nil){
+ r = canonrect(r);
+- drawedge(&b[0], col, Rect(r.min.x, r.min.y, r.min.x+Borderwidth, r.max.y));
+- drawedge(&b[1], col, Rect(r.min.x+Borderwidth, r.min.y, r.max.x-Borderwidth, r.min.y+Borderwidth));
+- drawedge(&b[2], col, Rect(r.max.x-Borderwidth, r.min.y, r.max.x, r.max.y));
+- drawedge(&b[3], col, Rect(r.min.x+Borderwidth, r.max.y-Borderwidth, r.max.x-Borderwidth, r.max.y));
++ drawedge(&b[0], col, Rect(r.min.x, r.min.y, r.min.x+Borderwid, r.max.y));
++ drawedge(&b[1], col, Rect(r.min.x+Borderwid, r.min.y, r.max.x-Borderwid, r.min.y+Borderwid));
++ drawedge(&b[2], col, Rect(r.max.x-Borderwid, r.min.y, r.max.x, r.max.y));
++ drawedge(&b[3], col, Rect(r.min.x+Borderwid, r.max.y-Borderwid, r.max.x-Borderwid, r.max.y));
+ }
+ lastcol = col;
+ }
+--- a/sys/src/cmd/rio/wctl.c
++++ b/sys/src/cmd/rio/wctl.c
+@@ -100,13 +100,13 @@
+ * that includes the border on each side with an extra pixel
+ * so that the text is still drawn
+ */
+- if(Dx(r) < 100 || Dy(r) < 2*(Borderwidth+1)+font->height)
++ if(Dx(r) < 100 || Dy(r) < 2*(Borderwid+Unselborder)+font->height)
+ return 0;
+ /* window must be on screen */
+ if(!rectXrect(screen->r, r))
+ return 0;
+ /* must have some screen and border visible so we can move it out of the way */
+- if(rectinrect(screen->r, insetrect(r, Borderwidth)))
++ if(rectinrect(screen->r, insetrect(r, Borderwid)))
+ return 0;
+ return 1;
+ }
+@@ -148,8 +148,8 @@
+ static int i = 0;
+ int minx, miny, dx, dy;
+
+- dx = min(600, Dx(screen->r) - 2*Borderwidth);
+- dy = min(400, Dy(screen->r) - 2*Borderwidth);
++ dx = min(600, Dx(screen->r) - 2*Borderwid);
++ dy = min(400, Dy(screen->r) - 2*Borderwid);
+ minx = 32 + 16*i;
+ miny = 32 + 16*i;
+ i++;
+--- a/sys/src/cmd/rio/wind.c
++++ b/sys/src/cmd/rio/wind.c
+@@ -353,7 +353,7 @@
+
+ w->i = i;
+ w->mc.image = i;
+- r = insetrect(i->r, Selborder+1);
++ r = insetrect(i->r, Selborder+Unselborder);
+ w->scrollr = r;
+ w->scrollr.max.x = r.min.x+Scrollwid;
+ w->lastsr = ZR;
+@@ -1249,7 +1249,7 @@
+
+ w = emalloc(sizeof(Window));
+ w->screenr = i->r;
+- r = insetrect(i->r, Selborder+1);
++ r = insetrect(i->r,Selborder+Unselborder);
+ w->i = i;
+ w->mc = *mc;
+ w->ck = ck;
+--- a/sys/src/cmd/upas/send/message.c
++++ b/sys/src/cmd/upas/send/message.c
+@@ -1,6 +1,7 @@
+ #include "common.h"
+ #include "send.h"
+ #include <regexp.h>
++#include <ctype.h>
+ #include "../smtp/smtp.h"
+ #include "../smtp/rfc822.tab.h"
+
+@@ -18,6 +19,23 @@
+ static String* getstring(Node *p);
+ static String* getaddr(Node *p);
+
++char *
++userfrom(char *cp)
++{
++ char *s;
++ int n;
++
++ if((n = strlen(cp)) > 4 && cp[n-1] == '>'){
++ if((s = strrchr(cp, '<')) != nil && s != cp && isspace(s[-1])) {
++ s++;
++ cp[n-1] = '\0';
++ strcpy(cp, s);
++ }
++ }
++
++ return cp;
++}
++
+ int
+ default_from(message *mp)
+ {
+@@ -32,7 +50,7 @@
+ return -1;
+ }
+ if(cp && *cp)
+- s_append(mp->sender, cp);
++ s_append(mp->sender, userfrom(cp));
+ else
+ s_append(mp->sender, lp);
+ free(cp);
--- /dev/null
+++ b/9front/c17447a0c0bc8211015c87261abe57ed46ffe0ca.patch
@@ -1,0 +1,233 @@
+From: Romano <[email protected]>
+Date: Thu, 11 Jul 2024 05:32:38 +0000
+Subject: [PATCH] rc: keep env vars and functions in sync
+
+
+ From env(3):
+ The env device serves a one-level directory containing files
+ with arbitrary names and contents. The intention is that
+ the file name is the name of an environment variable (see
+ rc(1)), and the content is the variable's current value.
+
+ And from rc(1):
+ Environment
+ The environment is a list of strings made available to exe-
+ cuting binaries by the env device (see env(3)).
+
+ But currently, the environment variables and functions are not kept
+ in sync with /env . For instance, '>/env/a echo -n b' will not
+ update $a to be 'b'. Also, even when the namespaces are shared
+ between processes, once the child process completes the namespaces
+ are out of sync.
+
+ This patch attempts to address that by updating the environment
+ variables and functions after children processes exit when the
+ children share the same namespace. Tests are added for the
+ functionality as well.
+---
+diff 8a64e5171aad8bb0201a61e7df3046892ee6617f c17447a0c0bc8211015c87261abe57ed46ffe0ca
+--- a/sys/src/cmd/rc/fns.h
++++ b/sys/src/cmd/rc/fns.h
+@@ -27,6 +27,7 @@
+ void Setstatus(char*);
+ void Trapinit(void);
+ void Updenv(void);
++void Updenvall(void);
+ void Vinit(void);
+ int Waitfor(int);
+ long Write(int, void*, long);
+--- a/sys/src/cmd/rc/havefork.c
++++ b/sys/src/cmd/rc/havefork.c
+@@ -64,6 +64,7 @@
+ setvar("apid", newword(npid, (word *)0));
+ break;
+ }
++ Updenvall();
+ }
+
+ void
+@@ -99,6 +100,7 @@
+ p->pid = pid;
+ break;
+ }
++ Updenvall();
+ }
+
+ /*
+@@ -128,7 +130,7 @@
+ Close(pfd[PRD]);
+ start(runq->code, runq->pc+1, runq->local, runq->redir);
+ pushredir(ROPEN, pfd[PWR], 1);
+- return;
++ break;
+ default:
+ addwaitpid(pid);
+ Close(pfd[PWR]);
+@@ -149,8 +151,9 @@
+ Waitfor(pid);
+
+ runq->pc = runq->code[runq->pc].i;
+- return;
++ break;
+ }
++ Updenvall();
+ }
+
+ void
+@@ -196,6 +199,7 @@
+ p->pc = p->code[pc+1].i;
+ break;
+ }
++ Updenvall();
+ }
+
+ void
+@@ -219,6 +223,7 @@
+ runq->pc = runq->code[runq->pc].i;
+ break;
+ }
++ Updenvall();
+ }
+
+ int
+--- a/sys/src/cmd/rc/plan9.c
++++ b/sys/src/cmd/rc/plan9.c
+@@ -259,6 +259,17 @@
+ }
+
+ void
++Updenvall(void)
++{
++ Vinit();
++ char *cmds = estrdup("for(fn in /env/fn'#'*) { . -bq $fn }\n");
++ int line = runq->line;
++ execcmds(openiocore(cmds, strlen(cmds)), estrdup(srcfile(runq)), runq->local, runq->redir);
++ runq->lex->line = line;
++ runq->lex->qflag = 1;
++}
++
++void
+ Exec(char **argv)
+ {
+ exec(argv[0], argv+1);
+--- a/sys/src/cmd/rc/simple.c
++++ b/sys/src/cmd/rc/simple.c
+@@ -102,6 +102,7 @@
+ /* interrupts don't get us out */
+ while(Waitfor(pid) < 0)
+ ;
++ Updenvall();
+ }
+ }
+ }
+--- /dev/null
++++ b/sys/src/cmd/rc/test/mkfile
+@@ -1,0 +1,6 @@
++</$objtype/mkfile
++
++TEST=\
++ updenvall\
++
++</sys/src/cmd/mktest
+--- /dev/null
++++ b/sys/src/cmd/rc/test/updenvall.file
+@@ -1,0 +1,80 @@
++>/env/var1 echo -n a
++ok `{whatis var1} 'var1=a
++' '$var1 is /env/var1'
++ok $var1 a '$var1 is a'
++ok `{cat /env/var1} a '/env/var1 is a'
++
++echo testing var with rc
++../$O.out -c 'var1=ab'
++ok `{whatis var1} 'var1=ab
++' 'var1 is ab'
++ok $var1 ab '$var1 is ab'
++ok `{cat /env/var1} ab '/env/var1 is ab'
++
++echo testing var with rc -c
++../$O.out -c 'var1=b'
++ok `{whatis var1} 'var1=b
++' 'var1 is b'
++ok $var1 b '$var1 is b'
++ok `{cat /env/var1} b '/env/var1 is b'
++
++echo testing var with subshell
++@{ var1=c }
++ok `{whatis var1} 'var1=c
++' 'var1 is c'
++ok $var1 c '$var1 is c'
++ok `{cat /env/var1} c '/env/var1 is c'
++
++echo testing var with backtick
++echo `{ var1=d } >/dev/null
++ok `{whatis var1} 'var1=d
++' 'var1 is d'
++ok $var1 d '$var1 is d'
++ok `{cat /env/var1} d '/env/var1 is d'
++
++a=()
++> '/env/fn#a' echo -n 'fn a {
++ echo a
++}
++'
++ok `{whatis a} 'fn a {
++ echo a
++}
++' 'fn a is echo a'
++ok `{cat '/env/fn#a'} 'fn a {
++ echo a
++}
++' '/env/fn#a is echo a'
++
++echo testing fn with rc -c
++../$O.out -c 'fn a { echo b }'
++ok `{whatis a} 'fn a {
++ echo b
++}
++' 'fn a is echo b'
++ok `{cat '/env/fn#a'} 'fn a {
++ echo b
++}
++' '/env/fn#a is echo b'
++
++echo testing fn with subshell
++@{ fn a { echo c } }
++ok `{whatis a} 'fn a {
++ echo c
++}
++' 'fn b is echo c'
++ok `{cat '/env/fn#a'} 'fn a {
++ echo c
++}
++' '/env/fn#a is echo c'
++
++echo testing fn with backtick
++echo `{fn a { echo d } } >/dev/null
++ok `{whatis a} 'fn a {
++ echo d
++}
++' 'fn a is echo d'
++ok `{cat '/env/fn#a'} 'fn a {
++ echo d
++}
++' '/env/fn#a is echo d'
+--- /dev/null
++++ b/sys/src/cmd/rc/test/updenvall.rc
+@@ -1,0 +1,16 @@
++#!/bin/rc
++# test that all environment variables and functions
++# are in sync.
++
++fn ok {
++ actual=$1
++ shift
++ expected=$1
++ shift
++ desc=$1
++ if(~ $"actual $"expected) echo ok $desc
++ if not echo 'not ok '^$"desc^', got '$"actual
++}
++
++# now let's run the test with our build
++../$O.out <updenvall.file
--- /dev/null
+++ b/9front/c32dabd4853888f62f09a6d3f8e0deed4077b6a7.patch
@@ -1,0 +1,42 @@
+From: Romano <[email protected]>
+Date: Fri, 12 Jul 2024 20:40:40 +0000
+Subject: [PATCH] rc: updated man page
+
+---
+diff 675bcd62992e59002c834ef445d515b346f4374d c32dabd4853888f62f09a6d3f8e0deed4077b6a7
+--- a/sys/man/1/rc
++++ b/sys/man/1/rc
+@@ -825,7 +825,13 @@
+ When
+ .I rc
+ starts executing it reads variable and function definitions from its
+-environment.
++environment, except for the special variables
++.BR $* ,
++.BR $pid ,
++and
++.BR $apid ,
++and
++.BR $status .
+ .SS Special Variables
+ The following variables are set or used by
+ .IR rc .
+@@ -1019,7 +1025,16 @@
+ .B ~
+ to check the value of
+ .B $status
+-changes
+-.BR $status .
++as a changes
++.BR $status
++when used alone as a built-in command. E.g.,
++.EX
++cpu% status=b; ~ $status a; echo $status
++no match
++cpu% status=b; if(~ $status a; echo $status) echo $status
++no match
++b
++cpu%
++.EE
+ .PP
+ Free carets don't get inserted next to keywords.
--- /dev/null
+++ b/9front/e51d4aa069548de51d0e88a6d621d278e9138cd0.patch
@@ -1,0 +1,142 @@
+From: Romano <[email protected]>
+Date: Thu, 09 May 2024 21:04:32 +0000
+Subject: [PATCH] rio: resize border and scrollbar based on font
+
+
+when using large fonts the scroll bar is aberrantly small, as is
+the border size. initialize the border widths and scroll widths
+based on the font size. set a minimum value based on existing
+hard-coded values.
+---
+diff 025a2d172ebfe36bc0da32f5712dd250916c73f1 e51d4aa069548de51d0e88a6d621d278e9138cd0
+--- a/sys/src/cmd/rio/dat.h
++++ b/sys/src/cmd/rio/dat.h
+@@ -46,11 +46,11 @@
+
+ enum
+ {
+- Selborder = 4, /* border of selected window */
+- Unselborder = 1, /* border of unselected window */
+- Scrollwid = 12, /* width of scroll bar */
+- Scrollgap = 4, /* gap right of scroll bar */
+- BIG = 3, /* factor by which window dimension can exceed screen */
++ Minselborder = 4, /* minimum border of selected window */
++ Minunselborder = 1, /* minimum border of unselected window */
++ Minscrollwid = 12, /* minimum width of scroll bar */
++ Minscrollgap = 4, /* minimum gap right of scroll bar */
++ BIG = 3, /* factor by which window dimension can exceed screen */
+ TRUE = 1,
+ FALSE = 0,
+ };
+@@ -341,3 +341,8 @@
+ int messagesize; /* negotiated in 9P version setup */
+ int shiftdown;
+ int debug;
++int Borderwid; /* border width of window */
++int Selborder; /* border of selected window */
++int Unselborder; /* border of unselected window */
++int Scrollwid; /* width of scroll bar */
++int Scrollgap; /* gap right of scroll bar */
+--- a/sys/src/cmd/rio/data.c
++++ b/sys/src/cmd/rio/data.c
+@@ -185,6 +185,16 @@
+ };
+
+ void
++fontinit(void)
++{
++ Borderwid = ceil(stringwidth(font, "0") / 4) > Borderwidth ? ceil(stringwidth(font, "0") / 4) : Borderwidth;
++ Selborder = ceil(stringwidth(font, "0") / 2) > Minselborder ? ceil(stringwidth(font, "0") / 2) : Minselborder;
++ Unselborder = ceil(stringwidth(font, "0") / 8) > Minunselborder ? ceil(stringwidth(font, "0") / 8) : Minunselborder;
++ Scrollwid = ceil(stringwidth(font, "0") * 1.5) > Minscrollwid ? ceil(stringwidth(font, "0") * 1.5) : Minscrollwid;
++ Scrollgap = ceil(stringwidth(font, "0") / 2) > Minscrollgap ? ceil(stringwidth(font, "0") / 2) : Minscrollgap;
++}
++
++void
+ iconinit(void)
+ {
+ background = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x777777FF);
+--- a/sys/src/cmd/rio/fns.h
++++ b/sys/src/cmd/rio/fns.h
+@@ -16,6 +16,7 @@
+ void error(char*);
+ void killprocs(void);
+ int shutdown(void*, char*);
++void fontinit(void);
+ void iconinit(void);
+ void *erealloc(void*, uint);
+ void *emalloc(uint);
+--- a/sys/src/cmd/rio/rio.c
++++ b/sys/src/cmd/rio/rio.c
+@@ -182,6 +182,7 @@
+ fprint(2, "rio: can't open display: %r\n");
+ exits("display open");
+ }
++ fontinit();
+ iconinit();
+
+ exitchan = chancreate(sizeof(int), 0);
+@@ -951,10 +952,10 @@
+ }
+ if(col != nil){
+ r = canonrect(r);
+- drawedge(&b[0], col, Rect(r.min.x, r.min.y, r.min.x+Borderwidth, r.max.y));
+- drawedge(&b[1], col, Rect(r.min.x+Borderwidth, r.min.y, r.max.x-Borderwidth, r.min.y+Borderwidth));
+- drawedge(&b[2], col, Rect(r.max.x-Borderwidth, r.min.y, r.max.x, r.max.y));
+- drawedge(&b[3], col, Rect(r.min.x+Borderwidth, r.max.y-Borderwidth, r.max.x-Borderwidth, r.max.y));
++ drawedge(&b[0], col, Rect(r.min.x, r.min.y, r.min.x+Borderwid, r.max.y));
++ drawedge(&b[1], col, Rect(r.min.x+Borderwid, r.min.y, r.max.x-Borderwid, r.min.y+Borderwid));
++ drawedge(&b[2], col, Rect(r.max.x-Borderwid, r.min.y, r.max.x, r.max.y));
++ drawedge(&b[3], col, Rect(r.min.x+Borderwid, r.max.y-Borderwid, r.max.x-Borderwid, r.max.y));
+ }
+ lastcol = col;
+ }
+--- a/sys/src/cmd/rio/wctl.c
++++ b/sys/src/cmd/rio/wctl.c
+@@ -100,13 +100,13 @@
+ * that includes the border on each side with an extra pixel
+ * so that the text is still drawn
+ */
+- if(Dx(r) < 100 || Dy(r) < 2*(Borderwidth+1)+font->height)
++ if(Dx(r) < 100 || Dy(r) < 2*(Borderwid+Unselborder)+font->height)
+ return 0;
+ /* window must be on screen */
+ if(!rectXrect(screen->r, r))
+ return 0;
+ /* must have some screen and border visible so we can move it out of the way */
+- if(rectinrect(screen->r, insetrect(r, Borderwidth)))
++ if(rectinrect(screen->r, insetrect(r, Borderwid)))
+ return 0;
+ return 1;
+ }
+@@ -148,8 +148,8 @@
+ static int i = 0;
+ int minx, miny, dx, dy;
+
+- dx = min(600, Dx(screen->r) - 2*Borderwidth);
+- dy = min(400, Dy(screen->r) - 2*Borderwidth);
++ dx = min(600, Dx(screen->r) - 2*Borderwid);
++ dy = min(400, Dy(screen->r) - 2*Borderwid);
+ minx = 32 + 16*i;
+ miny = 32 + 16*i;
+ i++;
+--- a/sys/src/cmd/rio/wind.c
++++ b/sys/src/cmd/rio/wind.c
+@@ -353,7 +353,7 @@
+
+ w->i = i;
+ w->mc.image = i;
+- r = insetrect(i->r, Selborder+1);
++ r = insetrect(i->r, Selborder+Unselborder);
+ w->scrollr = r;
+ w->scrollr.max.x = r.min.x+Scrollwid;
+ w->lastsr = ZR;
+@@ -1249,7 +1249,7 @@
+
+ w = emalloc(sizeof(Window));
+ w->screenr = i->r;
+- r = insetrect(i->r, Selborder+1);
++ r = insetrect(i->r,Selborder+Unselborder);
+ w->i = i;
+ w->mc = *mc;
+ w->ck = ck;
--- /dev/null
+++ b/9front/f12775c520326e2c300a3346a7deb1a777a9e4f6.patch
@@ -1,0 +1,28 @@
+From: Romano <[email protected]>
+Date: Sun, 30 Jun 2024 06:46:33 +0000
+Subject: [PATCH] 9p(2) minor typos
+
+---
+diff 559725a4c1048cb88e44cbb7a15d1c7990d2e465 f12775c520326e2c300a3346a7deb1a777a9e4f6
+--- a/sys/man/2/9p
++++ b/sys/man/2/9p
+@@ -241,8 +241,8 @@
+ .B RFNOTEG
+ and
+ .B RFMEM
+-flags. This isolates the service loop from the callers
+-namespace and from notes posted to the callers note group
++flags. This isolates the service loop from the caller's
++namespace and from notes posted to the caller's note group
+ but shares data and bss segments.
+ .IP
+ The child process then waits for the parent to copy its
+@@ -849,7 +849,7 @@
+ authenticated or will return -1 and
+ call
+ .I respond
+-with an apropiate error.
++with an appropriate error.
+ .I Authread
+ and
+ .I authwrite
--- /dev/null
+++ b/9front/f6228aa02e4fd3f7f5d1d2fa8b3a1e03afd2299a.patch
@@ -1,0 +1,32 @@
+From: Romano <[email protected]>
+Date: Tue, 13 Aug 2024 05:36:36 +0000
+Subject: [PATCH] riow: change shift+q → del as hotkey for deleting current window
+
+
+this helps particularly for OS X drawterm, since shift+q is already set for
+logging out. delete also clicked more with me since del is used for
+stopping a process.
+---
+diff 2235c398fa9e7b48e0c84cda05c6994a14736e55 f6228aa02e4fd3f7f5d1d2fa8b3a1e03afd2299a
+--- a/sys/man/1/riow
++++ b/sys/man/1/riow
+@@ -72,7 +72,7 @@
+ Spawn a new
+ .IR window (1).
+ .TP
+-.B Kmod4+shift+q
++.B Kmod4+del
+ Delete the current window.
+ .TP
+ .B Kmod4+h/j/k/l
+--- a/sys/src/cmd/riow.c
++++ b/sys/src/cmd/riow.c
+@@ -368,7 +368,7 @@
+ cycleaction(0, -1);
+ return 0;
+ }
+- if(r == 'Q' && mod == (Mmod4|Mshift)){
++ if(r == 0x7f && mod == Mmod4){
+ delete();
+ return 0;
+ }