shithub: riscv

Download patch

ref: 73235c6b2600c2baf4e88b1c88b592b7ce398a91
parent: 2dd9e4bbd92fac0b687edadead19de338d6cbe6d
parent: 5b81e7de3f1ab3691438878cf1da912a54138d5f
author: Alex Musolino <alex@musolino.id.au>
date: Mon Apr 1 19:14:14 EDT 2019

merge

--- a/rc/bin/cpurc
+++ b/rc/bin/cpurc
@@ -65,7 +65,7 @@
 					# try /lib/ndb first, then do dhcp/slaac
 					ip/ipconfig -6 ether $ether
 					ip/ipconfig -N ether $ether >[2]/dev/null || @{
-						ip/ipconfig ether $ether ra6 recvra 1 &
+						test -e /env/nora6 || ip/ipconfig ether $ether ra6 recvra 1 &
 						ip/ipconfig -h $sysname ether $ether &
 						wait
 					}
--- a/rc/bin/inst/startether
+++ b/rc/bin/inst/startether
@@ -21,7 +21,7 @@
 		ip/ipconfig -g $gwaddr ether $netdev $ipaddr $ipmask >>[2]/srv/log
 	case automatic
 		>>[2]/srv/log @{
-			ip/ipconfig ra6 recvra 1 &
+			test -e /env/nora6 || ip/ipconfig ra6 recvra 1 &
 			ip/ipconfig &
 			wait
 		}
--- a/rc/bin/termrc
+++ b/rc/bin/termrc
@@ -66,7 +66,7 @@
 					# try /lib/ndb first, then do dhcp/slaac
 					ip/ipconfig -6 ether $ether
 					ip/ipconfig -N ether $ether >[2]/dev/null || @{
-						ip/ipconfig ether $ether ra6 recvra 1 &
+						test -e /env/nora6 || ip/ipconfig ether $ether ra6 recvra 1 &
 						ip/ipconfig -h $sysname ether $ether &
 						wait
 					}
--- a/sys/include/dtracy.h
+++ b/sys/include/dtracy.h
@@ -241,7 +241,7 @@
 DTProbe *dtpnew(char *, DTProvider *, void *aux);
 int dtpmatch(char *, DTProbe ***);
 int dtplist(DTProbe ***);
-void dtptrigger(DTProbe *, int, DTTrigInfo *);
+void dtptrigger(DTProbe *, DTTrigInfo *);
 
 /* expression functions */
 int dteverify(DTExpr *);
@@ -285,7 +285,7 @@
 void *dtrealloc(void *, ulong);
 void dtfree(void *);
 void *dtmalloc(ulong);
-void dtmachlock(int); /* lock the per-cpu lock */
+int dtmachlock(int); /* lock the per-cpu lock */
 void dtmachunlock(int); /* unlock the per-cpu lock */
 void dtcoherence(void); /* memory barrier */
 uvlong dtgetvar(int); /* return the value of a variable */
--- a/sys/lib/dist/mkfile
+++ b/sys/lib/dist/mkfile
@@ -146,4 +146,5 @@
 	bind mail/lib /n/src9/mail/lib
 	bind ndb /n/src9/lib/ndb
 	bind -a adm/timezone /n/src9/adm/timezone
+	aux/stub -d /n/src9/usr
 	bind usr /n/src9/usr
--- /dev/null
+++ b/sys/man/1/walk
@@ -1,0 +1,122 @@
+.TH WALK 1
+.SH NAME
+walk \- walk a path
+.SH SYNOPSIS
+.B walk
+[
+.B -dftxu
+] [
+.B -n
+.I mind,maxd
+] [
+.B -e
+.I ststr
+] [
+.I name ...
+]
+.SH DESCRIPTION
+.I Walk
+recursively descends any directory arguments,
+printing the name of each file on a separate line.
+When no arguments are given, the current directory
+is assumed.
+Non-directory arguments are checked for existence,
+then printed, if so.
+.PP
+Options are:
+.TP
+.B -d
+Print only directories.
+.TP
+.B -f
+Print only non-directories.
+.TP
+.B -t
+Print a file only if it has the temporary flag set.
+.TP
+.B -x
+Print a file only if it has any executable bits set.
+.TP
+.B -u
+Unbuffered output.
+.TP
+.B -n min,max
+Set the inclusive range of depths for filtering in results.
+Both
+.I min
+and
+.I max
+are optional.
+.TP
+.B -e statfmt
+Setting the statfmt string allows specifying the data
+.B walk
+should print.
+It takes a string of characters, each corresponding
+to some piece of information about the file being
+traversed, and prints them separated by spaces.
+.PP
+The statfmt characters are as follows:
+.TF .
+.TP
+.B U
+owner name (uid)
+.TP
+.B G
+group name (gid)
+.TP
+.B M
+name of last user to modify (muid)
+.TP
+.B a
+last access time (atime)
+.TP
+.B m
+last modification time (mtime)
+.TP
+.B n
+final path element (name)
+.TP
+.B p
+path
+.TP
+.B q
+qid path.version.type (see
+.IR stat (2))
+.TP
+.B s
+size in bytes
+.TP
+.B x
+permissions
+.PD
+.PP
+The default statfmt is simply,
+.IR p .
+.SH EXAMPLES
+List files in a directory, sorted by modification time.
+.IP
+.EX
+walk -femp catpics | sort -n | sed 's/^[^ ]+ //'
+.EE
+.PP
+Print the size and path of files (excluding dirs)
+in the working directory.
+.IP
+.EX
+walk -fn1 -esp
+.EE
+.PD
+.SH SOURCE
+.B /sys/src/cmd/walk.c
+.SH SEE ALSO
+.IR ls (1),
+.IR du (1)
+.SH BUGS
+Statfmt character `x' displays permissions as an integer.
+.PP
+Manipulating ifs is a nuisance.
+.PP
+File names are assumed to not contain newlines.
+.PP
+Correct invocation requires too much thought.
--- a/sys/man/8/plan9.ini
+++ b/sys/man/8/plan9.ini
@@ -443,6 +443,8 @@
 or
 .B /boot. 
 See iwl section above for configuration details.
+.SS \fLnora6=
+Disable automatic IPv6 configuration from incoming router advertisements.
 .SS DISKS, TAPES
 (S)ATA controllers are autodetected.
 .SS \fL*nodma=\fP
@@ -865,6 +867,18 @@
 battery life (see
 .IR stats (8)).
 It is not on by default because it causes problems on some laptops.
+.SS USB
+.SS \fL*nousbprobe=\fP
+Disable USB host controller detection.
+.SS \fL*nousbohci=\fP
+.SS \fL*nousbuhci=\fP
+.SS \fL*nousbehci=\fP
+.SS \fL*nousbxhci=\fP
+Disable specific USB host controller types.
+.SS \fLnousbrc=\fP
+Disable
+.IR nusbrc (8)
+startup at boot time.
 .SS \fLnousbhname=\fP
 When defined,
 .IR nusbrc (8)
--- a/sys/src/9/boot/net.rc
+++ b/sys/src/9/boot/net.rc
@@ -15,9 +15,9 @@
 		}
 	}
 
-	if(~ $1 ether && ~ $#* 2) @{
+	if(~ $1 ether gbe && ~ $#* 2) @{
 		ip/ipconfig -6 $*
-		ip/ipconfig $* ra6 recvra 1 &
+		test -e /env/nora6 || ip/ipconfig $* ra6 recvra 1 &
 		ip/ipconfig -p $* &
 		wait
 	}
--- a/sys/src/9/port/devdtracy.c
+++ b/sys/src/9/port/devdtracy.c
@@ -512,10 +512,18 @@
 	return v;
 }
 
-void
+int
 dtmachlock(int i)
 {
+	while(i < 0) {
+		i = dtmachlock(m->machno);
+		if(i == m->machno)
+			return i;
+		dtmachunlock(i);
+		i = -1;
+	}
 	ilock(&machlocks[i]);
+	return i;
 }
 
 void
--- a/sys/src/9/port/dtracysys.c
+++ b/sys/src/9/port/dtracysys.c
@@ -20,10 +20,10 @@
 	uintptr rc;\
 	DTTrigInfo info;\
 	memset(&info, 0, sizeof(info));\
-	dtptrigger(dtpsysentry[y], m->machno, &info);\
+	dtptrigger(dtpsysentry[y], &info);\
 	rc = z(va);\
 	info.arg[9] = (uvlong) rc;\
-	dtptrigger(dtpsysreturn[y], m->machno, &info);\
+	dtptrigger(dtpsysreturn[y], &info);\
 	return rc;\
 }
 #define WRAP1(x,y,z,type0)\
@@ -33,10 +33,10 @@
 	DTTrigInfo info;\
 	memset(&info, 0, sizeof(info));\
 	info.arg[0] = (uvlong) va_arg(vb, type0);\
-	dtptrigger(dtpsysentry[y], m->machno, &info);\
+	dtptrigger(dtpsysentry[y], &info);\
 	rc = z(va);\
 	info.arg[9] = (uvlong) rc;\
-	dtptrigger(dtpsysreturn[y], m->machno, &info);\
+	dtptrigger(dtpsysreturn[y], &info);\
 	return rc;\
 }
 #define WRAP2(x,y,z,type0,type1)\
@@ -47,10 +47,10 @@
 	memset(&info, 0, sizeof(info));\
 	info.arg[0] = (uvlong) va_arg(vb, type0);\
 	info.arg[1] = (uvlong) va_arg(vb, type1);\
-	dtptrigger(dtpsysentry[y], m->machno, &info);\
+	dtptrigger(dtpsysentry[y], &info);\
 	rc = z(va);\
 	info.arg[9] = (uvlong) rc;\
-	dtptrigger(dtpsysreturn[y], m->machno, &info);\
+	dtptrigger(dtpsysreturn[y], &info);\
 	return rc;\
 }
 #define WRAP3(x,y,z,type0,type1,type2)\
@@ -62,10 +62,10 @@
 	info.arg[0] = (uvlong) va_arg(vb, type0);\
 	info.arg[1] = (uvlong) va_arg(vb, type1);\
 	info.arg[2] = (uvlong) va_arg(vb, type2);\
-	dtptrigger(dtpsysentry[y], m->machno, &info);\
+	dtptrigger(dtpsysentry[y], &info);\
 	rc = z(va);\
 	info.arg[9] = (uvlong) rc;\
-	dtptrigger(dtpsysreturn[y], m->machno, &info);\
+	dtptrigger(dtpsysreturn[y], &info);\
 	return rc;\
 }
 #define WRAP4(x,y,z,type0,type1,type2,type3)\
@@ -78,10 +78,10 @@
 	info.arg[1] = (uvlong) va_arg(vb, type1);\
 	info.arg[2] = (uvlong) va_arg(vb, type2);\
 	info.arg[3] = (uvlong) va_arg(vb, type3);\
-	dtptrigger(dtpsysentry[y], m->machno, &info);\
+	dtptrigger(dtpsysentry[y], &info);\
 	rc = z(va);\
 	info.arg[9] = (uvlong) rc;\
-	dtptrigger(dtpsysreturn[y], m->machno, &info);\
+	dtptrigger(dtpsysreturn[y], &info);\
 	return rc;\
 }
 /*TODO*/
@@ -96,10 +96,10 @@
 	info.arg[2] = (uvlong) va_arg(vb, type2);\
 	info.arg[3] = (uvlong) va_arg(vb, type3);\
 	info.arg[4] = (uvlong) va_arg(vb, type4);\
-	dtptrigger(dtpsysentry[y], m->machno, &info);\
+	dtptrigger(dtpsysentry[y], &info);\
 	rc = z(va);\
 	info.arg[9] = (uvlong) rc;\
-	dtptrigger(dtpsysreturn[y], m->machno, &info);\
+	dtptrigger(dtpsysreturn[y], &info);\
 	return rc;\
 }
 
--- a/sys/src/9/port/dtracytimer.c
+++ b/sys/src/9/port/dtracytimer.c
@@ -17,7 +17,7 @@
 	memset(&info, 0, sizeof(info));
 	for(;;){
 		tsleep(&up->sleep, return0, nil, 1000);
-		dtptrigger(timerprobe, m->machno, &info);
+		dtptrigger(timerprobe, &info);
 	}
 }
 
--- a/sys/src/9/port/portmkfile
+++ b/sys/src/9/port/portmkfile
@@ -80,6 +80,7 @@
 netif.$O:	../port/netif.h
 devuart.$O:	../port/netif.h
 devbridge.$O:	../port/netif.h ../ip/ip.h ../ip/ipv6.h
+devdtracy.$O dtracysys.$O dtracytimer.$O:	/sys/include/dtracy.h
 devdraw.$O:	screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/memlayer.h /sys/include/cursor.h
 devmouse.$O:	screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/cursor.h
 swcursor.$O:	screen.h /sys/include/draw.h /sys/include/memdraw.h /sys/include/cursor.h
--- a/sys/src/cmd/5c/peep.c
+++ b/sys/src/cmd/5c/peep.c
@@ -337,7 +337,7 @@
 			break;
 
 		case AMOVM:
-			t = 1<<v2->reg;
+			t = (1<<v1->reg) | (1<<v2->reg);
 			if((p->from.type == D_CONST && (p->from.offset&t)) ||
 			   (p->to.type == D_CONST && (p->to.offset&t)))
 				return 0;
--- a/sys/src/cmd/upas/fs/mbox.c
+++ b/sys/src/cmd/upas/fs/mbox.c
@@ -76,8 +76,10 @@
 	a = mb->root->subname;
 	if(rdidxfile(mb) == -2)
 		wridxfile(mb);
-	if(s = mb->sync(mb))
+	if(s = mb->sync(mb)){
+		mb->syncing = 0;
 		return s;
+	}
 	n = 0;
 	d = 0;
 	y = 0;
--- /dev/null
+++ b/sys/src/cmd/walk.c
@@ -1,0 +1,321 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <String.h>
+
+int Cflag = 0;
+int uflag = 0;
+String *stfmt;
+
+/* should turn these flags into a mask */
+int dflag = 1;
+int fflag = 1;
+int tflag = 0;
+int xflag = 0;
+long maxdepth = ~(1<<31);
+long mindepth = 0;
+
+char *dotpath = ".";
+Dir *dotdir = nil;
+
+Biobuf *bout;
+
+int seen(Dir*);
+
+void
+warn(char *fmt, ...)
+{
+	va_list arg;
+	char buf[1024];	/* arbitrary */
+	int n;
+
+	if((n = snprint(buf, sizeof(buf), "%s: ", argv0)) < 0)
+		sysfatal("snprint: %r");
+	va_start(arg, fmt);
+	vseprint(buf+n, buf+sizeof(buf), fmt, arg);
+	va_end(arg);
+
+	Bflush(bout);
+	fprint(2, "%s\n", buf);
+}
+
+void
+dofile(char *path, Dir *f, int pathonly)
+{
+	char *p;
+
+	if(
+		(f == dotdir)
+		|| (tflag && ! (f->qid.type & QTTMP))
+		|| (xflag && ! (f->mode & DMEXEC))
+	)
+		return;
+
+	for(p = s_to_c(stfmt); *p != '\0'; p++){
+		switch(*p){
+		case 'U': Bwrite(bout, f->uid, strlen(f->uid)); break;
+		case 'G': Bwrite(bout, f->gid, strlen(f->gid)); break;
+		case 'M': Bwrite(bout, f->muid, strlen(f->muid)); break;
+		case 'a': Bprint(bout, "%uld", f->atime); break;
+		case 'm': Bprint(bout, "%uld", f->mtime); break;
+		case 'n': Bwrite(bout, f->name, strlen(f->name)); break;
+		case 'p':
+			if(path != dotpath)
+				Bwrite(bout, path, strlen(path));
+			if(! (f->qid.type & QTDIR) && !pathonly){
+				if(path != dotpath)
+					Bputc(bout, '/');
+				Bwrite(bout, f->name, strlen(f->name));
+			}
+			break;
+		case 'q': Bprint(bout, "%ullx.%uld.%.2uhhx", f->qid.path, f->qid.vers, f->qid.type); break;
+		case 's': Bprint(bout, "%lld", f->length); break;
+		case 'x': Bprint(bout, "%ulo", f->mode); break;
+		default:
+			abort();
+		}
+
+		if(*(p+1) != '\0')
+			Bputc(bout, ' ');
+	}
+
+	Bputc(bout, '\n');
+
+	if(uflag)
+		Bflush(bout);
+}
+
+void
+walk(char *path, Dir *cf, long depth)
+{
+	String *file;
+	Dir *dirs, *f, *fe;
+	int fd;
+	long n;
+
+	if(cf == nil){
+		warn("path: %s: %r", path);
+		return;
+	}
+
+	if(depth >= maxdepth)
+		goto nodescend;
+
+	if((fd = open(path, OREAD)) < 0){
+		warn("couldn't open %s: %r", path);
+		return;
+	}
+
+	while((n = dirread(fd, &dirs)) > 0){
+		fe = dirs+n;
+		for(f = dirs; f < fe; f++){
+			if(seen(f))
+				continue;
+			if(! (f->qid.type & QTDIR)){
+				if(fflag && depth >= mindepth)
+					dofile(path, f, 0);
+			} else if(strcmp(f->name, ".") == 0 || strcmp(f->name, "..") == 0){
+				warn(". or .. named file: %s/%s", path, f->name);
+			} else{
+				if(depth+1 > maxdepth){
+					dofile(path, f, 0);
+					continue;
+				} else if(path == dotpath){
+					if((file = s_new()) == nil)
+						sysfatal("s_new: %r");
+				} else{
+					if((file = s_copy(path)) == nil)
+						sysfatal("s_copy: %r");
+					if(s_len(file) != 1 || *s_to_c(file) != '/')
+						s_putc(file, '/');
+				}
+				s_append(file, f->name);
+
+				walk(s_to_c(file), f, depth+1);	
+				s_free(file);
+			}
+		}
+		free(dirs);
+	}
+	close(fd);
+	if(n < 0)
+		warn("%s: %r", path);
+
+nodescend:
+	depth--;
+	if(dflag && depth >= mindepth)
+		dofile(path, cf, 0);
+}
+
+char*
+slashslash(char *s)
+{
+	char *p, *q;
+
+	for(p=q=s; *q; q++){
+		if(q>s && *q=='/' && *(q-1)=='/')
+			continue;
+		if(p != q)
+			*p = *q;
+		p++;
+	}
+	do{
+		*p-- = '\0';
+	} while(p>s && *p=='/');
+
+	return s;
+}
+
+long
+estrtol(char *as, char **aas, int base)
+{
+	long n;
+	char *p;
+
+	n = strtol(as, &p, base);
+	if(p == as || *p != '\0')
+		sysfatal("estrtol: bad input '%s'", as);
+	else if(aas != nil)
+		*aas = p;
+
+	return n;
+}
+
+void
+elimdepth(char *p){
+	char *q;
+
+	if(strlen(p) == 0)
+		sysfatal("empty depth argument");
+
+	if(q = strchr(p, ',')){
+		*q = '\0';
+		if(p != q)
+			mindepth = estrtol(p, nil, 0);
+		p = q+1;
+		if(*p == '\0')
+			return;
+	}
+
+	maxdepth = estrtol(p, nil, 0);
+}
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s [-udftx] [-n mind,maxd] [-e statfmt] [file ...]\n", argv0);
+	exits("usage");
+}
+
+/*
+	Last I checked (commit 3dd6a31881535615389c24ab9a139af2798c462c),
+	libString calls sysfatal when things go wrong; in my local
+	copy of libString, failed calls return nil and errstr is set.
+
+	There are various nil checks in this code when calling libString
+	functions, but since they are a no-op and libString needs
+	a rework, I left them in - BurnZeZ
+*/
+
+void
+main(int argc, char **argv)
+{
+	long i;
+	Dir *d;
+
+	stfmt = nil;
+	ARGBEGIN{
+	case 'C': Cflag++; break; /* undocumented; do not cleanname() the args */
+	case 'u': uflag++; break; /* unbuffered output */
+
+	case 'd': dflag++; fflag = 0; break; /* only dirs */
+	case 'f': fflag++; dflag = 0; break; /* only non-dirs */
+	case 't': tflag++; break; /* only tmp files */
+	case 'x': xflag++; break; /* only executable permission */
+
+	case 'n': elimdepth(EARGF(usage())); break;
+	case 'e':
+		if((stfmt = s_reset(stfmt)) == nil)
+			sysfatal("s_reset: %r");
+		s_append(stfmt, EARGF(usage()));
+		i = strspn(s_to_c(stfmt), "UGMamnpqsx");
+		if(i != s_len(stfmt))
+			sysfatal("bad stfmt: %s\n", s_to_c(stfmt));
+		break;
+	default:
+		usage();
+	}ARGEND;
+
+	if((bout = Bfdopen(1, OWRITE)) == nil)
+		sysfatal("Bfdopen: %r");
+	Blethal(bout, nil);
+	if(stfmt == nil){
+		if((stfmt = s_new()) == nil)
+			sysfatal("s_new: %r");
+		s_putc(stfmt, 'p');
+		s_terminate(stfmt);
+	}
+	if(maxdepth != ~(1<<31))
+		maxdepth++;
+	if(argc == 0){
+		dotdir = dirstat(".");
+		walk(dotpath, dotdir, 1);
+	} else for(i=0; i<argc; i++){
+		if(strncmp(argv[i], "#/", 2) == 0)
+			slashslash(argv[i]+2);
+		else{
+			if(!Cflag)
+				cleanname(argv[i]);
+			slashslash(argv[i]);
+		}
+		if((d = dirstat(argv[i])) != nil && ! (d->qid.type & QTDIR)){
+			if(fflag && !seen(d) && mindepth < 1)
+				dofile(argv[i], d, 1);
+		} else
+			walk(argv[i], d, 1);
+		free(d);
+	}
+	Bterm(bout);
+
+	exits(nil);
+}
+
+/* below pilfered from /sys/src/cmd/du.c
+ * NOTE: I did not check for bugs */
+
+#define	NCACHE	256	/* must be power of two */
+
+typedef struct
+{
+	Dir*	cache;
+	int	n;
+	int	max;
+} Cache;
+Cache cache[NCACHE];
+
+int
+seen(Dir *dir)
+{
+	Dir *dp;
+	int i;
+	Cache *c;
+
+	c = &cache[dir->qid.path&(NCACHE-1)];
+	dp = c->cache;
+	for(i=0; i<c->n; i++, dp++)
+		if(dir->qid.path == dp->qid.path &&
+		   dir->type == dp->type &&
+		   dir->dev == dp->dev)
+			return 1;
+	if(c->n == c->max){
+		if (c->max == 0)
+			c->max = 8;
+		else
+			c->max += c->max/2;
+		c->cache = realloc(c->cache, c->max*sizeof(Dir));
+		if(c->cache == nil)
+			sysfatal("realloc: %r");
+	}
+	c->cache[c->n++] = *dir;
+	return 0;
+}
--- a/sys/src/cmd/webfs/fns.h
+++ b/sys/src/cmd/webfs/fns.h
@@ -15,10 +15,12 @@
 #pragma	varargck type "U" Url*
 #pragma varargck type "E" Str2
 #pragma varargck type "N" char*
+#pragma varargck type "]" char*
 
 int	Efmt(Fmt*);
 int	Nfmt(Fmt*);
 int	Ufmt(Fmt*);
+int	Mfmt(Fmt*);
 char*	Upath(Url *);
 Url*	url(char *s, Url *b);
 Url*	saneurl(Url *u);
--- a/sys/src/cmd/webfs/fs.c
+++ b/sys/src/cmd/webfs/fs.c
@@ -766,6 +766,7 @@
 	quotefmtinstall();
 	fmtinstall('U', Ufmt);
 	fmtinstall('N', Nfmt);
+	fmtinstall(']', Mfmt);
 	fmtinstall('E', Efmt);
 	fmtinstall('[', encodefmt);
 	fmtinstall('H', encodefmt);
--- a/sys/src/cmd/webfs/http.c
+++ b/sys/src/cmd/webfs/http.c
@@ -637,7 +637,7 @@
 			ru.path = Upath(u);
 			ru.query = u->query;
 		}
-		n = snprint(buf, sizeof(buf), "%s %U HTTP/1.1\r\nHost: %s%s%s\r\n",
+		n = snprint(buf, sizeof(buf), "%s %U HTTP/1.1\r\nHost: %]%s%s\r\n",
 			method, &ru, host, u->port ? ":" : "", u->port ? u->port : "");
 		if(n >= sizeof(buf)-64){
 			werrstr("request too large");
@@ -649,7 +649,7 @@
 				break;
 		}
 		if(h->tunnel){
-			n = snprint(buf, sizeof(buf), "CONNECT %s:%s HTTP/1.1\r\nHost: %s:%s\r\n",
+			n = snprint(buf, sizeof(buf), "CONNECT %]:%s HTTP/1.1\r\nHost: %]:%s\r\n",
 				host, u->port ? u->port : "443",
 				host, u->port ? u->port : "443");
 		}
--- a/sys/src/cmd/webfs/url.c
+++ b/sys/src/cmd/webfs/url.c
@@ -83,6 +83,14 @@
 }
 
 int
+Mfmt(Fmt *f)
+{
+	char *s = va_arg(f->args, char*);
+	fmtprint(f, (*s != '[' && strchr(s, ':') != nil)? "[%s]" : "%s", s);
+	return 0;
+}
+
+int
 Ufmt(Fmt *f)
 {
 	char *s;
@@ -101,7 +109,7 @@
 		fmtprint(f, "@");
 	}
 	if(u->host){
-		fmtprint(f, strchr(u->host, ':') ? "[%s]" : "%s", u->host);
+		fmtprint(f, "%]", u->host);
 		if(u->port)
 			fmtprint(f, ":%s", u->port);
 	}
--- a/sys/src/libdtracy/prog.c
+++ b/sys/src/libdtracy/prog.c
@@ -336,13 +336,12 @@
 }
 
 void
-dtptrigger(DTProbe *p, int machno, DTTrigInfo *info)
+dtptrigger(DTProbe *p, DTTrigInfo *info)
 {
 	DTEnab *e;
 	
 	info->ts = dttime();
-	dtmachlock(machno);
-	info->machno = machno;
+	info->machno = dtmachlock(-1);
 	for(e = p->enablist.probnext; e != &p->enablist; e = e->probnext)
 		if(e->gr->chan->state == DTCGO){
 			info->ch = e->gr->chan;
@@ -350,5 +349,5 @@
 			if(dtgexec(e->gr, info) < 0)
 				e->gr->chan->state = DTCFAULT;
 		}
-	dtmachunlock(machno);
+	dtmachunlock(info->machno);
 }