This commit is contained in:
Alex Musolino 2019-04-01 23:14:14 +10:30
commit 73235c6b26
20 changed files with 509 additions and 30 deletions

View file

@ -65,7 +65,7 @@ if(test -r /net/ipselftab){
# 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
}

View file

@ -21,7 +21,7 @@ case go
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
}

View file

@ -66,7 +66,7 @@ if(test -r /net/ipselftab){
# 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
}

View file

@ -241,7 +241,7 @@ void dtsync(void);
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 @@ uvlong dttime(void); /* return current timestamp */
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 */

1
sys/lib/dist/mkfile vendored
View file

@ -146,4 +146,5 @@ binds:V:
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

122
sys/man/1/walk Normal file
View file

@ -0,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.

View file

@ -443,6 +443,8 @@ to be present on attach in
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 @@ The main feature of the interface is the ability to watch
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)

View file

@ -15,9 +15,9 @@ fn confignet{
}
}
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
}

View file

@ -512,10 +512,18 @@ dtrealloc(void *v, ulong n)
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

View file

@ -20,10 +20,10 @@ extern Syscall *systab[];
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 @@ extern Syscall *systab[];
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 @@ extern Syscall *systab[];
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 @@ extern Syscall *systab[];
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 @@ extern Syscall *systab[];
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 @@ extern Syscall *systab[];
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;\
}

View file

@ -17,7 +17,7 @@ dtracytimer(void *)
memset(&info, 0, sizeof(info));
for(;;){
tsleep(&up->sleep, return0, nil, 1000);
dtptrigger(timerprobe, m->machno, &info);
dtptrigger(timerprobe, &info);
}
}

View file

@ -80,6 +80,7 @@ devpipe.$O: ../port/netif.h
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

View file

@ -337,7 +337,7 @@ subprop(Reg *r0)
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;

View file

@ -76,8 +76,10 @@ syncmbox(Mailbox *mb, int doplumb)
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;

321
sys/src/cmd/walk.c Normal file
View file

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

View file

@ -15,10 +15,12 @@ char* unquote(char *s, char **ps);
#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);

View file

@ -766,6 +766,7 @@ main(int argc, char *argv[])
quotefmtinstall();
fmtinstall('U', Ufmt);
fmtinstall('N', Nfmt);
fmtinstall(']', Mfmt);
fmtinstall('E', Efmt);
fmtinstall('[', encodefmt);
fmtinstall('H', encodefmt);

View file

@ -637,7 +637,7 @@ http(char *m, Url *u, Key *shdr, Buq *qbody, Buq *qpost)
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 @@ http(char *m, Url *u, Key *shdr, Buq *qbody, Buq *qpost)
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");
}

View file

@ -82,6 +82,14 @@ Nfmt(Fmt *f)
return 0;
}
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)
{
@ -101,7 +109,7 @@ Ufmt(Fmt *f)
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);
}

View file

@ -336,13 +336,12 @@ dtgexec(DTActGr *g, DTTrigInfo *info)
}
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 @@ dtptrigger(DTProbe *p, int machno, DTTrigInfo *info)
if(dtgexec(e->gr, info) < 0)
e->gr->chan->state = DTCFAULT;
}
dtmachunlock(machno);
dtmachunlock(info->machno);
}