OK, turing.

<- leave blank

Thu Oct 22 11:36:30 EDT 2020

#!/usr/bin/env python3

import os
from ctypes import CDLL
from time import sleep, monotonic
from operator import itemgetter
from sys import stdout, stderr, argv, exit
from re import search
from sre_constants import error as invalid_re
from signal import signal, SIGKILL, SIGTERM, SIGINT, SIGQUIT, SIGHUP, SIGUSR1,
SIGSTOP, SIGCONT
import threading
import shlex
from subprocess import Popen, TimeoutExpired


cmd_list = argv[1:]

psi_support = True


exit_d = dict()
exit_d[0] = False


def find_psi_metrics_value():
    """
    """
    psi_path = '/proc/pressure/memory'
    psi_metrics = 'full_avg10'

    if psi_support:

	if psi_metrics == 'some_avg10':
	    return float(rline1(psi_path).split(' ')[1].split('=')[1])
	if psi_metrics == 'some_avg60':
	    return float(rline1(psi_path).split(' ')[2].split('=')[1])
	if psi_metrics == 'some_avg300':
	    return float(rline1(psi_path).split(' ')[3].split('=')[1])

	if psi_metrics == 'full_avg10':
	    with open(psi_path) as f:
		psi_list = f.readlines()
		return float(psi_list[1].split(' ')[1].split('=')[1])
	if psi_metrics == 'full_avg60':
	    with open(psi_path) as f:
		psi_list = f.readlines()
		return float(psi_list[1].split(' ')[2].split('=')[1])
	if psi_metrics == 'full_avg300':
	    with open(psi_path) as f:
		psi_list = f.readlines()
		return float(psi_list[1].split(' ')[3].split('=')[1])

def exe(cmd):
    """ execute cmd in subprocess.Popen()
    """
    cmd_list = shlex.split(cmd)

    cmd_num_dict['cmd_num'] += 1
    cmd_num = cmd_num_dict['cmd_num']

    log('Execute the command ({}) in {}: {}'.format(
	cmd_num,
	threading.current_thread().getName(),
	cmd_list))
    t3 = monotonic()
    with Popen(cmd_list) as proc:
	try:
	    proc.wait(timeout=exe_timeout)
	    exit_status = proc.poll()
	    t4 = monotonic()
	    log('Command ({}) execution completed in {} sec; exit status'
		': {}'.format(cmd_num, round(t4 - t3, 3), exit_status))
	except TimeoutExpired:
	    proc.kill()
	    t4 = monotonic()
	    log('TimeoutExpired for the command ({}) in {} sec'.format(
		cmd_num, round(t4 - t3, 3)))

def pid_to_autogroup(pid):
    """
    """
    try:
	return rline1('/proc/{}/autogroup'.format(pid)).partition(
	    '/autogroup-')[2].partition(' nice ')[0]
    except IndexError:
	return None
    except FileNotFoundError:
	return None
    except ProcessLookupError:
	return None
    except AttributeError:
	return None

def rline1(path):
    """Read 1st line from the path."""
    try:
	with open(path) as f:
	    for line in f:
		return line.rstrip()
    except UnicodeDecodeError:
	with open(path, 'rb') as f:
	    return f.read(999).decode(
		'utf-8', 'ignore').split('\n')[0] # use partition()!


def exe(cmd_list):
    """ execute cmd in subprocess.Popen()
    """
    th_name = threading.current_thread().getName()
    t3 = monotonic()
    try:
	with Popen(cmd_list) as proc:
	    proc.wait()
	    exit_status = proc.poll()
	    t4 = monotonic()
	    print('Command execution completed in {}s; exit status:
	    {}'.format(round(t4 - t3, 3), exit_status))
	    exit_d[0] = True

    except Exception as e:
	print('Exception in {}: {}'.format(th_name, e))
	exit_d[0] = True


def start_thread(func, *a, **k):
    """ run function in a new thread
    """
    th = threading.Thread(target=func, args=a, kwargs=k, daemon=True)
    th_name = th.getName()

    print('Starting {} from {}'.format(
	th_name, threading.current_thread().getName()
    ))

    try:

	t1 = monotonic()
	th.start()
	t2 = monotonic()

	print('{} has started in {} ms, {} threads are '
	    'currently alive'.format(th_name, round((
		t2 - t1) * 1000, 1), threading.active_count()))

    except RuntimeError:
	print('RuntimeError: cannot start {}'.format(th_name))
	exit_d[0] = True
	return 1


def mlockall():
    """
    """
    MCL_CURRENT = 1
    MCL_FUTURE = 2
    MCL_ONFAULT = 4

    libc = CDLL('libc.so.6', use_errno=True)
    result = libc.mlockall(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT)

    if result != 0:
	result = libc.mlockall(MCL_CURRENT | MCL_FUTURE)
	if result != 0:
	    print('WARNING: cannot lock all memory: [Errno {}]'.format(result))
	else:
	    print('All memory locked with MCL_CURRENT | MCL_FUTURE')
    else:
	print('All memory locked with MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT')


# mlockall()


def alive_pid_list():
    """
    """
    pid_list = []

    proc_list = os.listdir('/proc')

    for pid in proc_list:

	if not pid[0].isdecimal():
	    continue

	pid_list.append(pid)

    return pid_list



def pid_to_name(pid):
    """
    """
    try:
	with open('/proc/{}/comm'.format(pid), 'rb', buffering=0) as f:
	    return f.read().decode('utf-8', 'ignore')[:-1]
    except FileNotFoundError:
	return ''
    except ProcessLookupError:
	return ''


self_pid = os.getpid()

self_au = pid_to_autogroup('self')


pid_list = alive_pid_list()
stop_pid_set = set()
for pid in pid_list:
    au = pid_to_autogroup(pid)
    if au == self_au:
	print(pid, au, pid_to_name(pid))
	stop_pid_set.add(pid)



start_thread(exe, cmd_list)






def cont():
    """
    """
    pid_list = alive_pid_list()

    for pid in pid_list:
	au = pid_to_autogroup(pid)
	name = pid_to_name(pid)

	if au == self_au:
	    if pid in stop_pid_set:
		# print('EXCLUDE', pid, au, name)
		continue
	    else:
		print('CONT', pid, name)
		try:
		    os.kill(int(pid), SIGCONT)
		except (ProcessLookupError, FileNotFoundError, PermissionError):
		    pass


def stop():
    """
    """
    pid_list = alive_pid_list()

    for pid in pid_list:
	au = pid_to_autogroup(pid)
	name = pid_to_name(pid)

	if au == self_au:
	    if pid in stop_pid_set:
		# print('EXCLUDE', pid, au, name)
		continue
	    else:
		print('STOP', pid, name)
		try:
		    os.kill(int(pid), SIGSTOP)
		except (ProcessLookupError, FileNotFoundError, PermissionError):
		    pass





def correction():
    """
    """
    stop()
    stop()
    sleep(interval)
    while True:

	if exit_d[0]:
	    cont()
	    cont()
	    exit()

	m = find_psi_metrics_value()
	print(m)

	if m > m_th:
	    sleep(interval)
	else:
	    cont()
	    break


m_th = 10
interval = 1


while True:
    # print('---------------------------------')

    if exit_d[0]:
	cont()
	cont()
	exit()

    m = find_psi_metrics_value()
    print(m)

    if m > m_th:
	correction()

    sleep(interval)



Thu Oct 22 10:55:36 EDT 2020
Hope you and your family are safe and well.

I work for Editorial PR based here in London.  We have a client that is
potentially looking for
coverage on your site.

Do you provide article-based promotion at all for clients?

If you do, it would be great to work with you.

We are also always looking for ways to increase our customers visibility online so
if you have
any other sites you think our clients would be interested in advertising on, we
would love to
see them.

 I am currently working on a rolling 25-day budget so if you could come back as
soon as possible with your terms of business it would be appreciated.

We look forward to hearing from you

Kind Regards,

Thu Oct 22 09:50:17 EDT 2020
-- Logs begin at Mon 2020-10-19 10:14:09 EDT, end at Thu 2020-10-22 09:48:45 EDT.
--
Oct 22 09:43:41 user-virtualbox systemd[1]: Started Daemon that prevents eviction
of executables/libraries from memory.
Oct 22 09:43:41 user-virtualbox systemd[344]: prelockd.service: Failed to
determine user credentials: No such process
Oct 22 09:43:41 user-virtualbox systemd[344]: prelockd.service: Failed at step
USER spawning /usr/bin/prelockd: No such process
Oct 22 09:43:41 user-virtualbox systemd[1]: prelockd.service: Main process exited,
code=exited, status=217/USER
Oct 22 09:43:41 user-virtualbox systemd[1]: prelockd.service: Failed with result
'exit-code'.
[user@user-virtualbox ~]$ cat /etc/passwd
root:x:0:0::/root:/bin/bash
bin:x:1:1::/:/usr/bin/nologin
daemon:x:2:2::/:/usr/bin/nologin
mail:x:8:12::/var/spool/mail:/usr/bin/nologin
ftp:x:14:11::/srv/ftp:/usr/bin/nologin
http:x:33:33::/srv/http:/usr/bin/nologin
nobody:x:65534:65534:Nobody:/:/usr/bin/nologin
dbus:x:81:81:System Message Bus:/:/usr/bin/nologin
systemd-journal-remote:x:982:982:systemd Journal Remote:/:/usr/bin/nologin
systemd-network:x:981:981:systemd Network Management:/:/usr/bin/nologin
systemd-resolve:x:980:980:systemd Resolver:/:/usr/bin/nologin
systemd-timesync:x:979:979:systemd Time Synchronization:/:/usr/bin/nologin
systemd-coredump:x:978:978:systemd Core Dumper:/:/usr/bin/nologin
uuidd:x:68:68::/:/usr/bin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/usr/bin/nologin
avahi:x:974:974:Avahi mDNS/DNS-SD daemon:/:/usr/bin/nologin
named:x:40:40:BIND DNS Server:/:/usr/bin/nologin
colord:x:973:973:Color management daemon:/var/lib/colord:/usr/bin/nologin
cups:x:209:209:cups helper user:/:/usr/bin/nologin
deluge:x:972:972:Deluge BitTorrent daemon:/srv/deluge:/usr/bin/nologin
dnsmasq:x:971:971:dnsmasq daemon:/:/usr/bin/nologin
geoclue:x:970:970:Geoinformation service:/var/lib/geoclue:/usr/bin/nologin
git:x:969:969:git daemon user:/:/usr/bin/git-shell
lightdm:x:968:968:Light Display Manager:/var/lib/lightdm:/usr/bin/nologin
nm-openconnect:x:967:967:NetworkManager OpenConnect:/:/usr/bin/nologin
nm-openvpn:x:966:966:NetworkManager OpenVPN:/:/usr/bin/nologin
ntp:x:87:87:Network Time Protocol:/var/lib/ntp:/bin/false
ldap:x:439:439:LDAP Server:/var/lib/openldap:/usr/bin/nologin
polkitd:x:102:102:PolicyKit daemon:/:/usr/bin/nologin
rtkit:x:133:133:RealtimeKit:/proc:/usr/bin/nologin
usbmux:x:140:140:usbmux user:/:/usr/bin/nologin
user:x:1000:1000:user:/home/user:/bin/zsh
memavaild:x:965:965::/home/memavaild:/bin/false


Wed Oct 21 20:27:22 EDT 2020
diff -r bdd5a746e8c5 sys/src/cmd/rc/code.c
--- a/sys/src/cmd/rc/code.c Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/code.c Wed Oct 21 17:27:22 2020 -0700
@@ -6,10 +6,12 @@
 #define c0 t->child[0]
 #define c1 t->child[1]
 #define c2 t->child[2]
+code *codebuf;
 int codep, ncode;
 #define emitf(x) ((codep!=ncode || morecode()), codebuf[codep].f = (x), codep++)
 #define emiti(x) ((codep!=ncode || morecode()), codebuf[codep].i = (x), codep++)
 #define emits(x) ((codep!=ncode || morecode()), codebuf[codep].s = (x), codep++)
+
 void stuffdot(int);
 char *fnstr(tree*);
 void outcode(tree*, int);
@@ -37,9 +39,9 @@
 int
 compile(tree *t)
 {
+ codep = 0;
	ncode = 100;
- codebuf = (code *)emalloc(ncode*sizeof codebuf[0]);
- codep = 0;
+ codebuf = emalloc(ncode*sizeof codebuf[0]);
	emiti(0); /* reference count */
	outcode(t, flag['e']?1:0);
	if(nerror){
@@ -79,12 +81,28 @@
 void
 outcode(tree *t, int eflag)
 {
- int p, q;
+ static int file, line;
+ int p, q, f, l;
	tree *tt;
	if(t==0)
		return;
	if(t->type!=NOT && t->type!=';')
		runq->iflast = 0;
+ if(t->file != file || t->line != line){
+ file = t->file;
+ line = t->line;
+
+ /*
+ * These are small enough that with a ton of sourcing,
+ * overflow is a realistic risk.  If we run out of files,
+ * set to file 0, which is always '???'
+ */
+ f = (t->file > LFMAX) ? 0 : t->file << LSHIFT;
+ l = (t->line > LMASK) ? -1 : t->line;
+
+ emitf(Xloc);
+ emiti(f|l);
+ }
	switch(t->type){
	default:
		pfmt(err, "bad type %d in outcode\n", t->type);
diff -r bdd5a746e8c5 sys/src/cmd/rc/exec.c
--- a/sys/src/cmd/rc/exec.c Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/exec.c Wed Oct 21 17:27:22 2020 -0700
@@ -14,6 +14,7 @@
	struct thread *p = new(struct thread);

	p->code = codecopy(c);
+ p->loc = 0;
	p->pc = pc;
	p->argv = 0;
	p->redir = p->startredir = runq?runq->redir:0;
@@ -205,6 +206,11 @@
	pushlist();
	argv0 = estrdup(argv[0]);
	for(i = argc-1;i!=0;--i) pushword(argv[i]);
+
+ lexpath = erealloc(lexpath, sizeof(char*));
+ nlexpath = 1;
+ lexpath[0] = strdup("???");
+
	for(;;){
		if(flag['r'])
			pfnc(err, runq);
@@ -953,10 +959,15 @@
 void
 Xerror(char *s)
 {
+ int f, l;
+
+ f = runq->loc >> LSHIFT;
+ l = runq->loc & LMASK;
+ assert(f >= 0 && f < nlexpath);
	if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
- pfmt(err, "rc: %s: %r\n", s);
+ pfmt(err, "rc:%d: %s: %r\n", l, s);
	else
- pfmt(err, "rc (%s): %s: %r\n", argv0, s);
+ pfmt(err, "%s:%d: %s: %r\n", lexpath[f], l, s);
	flush(err);
	setstatus("error");
	while(!runq->iflag) Xreturn();
@@ -965,10 +976,15 @@
 void
 Xerror1(char *s)
 {
+ int f, l;
+
+ f = runq->loc >> LSHIFT;
+ l = runq->loc & LMASK;
+ assert(f >= 0 && f < nlexpath);
	if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
- pfmt(err, "rc: %s\n", s);
+ pfmt(err, "rc:%d: %s\n", l, s);
	else
- pfmt(err, "rc (%s): %s\n", argv0, s);
+ pfmt(err, "%s:%d: %s\n", lexpath[f], l, s);
	flush(err);
	setstatus("error");
	while(!runq->iflag) Xreturn();
@@ -1025,3 +1041,10 @@
 {
	globlist(runq->argv->words);
 }
+
+void
+Xloc(void)
+{
+ runq->loc = runq->code[runq->pc].i;
+ runq->pc++;
+}
diff -r bdd5a746e8c5 sys/src/cmd/rc/exec.h
--- a/sys/src/cmd/rc/exec.h Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/exec.h Wed Oct 21 17:27:22 2020 -0700
@@ -5,7 +5,7 @@
 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);
-extern void Xrdwr(void);
+extern void Xrdwr(void), Xloc(void);
 extern void Xrdfn(void), Xunredir(void), Xstar(void), Xreturn(void),
 Xsubshell(void);
 extern void Xtrue(void), Xword(void), Xglobs(void), Xwrite(void), Xpipefd(void),
 Xcase(void);
 extern void Xlocal(void), Xunlocal(void), Xassign(void), Xsimple(void),
 Xpopm(void);
@@ -30,7 +30,7 @@
 struct redir{
	char type; /* what to do */
	short from, to; /* what to do it to */
- struct redir *next; /* what else to do (reverse order) */
+ redir *next; /* what else to do (reverse order) */
 };
 #define NSTATUS ERRMAX /* length of status (from plan 9) */
 /*
@@ -40,14 +40,15 @@
 #define RDUP 2 /* dup2(from, to); */
 #define RCLOSE 3 /* close(from); */
 struct thread{
- union code *code; /* code for this thread */
+ code *code; /* code for this thread */
	int pc; /* code[pc] is the next instruction */
- struct list *argv; /* argument stack */
- struct redir *redir; /* redirection stack */
- struct redir *startredir; /* redir inheritance point */
- struct var *local; /* list of local variables */
+ int loc; /* source code location */
+ list *argv; /* argument stack */
+ redir *redir; /* redirection stack */
+ redir *startredir; /* redir inheritance point */
+ var *local; /* list of local variables */
	char *cmdfile; /* file name in Xrdcmd */
- struct io *cmdfd; /* file descriptor for Xrdcmd */
+ io *cmdfd; /* file descriptor for Xrdcmd */
	int iflast; /* static `if not' checking */
	int eof; /* is cmdfd at eof?  */
	int iflag; /* interactive?  */
@@ -55,7 +56,7 @@
	int pid; /* process for Xpipewait to wait for */
	char status[NSTATUS]; /* status for Xpipewait */
	tree *treenodes; /* tree nodes created by this process */
- thread *ret; /* who continues when this finishes */
+ thread *ret; /* who continues when this finishes */
 };
 thread *runq;
 code *codecopy(code*);
diff -r bdd5a746e8c5 sys/src/cmd/rc/lex.c
--- a/sys/src/cmd/rc/lex.c Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/lex.c Wed Oct 21 17:27:22 2020 -0700
@@ -25,6 +25,13 @@
 int doprompt = 1;
 int inquote;
 int incomm;
+int lastc;
+int ndot;
+int nerror;
+int lexline;
+int lexfile;
+char **lexpath;
+int nlexpath;
 /*
  * Look ahead in the input stream
  */
@@ -39,13 +46,14 @@
 /*
  * Consume the lookahead character.
  */
-
 int
 advance(void)
 {
	int c = nextc();
	lastc = future;
	future = EOF;
+ if(c == '\n')
+ lexline++;
	return c;
 }
 /*
diff -r bdd5a746e8c5 sys/src/cmd/rc/pfnc.c
--- a/sys/src/cmd/rc/pfnc.c Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/pfnc.c Wed Oct 21 17:27:22 2020 -0700
@@ -51,6 +51,7 @@
	Xrdfn, "Xrdfn",
	Xsimple, "Xsimple",
	Xqw, "Xqw",
+ Xloc, "Xloc",
 0};

 void
diff -r bdd5a746e8c5 sys/src/cmd/rc/rc.h
--- a/sys/src/cmd/rc/rc.h Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/rc.h Wed Oct 21 17:27:22 2020 -0700
@@ -43,6 +43,8 @@
	char *str;
	int quoted;
	int iskw;
+ int file;
+ int line;
	tree *child[3];
	tree *next;
 };
@@ -54,6 +56,19 @@
 tree *simplemung(tree*), *heredoc(tree*);
 void freetree(tree*);
 tree *cmdtree;
+
+/*
+ * Locations are stored as instructions in the rc bytecode.
+ * To avoid wasting too much space, both the file and line
+ * is packed into a single integer, as
+ * (file << LSHIFT) | line
+ * With 32 bit integers, this gives us 2048 filenames, with
+ * just over 1 million lines of code in each.
+ */
+#define LSHIFT 20
+#define LMASK ((1<<LSHIFT)-1)
+#define LFMAX (1<<(8*sizeof(int)-LSHIFT-1))
+
 /*
  * The first word of any code vector is a reference count.
  * Always create a new reference to a code vector by calling codecopy(.).
@@ -126,10 +141,15 @@
  */
 #define onebyte(c) ((c&0x80)==0x00)

-char **argp;
-char **args;
-int nerror; /* number of errors encountered during compilation */
-int doprompt; /* is it time for a prompt?  */
+extern char **argp;
+extern char **args;
+extern int nerror; /* number of errors encountered during compilation */
+extern int doprompt; /* is it time for a prompt?  */
+extern int lexfile;
+extern int lexline;
+extern char **lexpath;
+extern int nlexpath;
+
 /*
  * Which fds are the reading/writing end of a pipe?
  * Unfortunately, this can vary from system to system.
@@ -143,7 +163,7 @@
  * How many dot commands have we executed?
  * Used to ensure that -v flag doesn't print rcmain.
  */
-int ndot;
+extern int ndot;
+extern int lastc;
+extern int lastword;
 char *getstatus(void);
-int lastc;
-int lastword;
diff -r bdd5a746e8c5 sys/src/cmd/rc/simple.c
--- a/sys/src/cmd/rc/simple.c Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/simple.c Wed Oct 21 17:27:22 2020 -0700
@@ -11,7 +11,7 @@
  */
 int
 exitnext(void){
- union code *c=&runq->code[runq->pc];
+ code *c=&runq->code[runq->pc];
	while(c->f==Xpopredir || c->f==Xunlocal) c++;
	return c->f==Xexit;
 }
@@ -294,7 +294,7 @@
 execdot(void)
 {
	int iflag = 0;
- int fd;
+ int fd, i;
	list *av;
	thread *p = runq;
	char *zero, *file;
@@ -354,6 +354,22 @@
		Xerror(".: can't open");
		return;
	}
+
+ lexline = 1;
+ for(i = 0; i < nlexpath; i++){
+ if(strcmp(lexpath[i], zero) == 0){
+ lexfile = i;
+ break;
+ }
+ }
+ if(i == nlexpath){
+ if(nlexpath < LFMAX){
+ lexpath = erealloc(lexpath, (nlexpath + 1)*sizeof(char*));
+ lexpath[nlexpath] = estrdup(zero);
+ lexfile = nlexpath++;
+ }else
+ lexfile = 0;
+ }
	/* set up for a new command loop */
	start(dotcmds, 1, (struct var *)0);
	pushredir(RCLOSE, fd, 0);
diff -r bdd5a746e8c5 sys/src/cmd/rc/tree.c
--- a/sys/src/cmd/rc/tree.c Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/tree.c Wed Oct 21 17:27:22 2020 -0700
@@ -16,6 +16,8 @@
	t->str = 0;
	t->child[0] = t->child[1] = t->child[2] = 0;
	t->next = treenodes;
+ t->file = lexfile;
+ t->line = lexline;
	treenodes = t;
	return t;
 }


Wed Oct 21 13:24:42 EDT 2020
--- /mnt/git/object/b373c36d4caecfdbcd6d0833c11092893fcb770c/tree/./clone Fri Oct
9 08:48:32 2020
+++ ./clone Wed Oct 21 10:16:57 2020
@@ -33,13 +33,23 @@ fn clone{
		echo ' fetch=+refs/heads/*:refs/remotes/origin/*'
	}
	{git/fetch $debug $remote >[2=3] | awk '
- /^remote/{
+ BEGIN{
+ headref=""
+ headhash=""
+ }
+ /^symref /{
+ if($2 == "HEAD"){
+ gsub("^refs/heads", "refs/remotes/origin", $3)
+ gsub("^refs/tags", "refs/remotes/origin/tags", $3)
+ headref=$3
+ }
+ }
+ /^remote /{
			if($2=="HEAD"){
				headhash=$3
- headref=""
- }else{
+ }else if(match($2, "^refs/(heads|tags)/")){
				gsub("^refs/heads", "refs/remotes/origin", $2)
- if($2 == "refs/remotes/origin/master" || $3 == headhash)
+ if($2 == headref || (headref == "" && $3 == headhash))
					headref=$2
				outfile = ".git/" $2
				outdir = outfile
--- /mnt/git/object/b373c36d4caecfdbcd6d0833c11092893fcb770c/tree/./fetch.c Fri
Oct 9 08:48:32 2020
+++ ./fetch.c Wed Oct 21 10:20:11 2020
@@ -135,18 +135,46 @@ branchmatch(char *br, char *pat)
	return strcmp(br, name) == 0;
 }

+char *
+matchcap(char *s, char *cap, int full)
+{
+ if(strncmp(s, cap, strlen(cap)) == 0)
+ if(!full || strlen(s) == strlen(cap))
+ return s + strlen(cap);
+ return nil;
+}
+
+void
+handlecaps(char *caps)
+{
+ char *p, *n, *c, *r;
+
+ for(p = caps; p != nil; p = n){
+ n = strchr(p, ' ');
+ if(n != nil)
+ *n++ = 0;
+ if((c = matchcap(p, "symref=", 0)) != nil){
+ if((r = strchr(c, ':')) != nil){
+ *r++ = '\0';
+ print("symref %s %s\n", c, r);
+ }
+ }
+ }
+}
+
 int
 fetchpack(Conn *c, int pfd, char *packtmp)
 {
	char buf[Pktmax], idxtmp[256], *sp[3];
	Hash h, *have, *want;
- int nref, refsz;
+ int nref, refsz, first;
	int i, n, req;
	vlong packsz;
	Object *o;

	nref = 0;
	refsz = 16;
+ first = 1;
	have = emalloc(refsz * sizeof(have[0]));
	want = emalloc(refsz * sizeof(want[0]));
	while(1){
@@ -157,6 +185,11 @@ fetchpack(Conn *c, int pfd, char *packtm
			break;
		if(strncmp(buf, "ERR ", 4) == 0)
			sysfatal("%s", buf + 4);
+
+ if(first && n > strlen(buf))
+ handlecaps(buf + strlen(buf) + 1);
+ first = 0;
+
		getfields(buf, sp, nelem(sp), 1, " \t\n\r");
		if(strstr(sp[1], "^{}"))
			continue;


Wed Oct 21 12:03:54 EDT 2020
--- /mnt/git/object/b373c36d4caecfdbcd6d0833c11092893fcb770c/tree/./clone Fri Oct
9 08:48:32 2020
+++ ./clone Wed Oct 21 09:03:43 2020
@@ -33,13 +33,16 @@ fn clone{
		echo ' fetch=+refs/heads/*:refs/remotes/origin/*'
	}
	{git/fetch $debug $remote >[2=3] | awk '
- /^remote/{
+ /^symref /{
+ if($2 == "HEAD")
+ headref=$3
+ }
+ /^remote /{
			if($2=="HEAD"){
				headhash=$3
- headref=""
			}else{
				gsub("^refs/heads", "refs/remotes/origin", $2)
- if($2 == "refs/remotes/origin/master" || $3 == headhash)
+ if($2 == headref || (headref == "") && $3 == headhash)
					headref=$2
				outfile = ".git/" $2
				outdir = outfile
--- /mnt/git/object/b373c36d4caecfdbcd6d0833c11092893fcb770c/tree/./fetch.c Fri
Oct 9 08:48:32 2020
+++ ./fetch.c Wed Oct 21 08:55:47 2020
@@ -135,18 +135,46 @@ branchmatch(char *br, char *pat)
	return strcmp(br, name) == 0;
 }

+char *
+matchcap(char *s, char *cap, int full)
+{
+ if(strncmp(s, cap, strlen(cap)) == 0)
+ if(!full || strlen(s) == strlen(cap))
+ return s + strlen(cap);
+ return nil;
+}
+
+void
+handlecaps(char *caps)
+{
+ char *p, *n, *c, *r;
+
+ for(p = caps; p != nil; p = n){
+ n = strchr(p, ' ');
+ if(n != nil)
+ *n++ = 0;
+ if((c = matchcap(p, "symref=", 0)) != nil){
+ if((r = strchr(c, ':')) != nil){
+ *r++ = '\0';
+ print("symref %s %s\n", c, r);
+ }
+ }
+ }
+}
+
 int
 fetchpack(Conn *c, int pfd, char *packtmp)
 {
	char buf[Pktmax], idxtmp[256], *sp[3];
	Hash h, *have, *want;
- int nref, refsz;
+ int nref, refsz, first;
	int i, n, req;
	vlong packsz;
	Object *o;

	nref = 0;
	refsz = 16;
+ first = 1;
	have = emalloc(refsz * sizeof(have[0]));
	want = emalloc(refsz * sizeof(want[0]));
	while(1){
@@ -157,6 +185,8 @@ fetchpack(Conn *c, int pfd, char *packtm
			break;
		if(strncmp(buf, "ERR ", 4) == 0)
			sysfatal("%s", buf + 4);
+ if(first && n > strlen(buf))
+ handlecaps(buf + strlen(buf) + 1);
		getfields(buf, sp, nelem(sp), 1, " \t\n\r");
		if(strstr(sp[1], "^{}"))
			continue;
@@ -172,6 +202,7 @@ fetchpack(Conn *c, int pfd, char *packtm
		if (resolveremote(&have[nref], sp[1]) == -1)
			memset(&have[nref], 0, sizeof(have[nref]));
		print("remote %s %H local %H\n", sp[1], want[nref], have[nref]);
+ first = 0;
		nref++;
	}
	if(listonly){


Wed Oct 21 11:27:11 EDT 2020
symref
------

This parameterized capability is used to inform the receiver which symbolic ref
points to which ref; for example, "symref=HEAD:refs/heads/master" tells the
receiver that HEAD points to master.  This capability can be repeated to
represent multiple symrefs.

Servers SHOULD include this capability for the HEAD symref if it is one of the
refs being sent.

Clients MAY use the parameters from this capability to select the proper initial
branch when cloning a repository.


Mon Oct 19 12:57:00 EDT 2020
$ oom-sort -l0
oom_score oom_score_adj UID PID Name VmRSS VmSwap
--------- ------------- ---- ------- --------------- ------- --------
       18 0 0 533 Xorg 125 M 0 M
       10 0 1000 994 firewall-applet 70 M 0 M
	9 0 1000 883 caja 61 M 0 M
	7 0 1000 1047 redshift-gtk 52 M 0 M
	7 0 1000 1179 mate-terminal 50 M 0 M
	6 0 1000 871 mate-panel 42 M 0 M
	6 0 1000 930 nm-applet 41 M 0 M
	5 0 0 490 firewalld 40 M 0 M
	5 0 1000 862 mate-settings-d 37 M 0 M
	5 0 1000 866 marco 39 M 0 M
	5 0 1000 894 msm_kde_notifie 36 M 0 M
	5 0 1000 904 ibus-ui-gtk3 38 M 0 M
	5 0 1000 921 blueberry-obex- 39 M 0 M
	5 0 1000 946 pamac-tray 40 M 0 M
	5 0 1000 1001 mate-power-mana 37 M 0 M
	5 0 1000 1052 mate-volume-con 38 M 0 M
	5 0 1000 1151 clock-applet 36 M 0 M
	5 0 1000 1152 wnck-applet 38 M 0 M
	5 0 1000 1153 notification-ar 40 M 0 M
	4 0 1000 1046 applet.py 34 M 0 M
	3 0 102 335 polkitd 22 M 0 M
	3 0 1000 766 mate-session 24 M 0 M
	3 0 1000 905 ibus-extension- 26 M 0 M
	3 0 1000 908 ibus-x11 23 M 0 M
	3 0 1000 990 mate-maximus 24 M 0 M
	3 0 1000 995 polkit-mate-aut 22 M 0 M
	3 0 1000 1049 mate-screensave 24 M 0 M
	3 0 970 1083 geoclue 23 M 0 M
	2 0 0 495 NetworkManager 19 M 0 M
	2 0 1000 872 pulseaudio 19 M 0 M
	2 0 0 1036 bluetooth-autoc 19 M 0 M
	2 0 1000 1042 bluetooth-autoc 19 M 0 M
	1 0 979 323 systemd-timesyn 8 M 0 M
	1 0 965 333 python3 9 M 0 M
	1 0 0 334 python3 12 M 0 M
	1 0 0 336 systemd-logind 9 M 0 M
	1 0 0 489 ModemManager 10 M 0 M
	1 0 0 514 lightdm 7 M 0 M
	1 0 0 590 cupsd 9 M 0 M
	1 0 0 690 upowerd 10 M 0 M
	1 0 0 701 lightdm 8 M 0 M
	1 0 1000 753 systemd 10 M 0 M
	1 0 1000 775 gvfsd 7 M 0 M
	1 0 1000 823 at-spi2-registr 7 M 0 M
	1 0 1000 882 gvfs-udisks2-vo 12 M 0 M
	1 0 0 887 udisksd 12 M 0 M
	1 0 1000 895 ibus-daemon 7 M 0 M
	1 0 1000 985 gvfs-afc-volume 8 M 0 M
	1 0 1000 1037 gsettings-helpe 7 M 0 M
	1 0 1000 1082 obexd 7 M 0 M
	1 0 1000 1086 gvfsd-trash 8 M 0 M
	1 0 1000 1188 zsh 9 M 0 M
	1 0 1000 1625 python3 11 M 0 M
	0 0 0 238 haveged 5 M 0 M
	0 -250 0 239 systemd-journal 17 M 0 M
	0 -1000 0 240 systemd-udevd 11 M 0 M
	0 0 0 246 lvmetad 1 M 0 M
	0 0 974 327 avahi-daemon 3 M 0 M
	0 0 0 329 crond 3 M 0 M
	0 -900 81 330 dbus-daemon 5 M 0 M
	0 0 0 331 irqbalance 4 M 0 M
	0 0 0 343 VBoxService 4 M 0 M
	0 -999 0 402 python3 11 M 0 M
	0 0 974 436 avahi-daemon 0 M 0 M
	0 0 0 516 systemd-hostnam 7 M 0 M
	0 0 0 534 accounts-daemon 7 M 0 M
	0 0 1000 754 (sd-pam) 4 M 0 M
	0 0 1000 763 gnome-keyring-d 6 M 0 M
	0 0 1000 772 dbus-daemon 4 M 0 M
	0 0 1000 780 gvfsd-fuse 6 M 0 M
	0 0 1000 811 at-spi-bus-laun 6 M 0 M
	0 0 1000 817 dbus-daemon 4 M 0 M
	0 0 1000 856 dconf-service 5 M 0 M
	0 0 133 888 rtkit-daemon 3 M 0 M
	0 0 1000 902 ibus-dconf 7 M 0 M
	0 0 1000 918 ibus-portal 7 M 0 M
	0 0 1000 934 ibus-engine-sim 6 M 0 M
	0 0 1000 977 gvfs-mtp-volume 5 M 0 M
	0 0 1000 981 gvfs-gphoto2-vo 6 M 0 M
	0 0 1000 1008 agent 5 M 0 M
	0 0 1000 1022 VBoxClient 1 M 0 M
	0 0 1000 1023 VBoxClient 1 M 0 M
	0 0 1000 1027 VBoxClient 1 M 0 M
	0 0 1000 1031 VBoxClient 1 M 0 M
	0 0 1000 1032 VBoxClient 2 M 0 M
	0 0 1000 1033 VBoxClient 2 M 0 M
	0 0 1000 1074 redshift 5 M 0 M
	0 0 0 1100 wpa_supplicant 6 M 0 M
	0 0 1000 1101 gvfsd-metadata 6 M 0 M
	0 -900 0 1169 msd-datetime-me 6 M 0 M
	0 0 1000 1195 zsh 4 M 0 M
	0 0 1000 1318 sh 2 M 0 M
	0 0 1000 1319 bluetoothctl 2 M 0 M
	0 0 1000 1320 grep 2 M 0 M
	0 0 1000 1321 cut 1 M 0 M
	0 0 1000 1323 gitstatusd 4 M 0 M
	0 0 1000 1328 zsh 6 M 0 M
	0 0 1000 1329 zsh 4 M 0 M
	0 0 1000 1599 sh 4 M 0 M


Mon Oct 19 12:23:47 EDT 2020
sh-5.0$ oom-sort
oom_score oom_score_adj UID PID Name VmRSS VmSwap cmdline
--------- ------------- ---- ------- --------------- ------- -------- -------
      678 0 0 533 Xorg 99 M 21 M /usr/lib/Xorg :0 -seat seat0 -auth
      /run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch
      669 0 0 366 firewalld 6 M 25 M /usr/bin/python /usr/bin/firewalld --nofork
      --nopid
      669 0 1000 1704 caja 18 M 15 M /usr/bin/caja
      669 0 1000 1798 firewall-applet 8 M 24 M /usr/bin/python
      /usr/bin/firewall-applet
      669 0 1000 2023 wnck-applet 20 M 9 M /usr/lib/mate-panel/wnck-applet
      668 0 1000 1691 marco 11 M 11 M marco
      668 0 1000 1700 mate-panel 7 M 10 M mate-panel
      668 0 1000 1721 ibus-ui-gtk3 11 M 6 M /usr/lib/ibus/ibus-ui-gtk3
      668 0 1000 1723 ibus-extension- 6 M 8 M /usr/lib/ibus/ibus-extension-gtk3
      668 0 1000 1742 blueberry-obex- 7 M 16 M blueberry-obex-agent
      668 0 1000 1816 applet.py 6 M 15 M /usr/bin/python3
      /usr/share/system-config-printer/applet.py
      668 0 1000 1821 redshift-gtk 7 M 16 M python3 /usr/bin/redshift-gtk
      668 0 1000 2026 clock-applet 10 M 7 M /usr/lib/mate-panel/clock-applet
      668 0 1000 2027 notification-ar 7 M 8 M
      /usr/lib/mate-panel/notification-area-applet
      668 0 1000 3058 mate-terminal 18 M 8 M mate-terminal
      668 0 1000 9572 mate-system-mon 13 M 8 M mate-system-monitor
      667 0 0 237 haveged 2 M 6 M /usr/bin/haveged -w 1024 -v 1 --Foreground
      667 0 0 335 python3 12 M 0 M python3 /usr/bin/nohang --monitor --config
      /etc/nohang/nohang-desktop.conf
      667 0 102 336 polkitd 4 M 8 M /usr/lib/polkit-1/polkitd --no-debug
      667 0 0 501 NetworkManager 6 M 4 M /usr/bin/NetworkManager --no-daemon
      667 0 1000 1592 mate-session 5 M 6 M mate-session
      667 0 1000 1687 mate-settings-d 6 M 7 M
      /usr/lib/mate-settings-daemon/mate-settings-daemon
      667 0 1000 1696 pulseaudio 2 M 4 M /usr/bin/pulseaudio --daemonize=no
      --log-target=journal
      667 0 1000 1711 msm_kde_notifie 3 M 8 M msm_kde_notifier
      667 0 1000 1712 ibus-daemon 5 M 3 M ibus-daemon -drx
      667 0 1000 1726 ibus-x11 4 M 6 M /usr/lib/ibus/ibus-x11 --kill-daemon
      667 0 1000 1730 ibus-portal 3 M 5 M /usr/lib/ibus/ibus-portal
      667 0 1000 1751 nm-applet 4 M 8 M nm-applet
      667 0 1000 1787 pamac-tray 4 M 8 M pamac-tray
      667 0 1000 1792 mate-maximus 5 M 6 M mate-maximus
      667 0 1000 1801 polkit-mate-aut 4 M 5 M
      /usr/lib/mate-polkit/polkit-mate-authentication-agent-1
      667 0 1000 1803 mate-power-mana 7 M 6 M mate-power-manager
      667 0 1000 1822 mate-screensave 5 M 5 M mate-screensaver
      667 0 1000 1841 mate-volume-con 4 M 7 M mate-volume-control-status-icon
      667 0 970 1874 geoclue 3 M 7 M /usr/lib/geoclue
      667 0 1000 3069 zsh 3 M 4 M zsh
      667 0 1000 12012 zsh 3 M 4 M zsh
      667 0 965 14626 python3 9 M 0 M python3 /usr/local/sbin/memavaild -c
      /usr/local/etc/memavaild.conf
      667 0 1000 15437 python3 11 M 0 M python3 /usr/bin/oom-sort
      666 0 0 240 lvmetad 1 M 0 M /usr/bin/lvmetad -f
      666 0 979 325 systemd-timesyn 2 M 1 M /usr/lib/systemd/systemd-timesyncd
      666 0 974 329 avahi-daemon 2 M 0 M avahi-daemon: running
      [user-virtualbox.local]
      666 0 0 331 crond 2 M 0 M /usr/bin/crond -n
      666 0 0 333 irqbalance 2 M 0 M /usr/bin/irqbalance --foreground
      666 0 0 337 systemd-logind 2 M 1 M /usr/lib/systemd/systemd-logind
      666 0 0 344 VBoxService 0 M 1 M /usr/bin/VBoxService -f
      666 0 974 357 avahi-daemon 0 M 0 M avahi-daemon: chroot helper
      666 0 0 365 ModemManager 2 M 4 M /usr/bin/ModemManager
      666 0 0 521 lightdm 2 M 3 M /usr/bin/lightdm
      666 0 0 534 accounts-daemon 0 M 0 M /usr/lib/accounts-daemon
      666 0 0 588 cupsd 2 M 2 M /usr/bin/cupsd -l
      666 0 0 689 upowerd 2 M 3 M /usr/lib/upowerd
      666 0 0 700 lightdm 1 M 1 M lightdm --session-child 12 19
      666 0 1000 1579 systemd 3 M 2 M /usr/lib/systemd/systemd --user
      666 0 1000 1580 (sd-pam) 0 M 4 M (sd-pam)
      666 0 1000 1589 gnome-keyring-d 3 M 1 M /usr/bin/gnome-keyring-daemon
      --daemonize --login
      666 0 1000 1599 dbus-daemon 3 M 0 M /usr/bin/dbus-daemon --session
      --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
      666 0 1000 1601 gvfsd 4 M 1 M /usr/lib/gvfsd
      666 0 1000 1606 gvfsd-fuse 1 M 1 M /usr/lib/gvfsd-fuse /run/user/1000/gvfs
      -f
      666 0 1000 1637 at-spi-bus-laun 1 M 1 M /usr/lib/at-spi-bus-launcher
      666 0 1000 1643 dbus-daemon 3 M 0 M /usr/bin/dbus-daemon
      --config-file=/usr/share/defaults/at-spi2/accessibility.conf --nofork
      --print-address 3
      666 0 1000 1646 at-spi2-registr 3 M 1 M /usr/lib/at-spi2-registryd
      --use-gnome-session
      666 0 1000 1680 dconf-service 1 M 1 M /usr/lib/dconf-service
      666 0 133 1709 rtkit-daemon 1 M 0 M /usr/lib/rtkit-daemon
      666 0 1000 1720 ibus-dconf 2 M 1 M /usr/lib/ibus/ibus-dconf
      666 0 1000 1757 gvfs-udisks2-vo 2 M 2 M /usr/lib/gvfs-udisks2-volume-monitor
      666 0 1000 1758 ibus-engine-sim 5 M 0 M /usr/lib/ibus/ibus-engine-simple
      666 0 1000 1783 obexd 1 M 1 M /usr/lib/bluetooth/obexd
      666 0 1000 1812 agent 1 M 1 M /usr/lib/geoclue-2.0/demos/agent
      666 0 1000 1838 VBoxClient 0 M 1 M /usr/bin/VBoxClient --seamless
      666 0 1000 1840 VBoxClient 0 M 1 M /usr/bin/VBoxClient --seamless
      666 0 1000 1847 VBoxClient 0 M 1 M /usr/bin/VBoxClient --draganddrop
      666 0 1000 1848 VBoxClient 1 M 1 M /usr/bin/VBoxClient --draganddrop
      666 0 1000 1869 redshift 2 M 1 M /usr/bin/redshift -v
      666 0 0 1895 wpa_supplicant 1 M 1 M /usr/bin/wpa_supplicant -u -s -O
      /run/wpa_supplicant
      666 0 0 1898 udisksd 3 M 1 M /usr/lib/udisks2/udisksd
      666 0 1000 1944 gsettings-helpe 2 M 3 M /usr/lib/pulse/gsettings-helper
      666 0 1000 1974 gvfs-mtp-volume 2 M 1 M /usr/lib/gvfs-mtp-volume-monitor
      666 0 1000 1984 gvfs-gphoto2-vo 2 M 1 M /usr/lib/gvfs-gphoto2-volume-monitor
      666 0 1000 2011 gvfs-afc-volume 2 M 1 M /usr/lib/gvfs-afc-volume-monitor
      666 0 1000 2021 gvfsd-trash 2 M 1 M /usr/lib/gvfsd-trash --spawner :1.3
      /org/gtk/gvfs/exec_spaw/0
      666 0 1000 2086 sh 1 M 0 M /bin/sh
      /usr/share/garudawelcome/scripts/check-bt.sh
      666 0 1000 2087 bluetoothctl 0 M 0 M bluetoothctl show
      666 0 1000 2088 grep 2 M 0 M grep Powered
      666 0 1000 2089 cut 0 M 0 M cut -d -f2
      666 0 1000 2091 gvfsd-metadata 2 M 1 M /usr/lib/gvfsd-metadata
      666 0 1000 2687 gvfsd-network 2 M 1 M /usr/lib/gvfsd-network --spawner :1.3
      /org/gtk/gvfs/exec_spaw/1
      666 0 1000 2702 gvfsd-dnssd 2 M 3 M /usr/lib/gvfsd-dnssd --spawner :1.3
      /org/gtk/gvfs/exec_spaw/3
      666 0 1000 3074 zsh 1 M 2 M zsh
      666 0 1000 3109 zsh 1 M 3 M zsh
      666 0 1000 3110 zsh 0 M 3 M zsh
      666 0 1000 3112 gitstatusd 1 M 0 M
      /usr/share/zsh-theme-powerlevel10k/gitstatus/usrbin/gitstatusd -G v1.2.0 -s
      -1 -u -1 -d -1 -c -1 -m -1 -v FATAL -t 4
      666 0 1000 3157 sh 2 M 1 M sh
      666 0 1000 12020 zsh 1 M 2 M zsh
      666 0 1000 12078 zsh 1 M 3 M zsh
      666 0 1000 12079 gitstatusd 1 M 4 M
      /usr/share/zsh-theme-powerlevel10k/gitstatus/usrbin/gitstatusd -G v1.2.0 -s
      -1 -u -1 -d -1 -c -1 -m -1 -v FATAL -t 4
      666 0 1000 12080 zsh 0 M 3 M zsh
      666 0 1000 12391 sh 3 M 0 M sh
      502 -250 0 238 systemd-journal 17 M 1 M /usr/lib/systemd/systemd-journald
       67 -900 81 332 dbus-daemon 3 M 1 M /usr/bin/dbus-daemon --system
       --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
	2 -999 0 345 python3 9 M 2 M python3 /usr/bin/ananicy start
	0 -1000 0 239 systemd-udevd 2 M 3 M /usr/lib/systemd/systemd-udevd
sh-5.0$
sh-5.0$
sh-5.0$
sh-5.0$
sh-5.0$ cat /proc/self/oom_score
666
sh-5.0$


Mon Oct 19 09:36:11 EDT 2020
package main

import (
	"bytes"
	"encoding/gob"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"path"

	"github.com/matrix-org/gomatrix"
)

// FStore is the path to a directory which will contain our data.
type FStore string

func NewStore(s string) (*FStore, error) {
	fi, err := os.Lstat(s)
	if err != nil {
		return nil, err
	}

	if !fi.IsDir() {
		return nil, fmt.Errorf("not a directory")
	}
	fstore := FStore(s)
	return &fstore, nil
}

func (s *FStore) encodeRoom(room *gomatrix.Room) ([]byte, error) {
	buf := new(bytes.Buffer)
	enc := gob.NewEncoder(buf)
	err := enc.Encode(room)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

func (s *FStore) decodeRoom(room []byte) (*gomatrix.Room, error) {
	var r *gomatrix.Room
	buf := bytes.NewBuffer(room)
	dec := gob.NewDecoder(buf)
	err := dec.Decode(&r)
	if err != nil {
		return nil, err
	}
	return r, nil
}

func (s FStore) Set(key string, value string) {
	err := ioutil.WriteFile(path.Join(string(s), key), []byte(value), 0600)
	if err != nil {
		log.Println(err)
	}
}

func (s FStore) Get(key string) (string, error) {
	data, err := ioutil.ReadFile(path.Join(string(s), key))
	if err != nil {
		return "", nil
	}
	return string(data), nil
}

func (s *FStore) SaveFilterID(userID, filterID string) {
	s.Set(fmt.Sprintf("filter_%s", userID), filterID)
}

func (s *FStore) LoadFilterID(userID string) string {
	filter, _ := s.Get(fmt.Sprintf("filter_%s", userID))
	return filter
}

func (s *FStore) SaveNextBatch(userID, nextBatchToken string) {
	s.Set(fmt.Sprintf("batch_%s", userID), nextBatchToken)
}

// LoadNextBatch
func (s *FStore) LoadNextBatch(userID string) string {
	batch, _ := s.Get(fmt.Sprintf("batch_%s", userID))
	return batch
}

// SaveRoom exposed
func (s *FStore) SaveRoom(room *gomatrix.Room) {
	b, _ := s.encodeRoom(room)
	s.Set(fmt.Sprintf("room_%s", room.ID), string(b))
}

// LoadRoom expose
func (s *FStore) LoadRoom(roomID string) *gomatrix.Room {
	b, _ := s.Get(fmt.Sprintf("room_%s", roomID))
	room, _ := s.decodeRoom([]byte(b))
	return room
}


Sun Oct 18 22:24:25 EDT 2020
diff -r 78891f472fbf sys/src/cmd/vnc/auth.c
--- a/sys/src/cmd/vnc/auth.c Sun Oct 18 23:39:07 2020 +0200
+++ b/sys/src/cmd/vnc/auth.c Sun Oct 18 19:24:25 2020 -0700
@@ -77,7 +77,7 @@
				type == ANoAuth ? "None" :
				type == AVncAuth ? "VNC" : "Unknown");
		}
- if(type > auth)
+ if(type > auth && type <= AVncAuth)
			auth = type;
	}
	return auth;


prev | next