20110512-2206

This commit is contained in:
charles forsyth 2011-05-12 22:06:54 +01:00
commit 44b904efbb
31 changed files with 6121 additions and 0 deletions

16
LICENSE Normal file
View File

@ -0,0 +1,16 @@
The authors of this software are Bob Flandrena, Ken Thompson,
Rob Pike, and Russ Cox.
Copyright (c) 1992-2002 by Lucent Technologies.
Permission to use, copy, modify, and distribute this software for any
purpose without fee is hereby granted, provided that this entire notice
is included in all copies of any software which is or includes a copy
or modification of this software and in all copies of the supporting
documentation for such software.
THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.

25
authnone.c Normal file
View File

@ -0,0 +1,25 @@
#include <plan9.h>
#include <fcall.h>
#include <u9fs.h>
static char*
noneauth(Fcall *rx, Fcall *tx)
{
USED(rx);
USED(tx);
return "u9fs authnone: no authentication required";
}
static char*
noneattach(Fcall *rx, Fcall *tx)
{
USED(rx);
USED(tx);
return nil;
}
Auth authnone = {
"none",
noneauth,
noneattach,
};

538
authp9any.c Normal file
View File

@ -0,0 +1,538 @@
/*
* 4th Edition p9any/p9sk1 authentication based on auth9p1.c
* Nigel Roles (nigel@9fs.org) 2003
*/
#include <plan9.h>
#include <fcall.h>
#include <u9fs.h>
#include <stdlib.h> /* for random stuff */
typedef struct Ticket Ticket;
typedef struct Ticketreq Ticketreq;
typedef struct Authenticator Authenticator;
enum
{
DOMLEN= 48, /* length of an authentication domain name */
CHALLEN= 8 /* length of a challenge */
};
enum {
HaveProtos,
NeedProto,
NeedChal,
HaveTreq,
NeedTicket,
HaveAuth,
Established,
};
/* encryption numberings (anti-replay) */
enum
{
AuthTreq=1, /* ticket request */
AuthChal=2, /* challenge box request */
AuthPass=3, /* change password */
AuthOK=4, /* fixed length reply follows */
AuthErr=5, /* error follows */
AuthMod=6, /* modify user */
AuthApop=7, /* apop authentication for pop3 */
AuthOKvar=9, /* variable length reply follows */
AuthChap=10, /* chap authentication for ppp */
AuthMSchap=11, /* MS chap authentication for ppp */
AuthCram=12, /* CRAM verification for IMAP (RFC2195 & rfc2104) */
AuthHttp=13, /* http domain login */
AuthVNC=14, /* http domain login */
AuthTs=64, /* ticket encrypted with server's key */
AuthTc, /* ticket encrypted with client's key */
AuthAs, /* server generated authenticator */
AuthAc, /* client generated authenticator */
AuthTp, /* ticket encrypted with client's key for password change */
AuthHr /* http reply */
};
struct Ticketreq
{
char type;
char authid[NAMELEN]; /* server's encryption id */
char authdom[DOMLEN]; /* server's authentication domain */
char chal[CHALLEN]; /* challenge from server */
char hostid[NAMELEN]; /* host's encryption id */
char uid[NAMELEN]; /* uid of requesting user on host */
};
#define TICKREQLEN (3*NAMELEN+CHALLEN+DOMLEN+1)
struct Ticket
{
char num; /* replay protection */
char chal[CHALLEN]; /* server challenge */
char cuid[NAMELEN]; /* uid on client */
char suid[NAMELEN]; /* uid on server */
char key[DESKEYLEN]; /* nonce DES key */
};
#define TICKETLEN (CHALLEN+2*NAMELEN+DESKEYLEN+1)
struct Authenticator
{
char num; /* replay protection */
char chal[CHALLEN];
ulong id; /* authenticator id, ++'d with each auth */
};
#define AUTHENTLEN (CHALLEN+4+1)
extern int chatty9p;
static int convT2M(Ticket*, char*, char*);
static void convM2T(char*, Ticket*, char*);
static void convM2Tnoenc(char*, Ticket*);
static int convA2M(Authenticator*, char*, char*);
static void convM2A(char*, Authenticator*, char*);
static int convTR2M(Ticketreq*, char*);
static void convM2TR(char*, Ticketreq*);
static int passtokey(char*, char*);
/*
* destructively encrypt the buffer, which
* must be at least 8 characters long.
*/
static int
encrypt9p(void *key, void *vbuf, int n)
{
char ekey[128], *buf;
int i, r;
if(n < 8)
return 0;
key_setup(key, ekey);
buf = vbuf;
n--;
r = n % 7;
n /= 7;
for(i = 0; i < n; i++){
block_cipher(ekey, buf, 0);
buf += 7;
}
if(r)
block_cipher(ekey, buf - 7 + r, 0);
return 1;
}
/*
* destructively decrypt the buffer, which
* must be at least 8 characters long.
*/
static int
decrypt9p(void *key, void *vbuf, int n)
{
char ekey[128], *buf;
int i, r;
if(n < 8)
return 0;
key_setup(key, ekey);
buf = vbuf;
n--;
r = n % 7;
n /= 7;
buf += n * 7;
if(r)
block_cipher(ekey, buf - 7 + r, 1);
for(i = 0; i < n; i++){
buf -= 7;
block_cipher(ekey, buf, 1);
}
return 1;
}
#define CHAR(x) *p++ = f->x
#define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2
#define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4
#define LONG(x) VLONG(f->x)
#define STRING(x,n) memmove(p, f->x, n); p += n
static int
convTR2M(Ticketreq *f, char *ap)
{
int n;
uchar *p;
p = (uchar*)ap;
CHAR(type);
STRING(authid, NAMELEN);
STRING(authdom, DOMLEN);
STRING(chal, CHALLEN);
STRING(hostid, NAMELEN);
STRING(uid, NAMELEN);
n = p - (uchar*)ap;
return n;
}
static int
convT2M(Ticket *f, char *ap, char *key)
{
int n;
uchar *p;
p = (uchar*)ap;
CHAR(num);
STRING(chal, CHALLEN);
STRING(cuid, NAMELEN);
STRING(suid, NAMELEN);
STRING(key, DESKEYLEN);
n = p - (uchar*)ap;
if(key)
encrypt9p(key, ap, n);
return n;
}
int
convA2M(Authenticator *f, char *ap, char *key)
{
int n;
uchar *p;
p = (uchar*)ap;
CHAR(num);
STRING(chal, CHALLEN);
LONG(id);
n = p - (uchar*)ap;
if(key)
encrypt9p(key, ap, n);
return n;
}
#undef CHAR
#undef SHORT
#undef VLONG
#undef LONG
#undef STRING
#define CHAR(x) f->x = *p++
#define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2
#define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4
#define LONG(x) VLONG(f->x)
#define STRING(x,n) memmove(f->x, p, n); p += n
void
convM2A(char *ap, Authenticator *f, char *key)
{
uchar *p;
if(key)
decrypt9p(key, ap, AUTHENTLEN);
p = (uchar*)ap;
CHAR(num);
STRING(chal, CHALLEN);
LONG(id);
USED(p);
}
void
convM2T(char *ap, Ticket *f, char *key)
{
uchar *p;
if(key)
decrypt9p(key, ap, TICKETLEN);
p = (uchar*)ap;
CHAR(num);
STRING(chal, CHALLEN);
STRING(cuid, NAMELEN);
f->cuid[NAMELEN-1] = 0;
STRING(suid, NAMELEN);
f->suid[NAMELEN-1] = 0;
STRING(key, DESKEYLEN);
USED(p);
}
#undef CHAR
#undef SHORT
#undef LONG
#undef VLONG
#undef STRING
static int
passtokey(char *key, char *p)
{
uchar buf[NAMELEN], *t;
int i, n;
n = strlen(p);
if(n >= NAMELEN)
n = NAMELEN-1;
memset(buf, ' ', 8);
t = buf;
strncpy((char*)t, p, n);
t[n] = 0;
memset(key, 0, DESKEYLEN);
for(;;){
for(i = 0; i < DESKEYLEN; i++)
key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1)));
if(n <= 8)
return 1;
n -= 8;
t += 8;
if(n < 8){
t -= 8 - n;
n = 8;
}
encrypt9p(key, t, 8);
}
return 1; /* not reached */
}
static char authkey[DESKEYLEN];
static char *authid;
static char *authdom;
static char *haveprotosmsg;
static char *needprotomsg;
static void
p9anyinit(void)
{
int n, fd;
char abuf[200];
char *af, *f[4];
af = autharg;
if(af == nil)
af = "/etc/u9fs.key";
if((fd = open(af, OREAD)) < 0)
sysfatal("can't open key file '%s'", af);
if((n = readn(fd, abuf, sizeof(abuf)-1)) < 0)
sysfatal("can't read key file '%s'", af);
if (n > 0 && abuf[n - 1] == '\n')
n--;
abuf[n] = '\0';
if(getfields(abuf, f, nelem(f), 0, "\n") != 3)
sysfatal("key file '%s' not exactly 3 lines", af);
passtokey(authkey, f[0]);
authid = strdup(f[1]);
authdom = strdup(f[2]);
haveprotosmsg = malloc(strlen("p9sk1") + 1 + strlen(authdom) + 1);
sprint(haveprotosmsg, "p9sk1@%s", authdom);
needprotomsg = malloc(strlen("p9sk1") + 1 + strlen(authdom) + 1);
sprint(needprotomsg, "p9sk1 %s", authdom);
}
typedef struct AuthSession {
int state;
char *uname;
char *aname;
char cchal[CHALLEN];
Ticketreq tr;
Ticket t;
} AuthSession;
static char*
p9anyauth(Fcall *rx, Fcall *tx)
{
AuthSession *sp;
Fid *f;
char *ep;
sp = malloc(sizeof(AuthSession));
f = newauthfid(rx->afid, sp, &ep);
if (f == nil) {
free(sp);
return ep;
}
if (chatty9p)
fprint(2, "p9anyauth: afid %d\n", rx->afid);
sp->state = HaveProtos;
sp->uname = strdup(rx->uname);
sp->aname = strdup(rx->aname);
tx->aqid.type = QTAUTH;
tx->aqid.path = 1;
tx->aqid.vers = 0;
return nil;
}
static char *
p9anyattach(Fcall *rx, Fcall *tx)
{
AuthSession *sp;
Fid *f;
char *ep;
f = oldauthfid(rx->afid, (void **)&sp, &ep);
if (f == nil)
return ep;
if (chatty9p)
fprint(2, "p9anyattach: afid %d state %d\n", rx->afid, sp->state);
if (sp->state == Established && strcmp(rx->uname, sp->uname) == 0
&& strcmp(rx->aname, sp->aname) == 0)
return nil;
return "authentication failed";
}
static int
readstr(Fcall *rx, Fcall *tx, char *s, int len)
{
if (rx->offset >= len)
return 0;
tx->count = len - rx->offset;
if (tx->count > rx->count)
tx->count = rx->count;
memcpy(tx->data, s + rx->offset, tx->count);
return tx->count;
}
static char *
p9anyread(Fcall *rx, Fcall *tx)
{
AuthSession *sp;
char *ep;
Fid *f;
f = oldauthfid(rx->afid, (void **)&sp, &ep);
if (f == nil)
return ep;
if (chatty9p)
fprint(2, "p9anyread: afid %d state %d\n", rx->fid, sp->state);
switch (sp->state) {
case HaveProtos:
readstr(rx, tx, haveprotosmsg, strlen(haveprotosmsg) + 1);
if (rx->offset + tx->count == strlen(haveprotosmsg) + 1)
sp->state = NeedProto;
return nil;
case HaveTreq:
if (rx->count != TICKREQLEN)
goto botch;
convTR2M(&sp->tr, tx->data);
tx->count = TICKREQLEN;
sp->state = NeedTicket;
return nil;
case HaveAuth: {
Authenticator a;
if (rx->count != AUTHENTLEN)
goto botch;
a.num = AuthAs;
memmove(a.chal, sp->cchal, CHALLEN);
a.id = 0;
convA2M(&a, (char*)tx->data, sp->t.key);
memset(sp->t.key, 0, sizeof(sp->t.key));
tx->count = rx->count;
sp->state = Established;
return nil;
}
default:
botch:
return "protocol botch";
}
}
static char *
p9anywrite(Fcall *rx, Fcall *tx)
{
AuthSession *sp;
char *ep;
Fid *f;
f = oldauthfid(rx->afid, (void **)&sp, &ep);
if (f == nil)
return ep;
if (chatty9p)
fprint(2, "p9anywrite: afid %d state %d\n", rx->fid, sp->state);
switch (sp->state) {
case NeedProto:
if (rx->count != strlen(needprotomsg) + 1)
return "protocol response wrong length";
if (memcmp(rx->data, needprotomsg, rx->count) != 0)
return "unacceptable protocol";
sp->state = NeedChal;
tx->count = rx->count;
return nil;
case NeedChal:
if (rx->count != CHALLEN)
goto botch;
memmove(sp->cchal, rx->data, CHALLEN);
sp->tr.type = AuthTreq;
safecpy(sp->tr.authid, authid, sizeof(sp->tr.authid));
safecpy(sp->tr.authdom, authdom, sizeof(sp->tr.authdom));
randombytes((uchar *)sp->tr.chal, CHALLEN);
safecpy(sp->tr.hostid, "", sizeof(sp->tr.hostid));
safecpy(sp->tr.uid, "", sizeof(sp->tr.uid));
tx->count = rx->count;
sp->state = HaveTreq;
return nil;
case NeedTicket: {
Authenticator a;
if (rx->count != TICKETLEN + AUTHENTLEN) {
fprint(2, "bad length in attach");
goto botch;
}
convM2T((char*)rx->data, &sp->t, authkey);
if (sp->t.num != AuthTs) {
fprint(2, "bad AuthTs in attach\n");
goto botch;
}
if (memcmp(sp->t.chal, sp->tr.chal, CHALLEN) != 0) {
fprint(2, "bad challenge in attach\n");
goto botch;
}
convM2A((char*)rx->data + TICKETLEN, &a, sp->t.key);
if (a.num != AuthAc) {
fprint(2, "bad AuthAs in attach\n");
goto botch;
}
if(memcmp(a.chal, sp->tr.chal, CHALLEN) != 0) {
fprint(2, "bad challenge in attach 2\n");
goto botch;
}
sp->state = HaveAuth;
tx->count = rx->count;
return nil;
}
default:
botch:
return "protocol botch";
}
}
static void
safefree(char *p)
{
if (p) {
memset(p, 0, strlen(p));
free(p);
}
}
static char *
p9anyclunk(Fcall *rx, Fcall *tx)
{
Fid *f;
AuthSession *sp;
char *ep;
f = oldauthfid(rx->afid, (void **)&sp, &ep);
if (f == nil)
return ep;
if (chatty9p)
fprint(2, "p9anyclunk: afid %d\n", rx->fid);
safefree(sp->uname);
safefree(sp->aname);
memset(sp, 0, sizeof(sp));
free(sp);
return nil;
}
Auth authp9any = {
"p9any",
p9anyauth,
p9anyattach,
p9anyinit,
p9anyread,
p9anywrite,
p9anyclunk,
};

38
authrhosts.c Normal file
View File

@ -0,0 +1,38 @@
#include <plan9.h>
#include <fcall.h>
#include <u9fs.h>
/*
* return whether the user is authenticated.
* uses berkeley-style rhosts ``authentication''.
* this is only a good idea behind a firewall,
* where you trust your network, and even then
* not such a great idea. it's grandfathered.
*/
static char*
rhostsauth(Fcall *rx, Fcall *tx)
{
USED(rx);
USED(tx);
return "u9fs rhostsauth: no authentication required";
}
static char*
rhostsattach(Fcall *rx, Fcall *tx)
{
USED(tx);
if(ruserok(remotehostname, 0, rx->uname, rx->uname) < 0){
fprint(2, "ruserok(%s, %s) not okay\n", remotehostname, rx->uname);
return "u9fs: rhosts authentication failed";
}
return 0;
}
Auth authrhosts = {
"rhosts",
rhostsauth,
rhostsattach,
};

89
convD2M.c Normal file
View File

@ -0,0 +1,89 @@
#include <plan9.h>
#include <fcall.h>
uint
sizeD2M(Dir *d)
{
char *sv[4];
int i, ns;
sv[0] = d->name;
sv[1] = d->uid;
sv[2] = d->gid;
sv[3] = d->muid;
ns = 0;
for(i = 0; i < 4; i++)
ns += strlen(sv[i]);
return STATFIXLEN + ns;
}
uint
convD2M(Dir *d, uchar *buf, uint nbuf)
{
uchar *p, *ebuf;
char *sv[4];
int i, ns, nsv[4], ss;
if(nbuf < BIT16SZ)
return 0;
p = buf;
ebuf = buf + nbuf;
sv[0] = d->name;
sv[1] = d->uid;
sv[2] = d->gid;
sv[3] = d->muid;
ns = 0;
for(i = 0; i < 4; i++){
nsv[i] = strlen(sv[i]);
ns += nsv[i];
}
ss = STATFIXLEN + ns;
/* set size befor erroring, so user can know how much is needed */
/* note that length excludes count field itself */
PBIT16(p, ss-BIT16SZ);
p += BIT16SZ;
if(ss > nbuf)
return BIT16SZ;
PBIT16(p, d->type);
p += BIT16SZ;
PBIT32(p, d->dev);
p += BIT32SZ;
PBIT8(p, d->qid.type);
p += BIT8SZ;
PBIT32(p, d->qid.vers);
p += BIT32SZ;
PBIT64(p, d->qid.path);
p += BIT64SZ;
PBIT32(p, d->mode);
p += BIT32SZ;
PBIT32(p, d->atime);
p += BIT32SZ;
PBIT32(p, d->mtime);
p += BIT32SZ;
PBIT64(p, d->length);
p += BIT64SZ;
for(i = 0; i < 4; i++){
ns = nsv[i];
if(p + ns + BIT16SZ > ebuf)
return 0;
PBIT16(p, ns);
p += BIT16SZ;
memmove(p, sv[i], ns);
p += ns;
}
if(ss != p - buf)
return 0;
return p - buf;
}

92
convM2D.c Normal file
View File

@ -0,0 +1,92 @@
#include <plan9.h>
#include <fcall.h>
int
statcheck(uchar *buf, uint nbuf)
{
uchar *ebuf;
int i;
ebuf = buf + nbuf;
buf += STATFIXLEN - 4 * BIT16SZ;
for(i = 0; i < 4; i++){
if(buf + BIT16SZ > ebuf)
return -1;
buf += BIT16SZ + GBIT16(buf);
}
if(buf != ebuf)
return -1;
return 0;
}
static char nullstring[] = "";
uint
convM2D(uchar *buf, uint nbuf, Dir *d, char *strs)
{
uchar *p, *ebuf;
char *sv[4];
int i, ns;
p = buf;
ebuf = buf + nbuf;
p += BIT16SZ; /* ignore size */
d->type = GBIT16(p);
p += BIT16SZ;
d->dev = GBIT32(p);
p += BIT32SZ;
d->qid.type = GBIT8(p);
p += BIT8SZ;
d->qid.vers = GBIT32(p);
p += BIT32SZ;
d->qid.path = GBIT64(p);
p += BIT64SZ;
d->mode = GBIT32(p);
p += BIT32SZ;
d->atime = GBIT32(p);
p += BIT32SZ;
d->mtime = GBIT32(p);
p += BIT32SZ;
d->length = GBIT64(p);
p += BIT64SZ;
d->name = nil;
d->uid = nil;
d->gid = nil;
d->muid = nil;
for(i = 0; i < 4; i++){
if(p + BIT16SZ > ebuf)
return 0;
ns = GBIT16(p);
p += BIT16SZ;
if(p + ns > ebuf)
return 0;
if(strs){
sv[i] = strs;
memmove(strs, p, ns);
strs += ns;
*strs++ = '\0';
}
p += ns;
}
if(strs){
d->name = sv[0];
d->uid = sv[1];
d->gid = sv[2];
d->muid = sv[3];
}else{
d->name = nullstring;
d->uid = nullstring;
d->gid = nullstring;
d->muid = nullstring;
}
return p - buf;
}

382
convM2S.c Normal file
View File

@ -0,0 +1,382 @@
#include <plan9.h>
#include <fcall.h>
static
uchar*
gstring(uchar *p, uchar *ep, char **s)
{
uint n;
if(p+BIT16SZ > ep)
return nil;
n = GBIT16(p);
p += BIT16SZ - 1;
if(p+n+1 > ep)
return nil;
/* move it down, on top of count, to make room for '\0' */
memmove(p, p + 1, n);
p[n] = '\0';
*s = (char*)p;
p += n+1;
return p;
}
static
uchar*
gqid(uchar *p, uchar *ep, Qid *q)
{
if(p+QIDSZ > ep)
return nil;
q->type = GBIT8(p);
p += BIT8SZ;
q->vers = GBIT32(p);
p += BIT32SZ;
q->path = GBIT64(p);
p += BIT64SZ;
return p;
}
/*
* no syntactic checks.
* three causes for error:
* 1. message size field is incorrect
* 2. input buffer too short for its own data (counts too long, etc.)
* 3. too many names or qids
* gqid() and gstring() return nil if they would reach beyond buffer.
* main switch statement checks range and also can fall through
* to test at end of routine.
*/
uint
convM2S(uchar *ap, uint nap, Fcall *f)
{
uchar *p, *ep;
uint i, size;
p = ap;
ep = p + nap;
if(p+BIT32SZ+BIT8SZ+BIT16SZ > ep)
return 0;
size = GBIT32(p);
p += BIT32SZ;
if(size > nap)
return 0;
if(size < BIT32SZ+BIT8SZ+BIT16SZ)
return 0;
f->type = GBIT8(p);
p += BIT8SZ;
f->tag = GBIT16(p);
p += BIT16SZ;
switch(f->type)
{
default:
return 0;
case Tversion:
if(p+BIT32SZ > ep)
return 0;
f->msize = GBIT32(p);
p += BIT32SZ;
p = gstring(p, ep, &f->version);
break;
/*
case Tsession:
if(p+BIT16SZ > ep)
return 0;
f->nchal = GBIT16(p);
p += BIT16SZ;
if(p+f->nchal > ep)
return 0;
f->chal = p;
p += f->nchal;
break;
*/
case Tflush:
if(p+BIT16SZ > ep)
return 0;
f->oldtag = GBIT16(p);
p += BIT16SZ;
break;
case Tauth:
if(p+BIT32SZ > ep)
return 0;
f->afid = GBIT32(p);
p += BIT32SZ;
p = gstring(p, ep, &f->uname);
if(p == nil)
break;
p = gstring(p, ep, &f->aname);
if(p == nil)
break;
break;
/*
b
case Tattach:
if(p+BIT32SZ > ep)
return 0;
f->fid = GBIT32(p);
p += BIT32SZ;
p = gstring(p, ep, &f->uname);
if(p == nil)
break;
p = gstring(p, ep, &f->aname);
if(p == nil)
break;
if(p+BIT16SZ > ep)
return 0;
f->nauth = GBIT16(p);
p += BIT16SZ;
if(p+f->nauth > ep)
return 0;
f->auth = p;
p += f->nauth;
break;
*/
case Tattach:
if(p+BIT32SZ > ep)
return 0;
f->fid = GBIT32(p);
p += BIT32SZ;
if(p+BIT32SZ > ep)
return 0;
f->afid = GBIT32(p);
p += BIT32SZ;
p = gstring(p, ep, &f->uname);
if(p == nil)
break;
p = gstring(p, ep, &f->aname);
if(p == nil)
break;
break;
case Twalk:
if(p+BIT32SZ+BIT32SZ+BIT16SZ > ep)
return 0;
f->fid = GBIT32(p);
p += BIT32SZ;
f->newfid = GBIT32(p);
p += BIT32SZ;
f->nwname = GBIT16(p);
p += BIT16SZ;
if(f->nwname > MAXWELEM)
return 0;
for(i=0; i<f->nwname; i++){
p = gstring(p, ep, &f->wname[i]);
if(p == nil)
break;
}
break;
case Topen:
if(p+BIT32SZ+BIT8SZ > ep)
return 0;
f->fid = GBIT32(p);
p += BIT32SZ;
f->mode = GBIT8(p);
p += BIT8SZ;
break;
case Tcreate:
if(p+BIT32SZ > ep)
return 0;
f->fid = GBIT32(p);
p += BIT32SZ;
p = gstring(p, ep, &f->name);
if(p == nil)
break;
if(p+BIT32SZ+BIT8SZ > ep)
return 0;
f->perm = GBIT32(p);
p += BIT32SZ;
f->mode = GBIT8(p);
p += BIT8SZ;
break;
case Tread:
if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
return 0;
f->fid = GBIT32(p);
p += BIT32SZ;
f->offset = GBIT64(p);
p += BIT64SZ;
f->count = GBIT32(p);
p += BIT32SZ;
break;
case Twrite:
if(p+BIT32SZ+BIT64SZ+BIT32SZ > ep)
return 0;
f->fid = GBIT32(p);
p += BIT32SZ;
f->offset = GBIT64(p);
p += BIT64SZ;
f->count = GBIT32(p);
p += BIT32SZ;
if(p+f->count > ep)
return 0;
f->data = (char*)p;
p += f->count;
break;
case Tclunk:
case Tremove:
if(p+BIT32SZ > ep)
return 0;
f->fid = GBIT32(p);
p += BIT32SZ;
break;
case Tstat:
if(p+BIT32SZ > ep)
return 0;
f->fid = GBIT32(p);
p += BIT32SZ;
break;
case Twstat:
if(p+BIT32SZ+BIT16SZ > ep)
return 0;
f->fid = GBIT32(p);
p += BIT32SZ;
f->nstat = GBIT16(p);
p += BIT16SZ;
if(p+f->nstat > ep)
return 0;
f->stat = p;
p += f->nstat;
break;
/*
*/
case Rversion:
if(p+BIT32SZ > ep)
return 0;
f->msize = GBIT32(p);
p += BIT32SZ;
p = gstring(p, ep, &f->version);
break;
/*
case Rsession:
if(p+BIT16SZ > ep)
return 0;
f->nchal = GBIT16(p);
p += BIT16SZ;
if(p+f->nchal > ep)
return 0;
f->chal = p;
p += f->nchal;
p = gstring(p, ep, &f->authid);
if(p == nil)
break;
p = gstring(p, ep, &f->authdom);
break;
*/
case Rerror:
p = gstring(p, ep, &f->ename);
break;
case Rflush:
break;
/*
case Rattach:
p = gqid(p, ep, &f->qid);
if(p == nil)
break;
if(p+BIT16SZ > ep)
return 0;
f->nrauth = GBIT16(p);
p += BIT16SZ;
if(p+f->nrauth > ep)
return 0;
f->rauth = p;
p += f->nrauth;
break;
*/
case Rattach:
p = gqid(p, ep, &f->qid);
if(p == nil)
break;
break;
case Rwalk:
if(p+BIT16SZ > ep)
return 0;
f->nwqid = GBIT16(p);
p += BIT16SZ;
if(f->nwqid > MAXWELEM)
return 0;
for(i=0; i<f->nwqid; i++){
p = gqid(p, ep, &f->wqid[i]);
if(p == nil)
break;
}
break;
case Ropen:
case Rcreate:
p = gqid(p, ep, &f->qid);
if(p == nil)
break;
if(p+BIT32SZ > ep)
return 0;
f->iounit = GBIT32(p);
p += BIT32SZ;
break;
case Rread:
if(p+BIT32SZ > ep)
return 0;
f->count = GBIT32(p);
p += BIT32SZ;
if(p+f->count > ep)
return 0;
f->data = (char*)p;
p += f->count;
break;
case Rwrite:
if(p+BIT32SZ > ep)
return 0;
f->count = GBIT32(p);
p += BIT32SZ;
break;
case Rclunk:
case Rremove:
break;
case Rstat:
if(p+BIT16SZ > ep)
return 0;
f->nstat = GBIT16(p);
p += BIT16SZ;
if(p+f->nstat > ep)
return 0;
f->stat = p;
p += f->nstat;
break;
case Rwstat:
break;
}
if(p==nil || p>ep)
return 0;
if(ap+size == p)
return size;
return 0;
}

423
convS2M.c Normal file
View File

@ -0,0 +1,423 @@
#include <plan9.h>
#include <fcall.h>
static
uchar*
pstring(uchar *p, char *s)
{
uint n;
n = strlen(s);
PBIT16(p, n);
p += BIT16SZ;
memmove(p, s, n);
p += n;
return p;
}
static
uchar*
pqid(uchar *p, Qid *q)
{
PBIT8(p, q->type);
p += BIT8SZ;
PBIT32(p, q->vers);
p += BIT32SZ;
PBIT64(p, q->path);
p += BIT64SZ;
return p;
}
static
uint
stringsz(char *s)
{
return BIT16SZ+strlen(s);
}
static
uint
sizeS2M(Fcall *f)
{
uint n;
int i;
n = 0;
n += BIT32SZ; /* size */
n += BIT8SZ; /* type */
n += BIT16SZ; /* tag */
switch(f->type)
{
default:
return 0;
case Tversion:
n += BIT32SZ;
n += stringsz(f->version);
break;
/*
case Tsession:
n += BIT16SZ;
n += f->nchal;
break;
*/
case Tflush:
n += BIT16SZ;
break;
case Tauth:
n += BIT32SZ;
n += stringsz(f->uname);
n += stringsz(f->aname);
break;
case Tattach:
n += BIT32SZ;
n += BIT32SZ;
n += stringsz(f->uname);
n += stringsz(f->aname);
break;
case Twalk:
n += BIT32SZ;
n += BIT32SZ;
n += BIT16SZ;
for(i=0; i<f->nwname; i++)
n += stringsz(f->wname[i]);
break;
case Topen:
n += BIT32SZ;
n += BIT8SZ;
break;
case Tcreate:
n += BIT32SZ;
n += stringsz(f->name);
n += BIT32SZ;
n += BIT8SZ;
break;
case Tread:
n += BIT32SZ;
n += BIT64SZ;
n += BIT32SZ;
break;
case Twrite:
n += BIT32SZ;
n += BIT64SZ;
n += BIT32SZ;
n += f->count;
break;
case Tclunk:
case Tremove:
n += BIT32SZ;
break;
case Tstat:
n += BIT32SZ;
break;
case Twstat:
n += BIT32SZ;
n += BIT16SZ;
n += f->nstat;
break;
/*
*/
case Rversion:
n += BIT32SZ;
n += stringsz(f->version);
break;
/*
case Rsession:
n += BIT16SZ;
n += f->nchal;
n += stringsz(f->authid);
n += stringsz(f->authdom);
break;
*/
case Rerror:
n += stringsz(f->ename);
break;
case Rflush:
break;
case Rauth:
n += QIDSZ;
break;
/*
case Rattach:
n += QIDSZ;
n += BIT16SZ;
n += f->nrauth;
break;
*/
case Rattach:
n += QIDSZ;
break;
case Rwalk:
n += BIT16SZ;
n += f->nwqid*QIDSZ;
break;
case Ropen:
case Rcreate:
n += QIDSZ;
n += BIT32SZ;
break;
case Rread:
n += BIT32SZ;
n += f->count;
break;
case Rwrite:
n += BIT32SZ;
break;
case Rclunk:
break;
case Rremove:
break;
case Rstat:
n += BIT16SZ;
n += f->nstat;
break;
case Rwstat:
break;
}
return n;
}
uint
convS2M(Fcall *f, uchar *ap, uint nap)
{
uchar *p;
uint i, size;
size = sizeS2M(f);
if(size == 0)
return 0;
if(size > nap)
return 0;
p = (uchar*)ap;
PBIT32(p, size);
p += BIT32SZ;
PBIT8(p, f->type);
p += BIT8SZ;
PBIT16(p, f->tag);
p += BIT16SZ;
switch(f->type)
{
default:
return 0;
case Tversion:
PBIT32(p, f->msize);
p += BIT32SZ;
p = pstring(p, f->version);
break;
/*
case Tsession:
PBIT16(p, f->nchal);
p += BIT16SZ;
f->chal = p;
p += f->nchal;
break;
*/
case Tflush:
PBIT16(p, f->oldtag);
p += BIT16SZ;
break;
case Tauth:
PBIT32(p, f->afid);
p += BIT32SZ;
p = pstring(p, f->uname);
p = pstring(p, f->aname);
break;
case Tattach:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT32(p, f->afid);
p += BIT32SZ;
p = pstring(p, f->uname);
p = pstring(p, f->aname);
break;
case Twalk:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT32(p, f->newfid);
p += BIT32SZ;
PBIT16(p, f->nwname);
p += BIT16SZ;
if(f->nwname > MAXWELEM)
return 0;
for(i=0; i<f->nwname; i++)
p = pstring(p, f->wname[i]);
break;
case Topen:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT8(p, f->mode);
p += BIT8SZ;
break;
case Tcreate:
PBIT32(p, f->fid);
p += BIT32SZ;
p = pstring(p, f->name);
PBIT32(p, f->perm);
p += BIT32SZ;
PBIT8(p, f->mode);
p += BIT8SZ;
break;
case Tread:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT64(p, f->offset);
p += BIT64SZ;
PBIT32(p, f->count);
p += BIT32SZ;
break;
case Twrite:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT64(p, f->offset);
p += BIT64SZ;
PBIT32(p, f->count);
p += BIT32SZ;
memmove(p, f->data, f->count);
p += f->count;
break;
case Tclunk:
case Tremove:
PBIT32(p, f->fid);
p += BIT32SZ;
break;
case Tstat:
PBIT32(p, f->fid);
p += BIT32SZ;
break;
case Twstat:
PBIT32(p, f->fid);
p += BIT32SZ;
PBIT16(p, f->nstat);
p += BIT16SZ;
memmove(p, f->stat, f->nstat);
p += f->nstat;
break;
/*
*/
case Rversion:
PBIT32(p, f->msize);
p += BIT32SZ;
p = pstring(p, f->version);
break;
/*
case Rsession:
PBIT16(p, f->nchal);
p += BIT16SZ;
f->chal = p;
p += f->nchal;
p = pstring(p, f->authid);
p = pstring(p, f->authdom);
break;
*/
case Rerror:
p = pstring(p, f->ename);
break;
case Rflush:
break;
case Rauth:
p = pqid(p, &f->aqid);
break;
case Rattach:
p = pqid(p, &f->qid);
break;
case Rwalk:
PBIT16(p, f->nwqid);
p += BIT16SZ;
if(f->nwqid > MAXWELEM)
return 0;
for(i=0; i<f->nwqid; i++)
p = pqid(p, &f->wqid[i]);
break;
case Ropen:
case Rcreate:
p = pqid(p, &f->qid);
PBIT32(p, f->iounit);
p += BIT32SZ;
break;
case Rread:
PBIT32(p, f->count);
p += BIT32SZ;
memmove(p, f->data, f->count);
p += f->count;
break;
case Rwrite:
PBIT32(p, f->count);
p += BIT32SZ;
break;
case Rclunk:
break;
case Rremove:
break;
case Rstat:
PBIT16(p, f->nstat);
p += BIT16SZ;
memmove(p, f->stat, f->nstat);
p += f->nstat;
break;
case Rwstat:
break;
}
if(size != p-ap)
return 0;
return size;
}

62
cygwin.c Normal file
View File

@ -0,0 +1,62 @@
/* compatability layer for u9fs support on CYGWIN */
#include <unistd.h>
#include <errno.h>
ssize_t
pread(int fd, void *p, size_t n, off_t off)
{
off_t ooff;
int oerrno;
if ((ooff = lseek(fd, off, SEEK_SET)) == -1)
return -1;
n = read(fd, p, n);
oerrno = errno;
lseek(fd, ooff, SEEK_SET);
errno = oerrno;
return n;
}
ssize_t
pwrite(int fd, const void *p, size_t n, off_t off)
{
off_t ooff;
int oerrno;
if ((ooff = lseek(fd, off, SEEK_SET)) == -1)
return -1;
n = write(fd, p, n);
oerrno = errno;
lseek(fd, ooff, SEEK_SET);
errno = oerrno;
return n;
}
int
setreuid(int ruid, int euid)
{
if (ruid != -1)
if (setuid(ruid) == -1)
return(-1);
if (euid != -1)
if (seteuid(euid) == -1)
return(-1);
}
int
setregid(int rgid, int egid)
{
if (rgid != -1)
if (setgid(rgid) == -1)
return(-1);
if (egid != -1)
if (setegid(egid) == -1)
return(-1);
}

355
des.c Normal file
View File

@ -0,0 +1,355 @@
#include <plan9.h>
/*
* Data Encryption Standard
* D.P.Mitchell 83/06/08.
*
* block_cipher(key, block, decrypting)
*/
static long ip_low(char [8]);
static long ip_high(char [8]);
static void fp(long, long, char[8]);
extern int chatty9p;
/*
* Tables for Combined S and P Boxes
*/
static long s0p[] = {
0x00410100,0x00010000,0x40400000,0x40410100,0x00400000,0x40010100,0x40010000,0x40400000,
0x40010100,0x00410100,0x00410000,0x40000100,0x40400100,0x00400000,0x00000000,0x40010000,
0x00010000,0x40000000,0x00400100,0x00010100,0x40410100,0x00410000,0x40000100,0x00400100,
0x40000000,0x00000100,0x00010100,0x40410000,0x00000100,0x40400100,0x40410000,0x00000000,
0x00000000,0x40410100,0x00400100,0x40010000,0x00410100,0x00010000,0x40000100,0x00400100,
0x40410000,0x00000100,0x00010100,0x40400000,0x40010100,0x40000000,0x40400000,0x00410000,
0x40410100,0x00010100,0x00410000,0x40400100,0x00400000,0x40000100,0x40010000,0x00000000,
0x00010000,0x00400000,0x40400100,0x00410100,0x40000000,0x40410000,0x00000100,0x40010100,
};
static long s1p[] = {
0x08021002,0x00000000,0x00021000,0x08020000,0x08000002,0x00001002,0x08001000,0x00021000,
0x00001000,0x08020002,0x00000002,0x08001000,0x00020002,0x08021000,0x08020000,0x00000002,
0x00020000,0x08001002,0x08020002,0x00001000,0x00021002,0x08000000,0x00000000,0x00020002,
0x08001002,0x00021002,0x08021000,0x08000002,0x08000000,0x00020000,0x00001002,0x08021002,
0x00020002,0x08021000,0x08001000,0x00021002,0x08021002,0x00020002,0x08000002,0x00000000,
0x08000000,0x00001002,0x00020000,0x08020002,0x00001000,0x08000000,0x00021002,0x08001002,
0x08021000,0x00001000,0x00000000,0x08000002,0x00000002,0x08021002,0x00021000,0x08020000,
0x08020002,0x00020000,0x00001002,0x08001000,0x08001002,0x00000002,0x08020000,0x00021000,
};
static long s2p[] = {
0x20800000,0x00808020,0x00000020,0x20800020,0x20008000,0x00800000,0x20800020,0x00008020,
0x00800020,0x00008000,0x00808000,0x20000000,0x20808020,0x20000020,0x20000000,0x20808000,
0x00000000,0x20008000,0x00808020,0x00000020,0x20000020,0x20808020,0x00008000,0x20800000,
0x20808000,0x00800020,0x20008020,0x00808000,0x00008020,0x00000000,0x00800000,0x20008020,
0x00808020,0x00000020,0x20000000,0x00008000,0x20000020,0x20008000,0x00808000,0x20800020,
0x00000000,0x00808020,0x00008020,0x20808000,0x20008000,0x00800000,0x20808020,0x20000000,
0x20008020,0x20800000,0x00800000,0x20808020,0x00008000,0x00800020,0x20800020,0x00008020,
0x00800020,0x00000000,0x20808000,0x20000020,0x20800000,0x20008020,0x00000020,0x00808000,
};
static long s3p[] = {
0x00080201,0x02000200,0x00000001,0x02080201,0x00000000,0x02080000,0x02000201,0x00080001,
0x02080200,0x02000001,0x02000000,0x00000201,0x02000001,0x00080201,0x00080000,0x02000000,
0x02080001,0x00080200,0x00000200,0x00000001,0x00080200,0x02000201,0x02080000,0x00000200,
0x00000201,0x00000000,0x00080001,0x02080200,0x02000200,0x02080001,0x02080201,0x00080000,
0x02080001,0x00000201,0x00080000,0x02000001,0x00080200,0x02000200,0x00000001,0x02080000,
0x02000201,0x00000000,0x00000200,0x00080001,0x00000000,0x02080001,0x02080200,0x00000200,
0x02000000,0x02080201,0x00080201,0x00080000,0x02080201,0x00000001,0x02000200,0x00080201,
0x00080001,0x00080200,0x02080000,0x02000201,0x00000201,0x02000000,0x02000001,0x02080200,
};
static long s4p[] = {
0x01000000,0x00002000,0x00000080,0x01002084,0x01002004,0x01000080,0x00002084,0x01002000,
0x00002000,0x00000004,0x01000004,0x00002080,0x01000084,0x01002004,0x01002080,0x00000000,
0x00002080,0x01000000,0x00002004,0x00000084,0x01000080,0x00002084,0x00000000,0x01000004,
0x00000004,0x01000084,0x01002084,0x00002004,0x01002000,0x00000080,0x00000084,0x01002080,
0x01002080,0x01000084,0x00002004,0x01002000,0x00002000,0x00000004,0x01000004,0x01000080,
0x01000000,0x00002080,0x01002084,0x00000000,0x00002084,0x01000000,0x00000080,0x00002004,
0x01000084,0x00000080,0x00000000,0x01002084,0x01002004,0x01002080,0x00000084,0x00002000,
0x00002080,0x01002004,0x01000080,0x00000084,0x00000004,0x00002084,0x01002000,0x01000004,
};
static long s5p[] = {
0x10000008,0x00040008,0x00000000,0x10040400,0x00040008,0x00000400,0x10000408,0x00040000,
0x00000408,0x10040408,0x00040400,0x10000000,0x10000400,0x10000008,0x10040000,0x00040408,
0x00040000,0x10000408,0x10040008,0x00000000,0x00000400,0x00000008,0x10040400,0x10040008,
0x10040408,0x10040000,0x10000000,0x00000408,0x00000008,0x00040400,0x00040408,0x10000400,
0x00000408,0x10000000,0x10000400,0x00040408,0x10040400,0x00040008,0x00000000,0x10000400,
0x10000000,0x00000400,0x10040008,0x00040000,0x00040008,0x10040408,0x00040400,0x00000008,
0x10040408,0x00040400,0x00040000,0x10000408,0x10000008,0x10040000,0x00040408,0x00000000,
0x00000400,0x10000008,0x10000408,0x10040400,0x10040000,0x00000408,0x00000008,0x10040008,
};
static long s6p[] = {
0x00000800,0x00000040,0x00200040,0x80200000,0x80200840,0x80000800,0x00000840,0x00000000,
0x00200000,0x80200040,0x80000040,0x00200800,0x80000000,0x00200840,0x00200800,0x80000040,
0x80200040,0x00000800,0x80000800,0x80200840,0x00000000,0x00200040,0x80200000,0x00000840,
0x80200800,0x80000840,0x00200840,0x80000000,0x80000840,0x80200800,0x00000040,0x00200000,
0x80000840,0x00200800,0x80200800,0x80000040,0x00000800,0x00000040,0x00200000,0x80200800,
0x80200040,0x80000840,0x00000840,0x00000000,0x00000040,0x80200000,0x80000000,0x00200040,
0x00000000,0x80200040,0x00200040,0x00000840,0x80000040,0x00000800,0x80200840,0x00200000,
0x00200840,0x80000000,0x80000800,0x80200840,0x80200000,0x00200840,0x00200800,0x80000800,
};
static long s7p[] = {
0x04100010,0x04104000,0x00004010,0x00000000,0x04004000,0x00100010,0x04100000,0x04104010,
0x00000010,0x04000000,0x00104000,0x00004010,0x00104010,0x04004010,0x04000010,0x04100000,
0x00004000,0x00104010,0x00100010,0x04004000,0x04104010,0x04000010,0x00000000,0x00104000,
0x04000000,0x00100000,0x04004010,0x04100010,0x00100000,0x00004000,0x04104000,0x00000010,
0x00100000,0x00004000,0x04000010,0x04104010,0x00004010,0x04000000,0x00000000,0x00104000,
0x04100010,0x04004010,0x04004000,0x00100010,0x04104000,0x00000010,0x00100010,0x04004000,
0x04104010,0x00100000,0x04100000,0x04000010,0x00104000,0x00004010,0x04004010,0x04100000,
0x00000010,0x04104000,0x00104010,0x00000000,0x04000000,0x04100010,0x00004000,0x00104010,
};
/*
* DES electronic codebook encryption of one block
*/
void
block_cipher(char expanded_key[128], char text[8], int decrypting)
{
char *key;
long crypto, temp, right, left;
int i, key_offset;
key = expanded_key;
left = ip_low(text);
right = ip_high(text);
if (decrypting) {
key_offset = 16;
key = key + 128 - 8;
} else
key_offset = 0;
for (i = 0; i < 16; i++) {
temp = (right << 1) | ((right >> 31) & 1);
crypto = s0p[(temp & 0x3f) ^ *key++];
crypto |= s1p[((temp >> 4) & 0x3f) ^ *key++];
crypto |= s2p[((temp >> 8) & 0x3f) ^ *key++];
crypto |= s3p[((temp >> 12) & 0x3f) ^ *key++];
crypto |= s4p[((temp >> 16) & 0x3f) ^ *key++];
crypto |= s5p[((temp >> 20) & 0x3f) ^ *key++];
crypto |= s6p[((temp >> 24) & 0x3f) ^ *key++];
temp = ((right & 1) << 5) | ((right >> 27) & 0x1f);
crypto |= s7p[temp ^ *key++];
temp = left;
left = right;
right = temp ^ crypto;
key -= key_offset;
}
/*
* standard final permutation (IPI)
* left and right are reversed here
*/
fp(right, left, text);
}
/*
* Initial Permutation
*/
static long iptab[] = {
0x00000000, 0x00008000, 0x00000000, 0x00008000,
0x00000080, 0x00008080, 0x00000080, 0x00008080
};
static long
ip_low(char block[8])
{
int i;
long l;
l = 0;
for(i = 0; i < 8; i++){
l |= iptab[(block[i] >> 4) & 7] >> i;
l |= iptab[block[i] & 7] << (16 - i);
}
return l;
}
static long
ip_high(char block[8])
{
int i;
long l;
l = 0;
for(i = 0; i < 8; i++){
l |= iptab[(block[i] >> 5) & 7] >> i;
l |= iptab[(block[i] >> 1) & 7] << (16 - i);
}
return l;
}
/*
* Final Permutation
*/
static unsigned long fptab[] = {
0x00000000,0x80000000,0x00800000,0x80800000,0x00008000,0x80008000,0x00808000,0x80808000,
0x00000080,0x80000080,0x00800080,0x80800080,0x00008080,0x80008080,0x00808080,0x80808080,
};
static void
fp(long left, long right, char text[8])
{
unsigned long ta[2], t, v[2];
int i, j, sh;
ta[0] = right;
ta[1] = left;
v[0] = v[1] = 0;
for(i = 0; i < 2; i++){
t = ta[i];
sh = i;
for(j = 0; j < 4; j++){
v[1] |= fptab[t & 0xf] >> sh;
t >>= 4;
v[0] |= fptab[t & 0xf] >> sh;
t >>= 4;
sh += 2;
}
}
for(i = 0; i < 2; i++)
for(j = 0; j < 4; j++){
*text++ = v[i];
v[i] >>= 8;
}
}
/*
* Key set-up
*/
static uchar keyexpand[][15][2] = {
{ 3, 2, 9, 8, 18, 8, 27, 32, 33, 2, 42, 16, 48, 8, 65, 16,
74, 2, 80, 2, 89, 4, 99, 16, 104, 4, 122, 32, 0, 0, },
{ 1, 4, 8, 1, 18, 4, 25, 32, 34, 32, 41, 8, 50, 8, 59, 32,
64, 16, 75, 4, 90, 1, 97, 16, 106, 2, 112, 2, 123, 1, },
{ 2, 1, 19, 8, 35, 1, 40, 1, 50, 4, 57, 32, 75, 2, 80, 32,
89, 1, 96, 16, 107, 4, 120, 8, 0, 0, 0, 0, 0, 0, },
{ 4, 32, 20, 2, 31, 4, 37, 32, 47, 1, 54, 1, 63, 2, 68, 1,
78, 4, 84, 8, 101, 16, 108, 4, 119, 16, 126, 8, 0, 0, },
{ 5, 4, 15, 4, 21, 32, 31, 1, 38, 1, 47, 2, 53, 2, 68, 8,
85, 16, 92, 4, 103, 16, 108, 32, 118, 32, 124, 2, 0, 0, },
{ 15, 2, 21, 2, 39, 8, 46, 16, 55, 32, 61, 1, 71, 16, 76, 32,
86, 32, 93, 4, 102, 2, 108, 16, 117, 8, 126, 1, 0, 0, },
{ 14, 16, 23, 32, 29, 1, 38, 8, 52, 2, 63, 4, 70, 2, 76, 16,
85, 8, 100, 1, 110, 4, 116, 8, 127, 8, 0, 0, 0, 0, },
{ 1, 8, 8, 32, 17, 1, 24, 16, 35, 4, 50, 1, 57, 16, 67, 8,
83, 1, 88, 1, 98, 4, 105, 32, 114, 32, 123, 2, 0, 0, },
{ 0, 1, 11, 16, 16, 4, 35, 2, 40, 32, 49, 1, 56, 16, 65, 2,
74, 16, 80, 8, 99, 8, 115, 1, 121, 4, 0, 0, 0, 0, },
{ 9, 16, 18, 2, 24, 2, 33, 4, 43, 16, 48, 4, 66, 32, 73, 8,
82, 8, 91, 32, 97, 2, 106, 16, 112, 8, 122, 1, 0, 0, },
{ 14, 32, 21, 4, 30, 2, 36, 16, 45, 8, 60, 1, 69, 2, 87, 8,
94, 16, 103, 32, 109, 1, 118, 8, 124, 32, 0, 0, 0, 0, },
{ 7, 4, 14, 2, 20, 16, 29, 8, 44, 1, 54, 4, 60, 8, 71, 8,
78, 16, 87, 32, 93, 1, 102, 8, 116, 2, 125, 4, 0, 0, },
{ 7, 2, 12, 1, 22, 4, 28, 8, 45, 16, 52, 4, 63, 16, 70, 8,
84, 2, 95, 4, 101, 32, 111, 1, 118, 1, 0, 0, 0, 0, },
{ 6, 16, 13, 16, 20, 4, 31, 16, 36, 32, 46, 32, 53, 4, 62, 2,
69, 32, 79, 1, 86, 1, 95, 2, 101, 2, 119, 8, 0, 0, },
{ 0, 32, 10, 8, 19, 32, 25, 2, 34, 16, 40, 8, 59, 8, 66, 2,
72, 2, 81, 4, 91, 16, 96, 4, 115, 2, 121, 8, 0, 0, },
{ 3, 16, 10, 4, 17, 32, 26, 32, 33, 8, 42, 8, 51, 32, 57, 2,
67, 4, 82, 1, 89, 16, 98, 2, 104, 2, 113, 4, 120, 1, },
{ 1, 16, 11, 8, 27, 1, 32, 1, 42, 4, 49, 32, 58, 32, 67, 2,
72, 32, 81, 1, 88, 16, 99, 4, 114, 1, 0, 0, 0, 0, },
{ 6, 32, 12, 2, 23, 4, 29, 32, 39, 1, 46, 1, 55, 2, 61, 2,
70, 4, 76, 8, 93, 16, 100, 4, 111, 16, 116, 32, 0, 0, },
{ 6, 2, 13, 32, 23, 1, 30, 1, 39, 2, 45, 2, 63, 8, 77, 16,
84, 4, 95, 16, 100, 32, 110, 32, 117, 4, 127, 4, 0, 0, },
{ 4, 1, 13, 2, 31, 8, 38, 16, 47, 32, 53, 1, 62, 8, 68, 32,
78, 32, 85, 4, 94, 2, 100, 16, 109, 8, 127, 2, 0, 0, },
{ 5, 16, 15, 32, 21, 1, 30, 8, 44, 2, 55, 4, 61, 32, 68, 16,
77, 8, 92, 1, 102, 4, 108, 8, 126, 16, 0, 0, 0, 0, },
{ 2, 8, 9, 1, 16, 16, 27, 4, 42, 1, 49, 16, 58, 2, 75, 1,
80, 1, 90, 4, 97, 32, 106, 32, 113, 8, 120, 32, 0, 0, },
{ 2, 4, 8, 4, 27, 2, 32, 32, 41, 1, 48, 16, 59, 4, 66, 16,
72, 8, 91, 8, 107, 1, 112, 1, 123, 16, 0, 0, 0, 0, },
{ 3, 8, 10, 2, 16, 2, 25, 4, 35, 16, 40, 4, 59, 2, 65, 8,
74, 8, 83, 32, 89, 2, 98, 16, 104, 8, 121, 16, 0, 0, },
{ 4, 2, 13, 4, 22, 2, 28, 16, 37, 8, 52, 1, 62, 4, 79, 8,
86, 16, 95, 32, 101, 1, 110, 8, 126, 32, 0, 0, 0, 0, },
{ 5, 32, 12, 16, 21, 8, 36, 1, 46, 4, 52, 8, 70, 16, 79, 32,
85, 1, 94, 8, 108, 2, 119, 4, 126, 2, 0, 0, 0, 0, },
{ 5, 2, 14, 4, 20, 8, 37, 16, 44, 4, 55, 16, 60, 32, 76, 2,
87, 4, 93, 32, 103, 1, 110, 1, 119, 2, 124, 1, 0, 0, },
{ 7, 32, 12, 4, 23, 16, 28, 32, 38, 32, 45, 4, 54, 2, 60, 16,
71, 1, 78, 1, 87, 2, 93, 2, 111, 8, 118, 16, 125, 16, },
{ 1, 1, 11, 32, 17, 2, 26, 16, 32, 8, 51, 8, 64, 2, 73, 4,
83, 16, 88, 4, 107, 2, 112, 32, 122, 8, 0, 0, 0, 0, },
{ 0, 4, 9, 32, 18, 32, 25, 8, 34, 8, 43, 32, 49, 2, 58, 16,
74, 1, 81, 16, 90, 2, 96, 2, 105, 4, 115, 16, 122, 4, },
{ 2, 2, 19, 1, 24, 1, 34, 4, 41, 32, 50, 32, 57, 8, 64, 32,
73, 1, 80, 16, 91, 4, 106, 1, 113, 16, 123, 8, 0, 0, },
{ 3, 4, 10, 16, 16, 8, 35, 8, 51, 1, 56, 1, 67, 16, 72, 4,
91, 2, 96, 32, 105, 1, 112, 16, 121, 2, 0, 0, 0, 0, },
{ 4, 16, 15, 1, 22, 1, 31, 2, 37, 2, 55, 8, 62, 16, 69, 16,
76, 4, 87, 16, 92, 32, 102, 32, 109, 4, 118, 2, 125, 32, },
{ 6, 4, 23, 8, 30, 16, 39, 32, 45, 1, 54, 8, 70, 32, 77, 4,
86, 2, 92, 16, 101, 8, 116, 1, 125, 2, 0, 0, 0, 0, },
{ 4, 4, 13, 1, 22, 8, 36, 2, 47, 4, 53, 32, 63, 1, 69, 8,
84, 1, 94, 4, 100, 8, 117, 16, 127, 32, 0, 0, 0, 0, },
{ 3, 32, 8, 16, 19, 4, 34, 1, 41, 16, 50, 2, 56, 2, 67, 1,
72, 1, 82, 4, 89, 32, 98, 32, 105, 8, 114, 8, 121, 1, },
{ 1, 32, 19, 2, 24, 32, 33, 1, 40, 16, 51, 4, 64, 8, 83, 8,
99, 1, 104, 1, 114, 4, 120, 4, 0, 0, 0, 0, 0, 0, },
{ 8, 2, 17, 4, 27, 16, 32, 4, 51, 2, 56, 32, 66, 8, 75, 32,
81, 2, 90, 16, 96, 8, 115, 8, 122, 2, 0, 0, 0, 0, },
{ 2, 16, 18, 1, 25, 16, 34, 2, 40, 2, 49, 4, 59, 16, 66, 4,
73, 32, 82, 32, 89, 8, 98, 8, 107, 32, 113, 2, 123, 4, },
{ 7, 1, 13, 8, 28, 1, 38, 4, 44, 8, 61, 16, 71, 32, 77, 1,
86, 8, 100, 2, 111, 4, 117, 32, 124, 16, 0, 0, 0, 0, },
{ 12, 8, 29, 16, 36, 4, 47, 16, 52, 32, 62, 32, 68, 2, 79, 4,
85, 32, 95, 1, 102, 1, 111, 2, 117, 2, 126, 4, 0, 0, },
{ 5, 1, 15, 16, 20, 32, 30, 32, 37, 4, 46, 2, 52, 16, 61, 8,
70, 1, 79, 2, 85, 2, 103, 8, 110, 16, 119, 32, 124, 4, },
{ 0, 16, 9, 2, 18, 16, 24, 8, 43, 8, 59, 1, 65, 4, 75, 16,
80, 4, 99, 2, 104, 32, 113, 1, 123, 32, 0, 0, 0, 0, },
{ 10, 32, 17, 8, 26, 8, 35, 32, 41, 2, 50, 16, 56, 8, 66, 1,
73, 16, 82, 2, 88, 2, 97, 4, 107, 16, 112, 4, 121, 32, },
{ 0, 2, 11, 1, 16, 1, 26, 4, 33, 32, 42, 32, 49, 8, 58, 8,
65, 1, 72, 16, 83, 4, 98, 1, 105, 16, 114, 2, 0, 0, },
{ 8, 8, 27, 8, 43, 1, 48, 1, 58, 4, 64, 4, 83, 2, 88, 32,
97, 1, 104, 16, 115, 4, 122, 16, 0, 0, 0, 0, 0, 0, },
{ 5, 8, 14, 1, 23, 2, 29, 2, 47, 8, 54, 16, 63, 32, 68, 4,
79, 16, 84, 32, 94, 32, 101, 4, 110, 2, 116, 16, 127, 1, },
{ 4, 8, 15, 8, 22, 16, 31, 32, 37, 1, 46, 8, 60, 2, 69, 4,
78, 2, 84, 16, 93, 8, 108, 1, 118, 4, 0, 0, 0, 0, },
{ 7, 16, 14, 8, 28, 2, 39, 4, 45, 32, 55, 1, 62, 1, 76, 1,
86, 4, 92, 8, 109, 16, 116, 4, 125, 1, 0, 0, 0, 0, },
{ 1, 2, 11, 4, 26, 1, 33, 16, 42, 2, 48, 2, 57, 4, 64, 1,
74, 4, 81, 32, 90, 32, 97, 8, 106, 8, 115, 32, 120, 16, },
{ 2, 32, 11, 2, 16, 32, 25, 1, 32, 16, 43, 4, 58, 1, 75, 8,
91, 1, 96, 1, 106, 4, 113, 32, 0, 0, 0, 0, 0, 0, },
{ 3, 1, 9, 4, 19, 16, 24, 4, 43, 2, 48, 32, 57, 1, 67, 32,
73, 2, 82, 16, 88, 8, 107, 8, 120, 2, 0, 0, 0, 0, },
{ 0, 8, 10, 1, 17, 16, 26, 2, 32, 2, 41, 4, 51, 16, 56, 4,
65, 32, 74, 32, 81, 8, 90, 8, 99, 32, 105, 2, 114, 16, },
{ 6, 1, 20, 1, 30, 4, 36, 8, 53, 16, 60, 4, 69, 1, 78, 8,
92, 2, 103, 4, 109, 32, 119, 1, 125, 8, 0, 0, 0, 0, },
{ 7, 8, 21, 16, 28, 4, 39, 16, 44, 32, 54, 32, 61, 4, 71, 4,
77, 32, 87, 1, 94, 1, 103, 2, 109, 2, 124, 8, 0, 0, },
{ 6, 8, 12, 32, 22, 32, 29, 4, 38, 2, 44, 16, 53, 8, 71, 2,
77, 2, 95, 8, 102, 16, 111, 32, 117, 1, 127, 16, 0, 0, }
};
void
key_setup(char key[DESKEYLEN], char *ek)
{
int i, j, k, mask;
uchar (*x)[2];
memset(ek, 0, 128);
x = keyexpand[0];
for(i = 0; i < 7; i++){
k = key[i];
for(mask = 0x80; mask; mask >>= 1){
if(k & mask)
for(j = 0; j < 15; j++)
ek[x[j][0]] |= x[j][1];
x += 15;
}
}
}

47
dirmodeconv.c Normal file
View File

@ -0,0 +1,47 @@
#include <plan9.h>
#include <fcall.h>
static char *modes[] =
{
"---",
"--x",
"-w-",
"-wx",
"r--",
"r-x",
"rw-",
"rwx",
};
static void
rwx(long m, char *s)
{
strncpy(s, modes[m], 3);
}
int
dirmodeconv(va_list *arg, Fconv *f)
{
static char buf[16];
ulong m;
m = va_arg(*arg, ulong);
if(m & DMDIR)
buf[0]='d';
else if(m & DMAPPEND)
buf[0]='a';
else
buf[0]='-';
if(m & DMEXCL)
buf[1]='l';
else
buf[1]='-';
rwx((m>>6)&7, buf+2);
rwx((m>>3)&7, buf+5);
rwx((m>>0)&7, buf+8);
buf[11] = 0;
strconv(buf, f);
return 0;
}

610
doprint.c Normal file
View File

@ -0,0 +1,610 @@
#include <plan9.h>
#define lock(x)
#define unlock(x)
enum
{
IDIGIT = 40,
MAXCONV = 40,
FDIGIT = 30,
FDEFLT = 6,
NONE = -1000,
MAXFMT = 512,
FPLUS = 1<<0,
FMINUS = 1<<1,
FSHARP = 1<<2,
FLONG = 1<<3,
FUNSIGN = 1<<5,
FVLONG = 1<<6,
FPOINTER= 1<<7
};
int printcol;
static struct
{
/* Lock; */
int convcount;
char index[MAXFMT];
int (*conv[MAXCONV])(va_list*, Fconv*);
} fmtalloc;
static int noconv(va_list*, Fconv*);
static int flags(va_list*, Fconv*);
static int cconv(va_list*, Fconv*);
static int sconv(va_list*, Fconv*);
static int percent(va_list*, Fconv*);
static int column(va_list*, Fconv*);
extern int numbconv(va_list*, Fconv*);
static void
initfmt(void)
{
int cc;
lock(&fmtalloc);
if(fmtalloc.convcount <= 0) {
cc = 0;
fmtalloc.conv[cc] = noconv;
cc++;
fmtalloc.conv[cc] = flags;
fmtalloc.index['+'] = cc;
fmtalloc.index['-'] = cc;
fmtalloc.index['#'] = cc;
fmtalloc.index['l'] = cc;
fmtalloc.index['u'] = cc;
cc++;
fmtalloc.conv[cc] = numbconv;
fmtalloc.index['d'] = cc;
fmtalloc.index['o'] = cc;
fmtalloc.index['x'] = cc;
fmtalloc.index['X'] = cc;
fmtalloc.index['p'] = cc;
cc++;
fmtalloc.conv[cc] = cconv;
fmtalloc.index['c'] = cc;
fmtalloc.index['C'] = cc;
cc++;
fmtalloc.conv[cc] = sconv;
fmtalloc.index['s'] = cc;
fmtalloc.index['S'] = cc;
cc++;
fmtalloc.conv[cc] = percent;
fmtalloc.index['%'] = cc;
cc++;
fmtalloc.conv[cc] = column;
fmtalloc.index['|'] = cc;
cc++;
fmtalloc.convcount = cc;
}
unlock(&fmtalloc);
}
int
fmtinstall(int c, int (*f)(va_list*, Fconv*))
{
if(fmtalloc.convcount <= 0)
initfmt();
lock(&fmtalloc);
if(c < 0 || c >= MAXFMT) {
unlock(&fmtalloc);
return -1;
}
if(fmtalloc.convcount >= MAXCONV) {
unlock(&fmtalloc);
return -1;
}
fmtalloc.conv[fmtalloc.convcount] = f;
fmtalloc.index[c] = fmtalloc.convcount;
fmtalloc.convcount++;
unlock(&fmtalloc);
return 0;
}
static void
pchar(Rune c, Fconv *fp)
{
int n;
n = fp->eout - fp->out;
if(n > 0) {
if(c < Runeself) {
*fp->out++ = c;
return;
}
if(n >= UTFmax || n >= runelen(c)) {
n = runetochar(fp->out, &c);
fp->out += n;
return;
}
fp->eout = fp->out;
}
}
char*
doprint(char *s, char *es, char *fmt, va_list *argp)
{
int n, c;
Rune rune;
Fconv local;
if(fmtalloc.convcount <= 0)
initfmt();
if(s >= es)
return s;
local.out = s;
local.eout = es-1;
loop:
c = *fmt & 0xff;
if(c >= Runeself) {
n = chartorune(&rune, fmt);
fmt += n;
c = rune;
} else
fmt++;
switch(c) {
case 0:
*local.out = 0;
return local.out;
default:
printcol++;
goto common;
case '\n':
printcol = 0;
goto common;
case '\t':
printcol = (printcol+8) & ~7;
goto common;
common:
pchar(c, &local);
goto loop;
case '%':
break;
}
local.f1 = NONE;
local.f2 = NONE;
local.f3 = 0;
/*
* read one of the following
* 1. number, => f1, f2 in order.
* 2. '*' same as number (from args)
* 3. '.' ignored (separates numbers)
* 4. flag => f3
* 5. verb and terminate
*/
l0:
c = *fmt & 0xff;
if(c >= Runeself) {
n = chartorune(&rune, fmt);
fmt += n;
c = rune;
} else
fmt++;
l1:
if(c == 0) {
fmt--;
goto loop;
}
if(c == '.') {
if(local.f1 == NONE)
local.f1 = 0;
local.f2 = 0;
goto l0;
}
if((c >= '1' && c <= '9') ||
(c == '0' && local.f1 != NONE)) { /* '0' is a digit for f2 */
n = 0;
while(c >= '0' && c <= '9') {
n = n*10 + c-'0';
c = *fmt++;
}
if(local.f1 == NONE)
local.f1 = n;
else
local.f2 = n;
goto l1;
}
if(c == '*') {
n = va_arg(*argp, int);
if(local.f1 == NONE)
local.f1 = n;
else
local.f2 = n;
goto l0;
}
n = 0;
if(c >= 0 && c < MAXFMT)
n = fmtalloc.index[c];
local.chr = c;
n = (*fmtalloc.conv[n])(argp, &local);
if(n < 0) {
local.f3 |= -n;
goto l0;
}
goto loop;
}
int
numbconv(va_list *arg, Fconv *fp)
{
char s[IDIGIT];
int i, f, n, b, ucase;
long v;
vlong vl;
SET(v);
SET(vl);
ucase = 0;
b = fp->chr;
switch(fp->chr) {
case 'u':
fp->f3 |= FUNSIGN;
case 'd':
b = 10;
break;
case 'b':
b = 2;
break;
case 'o':
b = 8;
break;
case 'X':
ucase = 1;
case 'x':
b = 16;
break;
case 'p':
fp->f3 |= FPOINTER|FUNSIGN;
b = 16;
break;
}
f = 0;
switch(fp->f3 & (FVLONG|FLONG|FUNSIGN|FPOINTER)) {
case FVLONG|FLONG:
vl = va_arg(*arg, vlong);
break;
case FUNSIGN|FVLONG|FLONG:
vl = va_arg(*arg, uvlong);
break;
case FUNSIGN|FPOINTER:
v = (ulong)va_arg(*arg, void*);
break;
case FLONG:
v = va_arg(*arg, long);
break;
case FUNSIGN|FLONG:
v = va_arg(*arg, ulong);
break;
default:
v = va_arg(*arg, int);
break;
case FUNSIGN:
v = va_arg(*arg, unsigned);
break;
}
if(fp->f3 & FVLONG) {
if(!(fp->f3 & FUNSIGN) && vl < 0) {
vl = -vl;
f = 1;
}
} else {
if(!(fp->f3 & FUNSIGN) && v < 0) {
v = -v;
f = 1;
}
}
s[IDIGIT-1] = 0;
for(i = IDIGIT-2;; i--) {
if(fp->f3 & FVLONG)
n = (uvlong)vl % b;
else
n = (ulong)v % b;
n += '0';
if(n > '9') {
n += 'a' - ('9'+1);
if(ucase)
n += 'A'-'a';
}
s[i] = n;
if(i < 2)
break;
if(fp->f3 & FVLONG)
vl = (uvlong)vl / b;
else
v = (ulong)v / b;
if(fp->f2 != NONE && i >= IDIGIT-fp->f2)
continue;
if(fp->f3 & FVLONG) {
if(vl <= 0)
break;
continue;
}
if(v <= 0)
break;
}
if(fp->f3 & FSHARP) {
if(b == 8 && s[i] != '0')
s[--i] = '0';
if(b == 16) {
if(ucase)
s[--i] = 'X';
else
s[--i] = 'x';
s[--i] = '0';
}
}
if(f)
s[--i] = '-';
else if(fp->f3 & FPLUS)
s[--i] = '+';
fp->f2 = NONE;
strconv(s+i, fp);
return 0;
}
void
Strconv(Rune *s, Fconv *fp)
{
int n, c;
if(fp->f3 & FMINUS)
fp->f1 = -fp->f1;
n = 0;
if(fp->f1 != NONE && fp->f1 >= 0) {
for(; s[n]; n++)
;
while(n < fp->f1) {
pchar(' ', fp);
printcol++;
n++;
}
}
for(;;) {
c = *s++;
if(c == 0)
break;
n++;
if(fp->f2 == NONE || fp->f2 > 0) {
pchar(c, fp);
if(fp->f2 != NONE)
fp->f2--;
switch(c) {
default:
printcol++;
break;
case '\n':
printcol = 0;
break;
case '\t':
printcol = (printcol+8) & ~7;
break;
}
}
}
if(fp->f1 != NONE && fp->f1 < 0) {
fp->f1 = -fp->f1;
while(n < fp->f1) {
pchar(' ', fp);
printcol++;
n++;
}
}
}
void
strconv(char *s, Fconv *fp)
{
int n, c, i;
Rune rune;
if(fp->f3 & FMINUS)
fp->f1 = -fp->f1;
n = 0;
if(fp->f1 != NONE && fp->f1 >= 0) {
n = utflen(s);
while(n < fp->f1) {
pchar(' ', fp);
printcol++;
n++;
}
}
for(;;) {
c = *s & 0xff;
if(c >= Runeself) {
i = chartorune(&rune, s);
s += i;
c = rune;
} else
s++;
if(c == 0)
break;
n++;
if(fp->f2 == NONE || fp->f2 > 0) {
pchar(c, fp);
if(fp->f2 != NONE)
fp->f2--;
switch(c) {
default:
printcol++;
break;
case '\n':
printcol = 0;
break;
case '\t':
printcol = (printcol+8) & ~7;
break;
}
}
}
if(fp->f1 != NONE && fp->f1 < 0) {
fp->f1 = -fp->f1;
while(n < fp->f1) {
pchar(' ', fp);
printcol++;
n++;
}
}
}
static int
noconv(va_list *va, Fconv *fp)
{
char s[10];
USED(va);
s[0] = '*';
s[1] = fp->chr;
s[2] = '*';
s[3] = 0;
fp->f1 = 0;
fp->f2 = NONE;
fp->f3 = 0;
strconv(s, fp);
return 0;
}
static int
cconv(va_list *arg, Fconv *fp)
{
char s[10];
Rune rune;
rune = va_arg(*arg, int);
if(fp->chr == 'c')
rune &= 0xff;
s[runetochar(s, &rune)] = 0;
fp->f2 = NONE;
strconv(s, fp);
return 0;
}
static Rune null[] = { L'<', L'n', L'u', L'l', L'l', L'>', L'\0' };
static int
sconv(va_list *arg, Fconv *fp)
{
char *s;
Rune *r;
if(fp->chr == 's') {
s = va_arg(*arg, char*);
if(s == 0)
s = "<null>";
strconv(s, fp);
} else {
r = va_arg(*arg, Rune*);
if(r == 0)
r = null;
Strconv(r, fp);
}
return 0;
}
static int
percent(va_list *va, Fconv *fp)
{
USED(va);
pchar('%', fp);
printcol++;
return 0;
}
static int
column(va_list *arg, Fconv *fp)
{
int col, pc;
col = va_arg(*arg, int);
while(printcol < col) {
pc = (printcol+8) & ~7;
if(pc <= col) {
pchar('\t', fp);
printcol = pc;
} else {
pchar(' ', fp);
printcol++;
}
}
return 0;
}
static int
flags(va_list *va, Fconv *fp)
{
int f;
USED(va);
f = 0;
switch(fp->chr) {
case '+':
f = FPLUS;
break;
case '-':
f = FMINUS;
break;
case '#':
f = FSHARP;
break;
case 'l':
f = FLONG;
if(fp->f3 & FLONG)
f = FVLONG;
break;
case 'u':
f = FUNSIGN;
break;
}
return -f;
}
/*
* This code is superseded by the more accurate (but more complex)
* algorithm in fltconv.c and dtoa.c. Uncomment this routine to avoid
* using the more complex code.
*
*/

123
fcall.h Normal file
View File

@ -0,0 +1,123 @@
#define VERSION9P "9P2000"
#define MAXWELEM 16
typedef
struct Fcall
{
uchar type;
u32int fid;
ushort tag;
u32int msize; /* Tversion, Rversion */
char *version; /* Tversion, Rversion */
u32int oldtag; /* Tflush */
char *ename; /* Rerror */
Qid qid; /* Rattach, Ropen, Rcreate */
u32int iounit; /* Ropen, Rcreate */
char *uname; /* Tattach, Tauth */
char *aname; /* Tattach, Tauth */
u32int perm; /* Tcreate */
char *name; /* Tcreate */
uchar mode; /* Tcreate, Topen */
u32int newfid; /* Twalk */
ushort nwname; /* Twalk */
char *wname[MAXWELEM]; /* Twalk */
ushort nwqid; /* Rwalk */
Qid wqid[MAXWELEM]; /* Rwalk */
vlong offset; /* Tread, Twrite */
u32int count; /* Tread, Twrite, Rread */
char *data; /* Twrite, Rread */
ushort nstat; /* Twstat, Rstat */
uchar *stat; /* Twstat, Rstat */
u32int afid; /* Tauth, Tattach */
Qid aqid; /* Rauth */
} Fcall;
#define GBIT8(p) ((p)[0])
#define GBIT16(p) ((p)[0]|((p)[1]<<8))
#define GBIT32(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
#define GBIT64(p) ((ulong)((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24)) |\
((vlong)((p)[4]|((p)[5]<<8)|((p)[6]<<16)|((p)[7]<<24)) << 32))
#define PBIT8(p,v) (p)[0]=(v)
#define PBIT16(p,v) (p)[0]=(v);(p)[1]=(v)>>8
#define PBIT32(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
#define PBIT64(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;\
(p)[4]=(v)>>32;(p)[5]=(v)>>40;(p)[6]=(v)>>48;(p)[7]=(v)>>56
#define BIT8SZ 1
#define BIT16SZ 2
#define BIT32SZ 4
#define BIT64SZ 8
#define QIDSZ (BIT8SZ+BIT32SZ+BIT64SZ)
/* STATFIXLEN includes leading 16-bit count */
/* The count, however, excludes itself; total size is BIT16SZ+count */
#define STATFIXLEN (BIT16SZ+QIDSZ+5*BIT16SZ+4*BIT32SZ+1*BIT64SZ) /* amount of fixed length data in a stat buffer */
#define MAXMSG 10000 /* max header sans data */
#define NOTAG ~0U /* Dummy tag */
#define IOHDRSZ 24 /* ample room for Twrite/Rread header (iounit) */
enum
{
Tversion = 100,
Rversion,
Tauth = 102,
Rauth,
Tattach = 104,
Rattach,
Terror = 106, /* illegal */
Rerror,
Tflush = 108,
Rflush,
Twalk = 110,
Rwalk,
Topen = 112,
Ropen,
Tcreate = 114,
Rcreate,
Tread = 116,
Rread,
Twrite = 118,
Rwrite,
Tclunk = 120,
Rclunk,
Tremove = 122,
Rremove,
Tstat = 124,
Rstat,
Twstat = 126,
Rwstat,
Tmax
};
uint convM2S(uchar*, uint, Fcall*);
uint convS2M(Fcall*, uchar*, uint);
int statcheck(uchar *abuf, uint nbuf);
uint convM2D(uchar*, uint, Dir*, char*);
uint convD2M(Dir*, uchar*, uint);
uint sizeD2M(Dir*);
int fcallconv(va_list*, Fconv*);
int dirconv(va_list*, Fconv*);
int dirmodeconv(va_list*, Fconv*);
int read9pmsg(int, void*, uint);
enum {
NOFID = 0xFFFFFFFF,
};

228
fcallconv.c Normal file
View File

@ -0,0 +1,228 @@
#include <plan9.h>
#include <fcall.h>
#include <oldfcall.h>
extern int old9p;
static uint dumpsome(char*, char*, long);
static void fdirconv(char*, Dir*);
static char *qidtype(char*, uchar);
#define QIDFMT "(%.16llux %lud %s)"
int
fcallconv(va_list *arg, Fconv *f1)
{
Fcall *f;
int fid, type, tag, n, i;
char buf[512], tmp[200];
Dir *d;
Qid *q;
f = va_arg(*arg, Fcall*);
type = f->type;
fid = f->fid;
tag = f->tag;
switch(type){
case Tversion: /* 100 */
sprint(buf, "Tversion tag %ud msize %ud version '%s'", tag, f->msize, f->version);
break;
case Rversion:
sprint(buf, "Rversion tag %ud msize %ud version '%s'", tag, f->msize, f->version);
break;
case Tauth: /* 102 */
sprint(buf, "Tauth tag %ud afid %d uname %s aname %s", tag,
f->afid, f->uname, f->aname);
break;
case Rauth:
sprint(buf, "Rauth tag %ud qid " QIDFMT, tag,
f->aqid.path, f->aqid.vers, qidtype(tmp, f->aqid.type));
break;
case Tattach: /* 104 */
sprint(buf, "Tattach tag %ud fid %d afid %d uname %s aname %s", tag,
fid, f->afid, f->uname, f->aname);
break;
case Rattach:
sprint(buf, "Rattach tag %ud qid " QIDFMT, tag,
f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type));
break;
case Rerror: /* 107; 106 (Terror) illegal */
sprint(buf, "Rerror tag %ud ename %s", tag, f->ename);
break;
case Tflush: /* 108 */
sprint(buf, "Tflush tag %ud oldtag %ud", tag, f->oldtag);
break;
case Rflush:
sprint(buf, "Rflush tag %ud", tag);
break;
case Twalk: /* 110 */
n = sprint(buf, "Twalk tag %ud fid %d newfid %d nwname %d ", tag, fid, f->newfid, f->nwname);
for(i=0; i<f->nwname; i++)
n += sprint(buf+n, "%d:%s ", i, f->wname[i]);
break;
case Rwalk:
n = sprint(buf, "Rwalk tag %ud nwqid %ud ", tag, f->nwqid);
for(i=0; i<f->nwqid; i++){
q = &f->wqid[i];
n += sprint(buf+n, "%d:" QIDFMT " ", i,
q->path, q->vers, qidtype(tmp, q->type));
}
break;
case Topen: /* 112 */
sprint(buf, "Topen tag %ud fid %ud mode %d", tag, fid, f->mode);
break;
case Ropen:
sprint(buf, "Ropen tag %ud qid " QIDFMT " iounit %ud ", tag,
f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
break;
case Tcreate: /* 114 */
sprint(buf, "Tcreate tag %ud fid %ud perm %M mode %d", tag, fid, (ulong)f->perm, f->mode);
break;
case Rcreate:
sprint(buf, "Rcreate tag %ud qid " QIDFMT " iounit %ud ", tag,
f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
break;
case Tread: /* 116 */
sprint(buf, "Tread tag %ud fid %d offset %lld count %ud",
tag, fid, f->offset, f->count);
break;
case Rread:
n = sprint(buf, "Rread tag %ud count %ud ", tag, f->count);
dumpsome(buf+n, f->data, f->count);
break;
case Twrite: /* 118 */
n = sprint(buf, "Twrite tag %ud fid %d offset %lld count %ud ",
tag, fid, f->offset, f->count);
dumpsome(buf+n, f->data, f->count);
break;
case Rwrite:
sprint(buf, "Rwrite tag %ud count %ud", tag, f->count);
break;
case Tclunk: /* 120 */
sprint(buf, "Tclunk tag %ud fid %ud", tag, fid);
break;
case Rclunk:
sprint(buf, "Rclunk tag %ud", tag);
break;
case Tremove: /* 122 */
sprint(buf, "Tremove tag %ud fid %ud", tag, fid);
break;
case Rremove:
sprint(buf, "Rremove tag %ud", tag);
break;
case Tstat: /* 124 */
sprint(buf, "Tstat tag %ud fid %ud", tag, fid);
break;
case Rstat:
n = sprint(buf, "Rstat tag %ud ", tag);
if(f->nstat > sizeof tmp)
sprint(buf+n, " stat(%d bytes)", f->nstat);
else{
d = (Dir*)tmp;
(old9p?convM2Dold:convM2D)(f->stat, f->nstat, d, (char*)(d+1));
sprint(buf+n, " stat ");
fdirconv(buf+n+6, d);
}
break;
case Twstat: /* 126 */
n = sprint(buf, "Twstat tag %ud fid %ud", tag, fid);
if(f->nstat > sizeof tmp)
sprint(buf+n, " stat(%d bytes)", f->nstat);
else{
d = (Dir*)tmp;
(old9p?convM2Dold:convM2D)(f->stat, f->nstat, d, (char*)(d+1));
sprint(buf+n, " stat ");
fdirconv(buf+n+6, d);
}
break;
case Rwstat:
sprint(buf, "Rwstat tag %ud", tag);
break;
default:
sprint(buf, "unknown type %d", type);
}
strconv(buf, f1);
return(sizeof(Fcall*));
}
static char*
qidtype(char *s, uchar t)
{
char *p;
p = s;
if(t & QTDIR)
*p++ = 'd';
if(t & QTAPPEND)
*p++ = 'a';
if(t & QTEXCL)
*p++ = 'l';
if(t & QTMOUNT)
*p++ = 'm';
if(t & QTAUTH)
*p++ = 'A';
*p = '\0';
return s;
}
int
dirconv(va_list *arg, Fconv *f)
{
char buf[160];
fdirconv(buf, va_arg(*arg, Dir*));
strconv(buf, f);
return(sizeof(Dir*));
}
static void
fdirconv(char *buf, Dir *d)
{
char tmp[16];
sprint(buf, "'%s' '%s' '%s' '%s' "
"q " QIDFMT " m %#luo "
"at %ld mt %ld l %lld "
"t %d d %d",
d->name, d->uid, d->gid, d->muid,
d->qid.path, d->qid.vers, qidtype(tmp, d->qid.type), d->mode,
d->atime, d->mtime, d->length,
d->type, d->dev);
}
/*
* dump out count (or DUMPL, if count is bigger) bytes from
* buf to ans, as a string if they are all printable,
* else as a series of hex bytes
*/
#define DUMPL 64
static uint
dumpsome(char *ans, char *buf, long count)
{
int i, printable;
char *p;
printable = 1;
if(count > DUMPL)
count = DUMPL;
for(i=0; i<count && printable; i++)
if((buf[i]<32 && buf[i] !='\n' && buf[i] !='\t') || (uchar)buf[i]>127)
printable = 0;
p = ans;
*p++ = '\'';
if(printable){
memmove(p, buf, count);
p += count;
}else{
for(i=0; i<count; i++){
if(i>0 && i%4==0)
*p++ = ' ';
sprint(p, "%2.2ux", (uchar)buf[i]);
p += 2;
}
}
*p++ = '\'';
*p = 0;
return p - ans;
}

63
makefile Normal file
View File

@ -0,0 +1,63 @@
#
# The goal is to keep as much per-system stuff autodetected in plan9.h
# as possible. Still, sometimes you can't help it. Look for your system.
#
# SGI
#
# To correctly handle 64-bit files and offsets, add -64 to CFLAGS and LDFLAGS
# On Irix 5.X, add -DIRIX5X to hack around their own #include problems (see plan9.h).
#
# SunOS
#
# SunOS 5.5.1 does not provide inttypes.h; add -lsunos to CFLAGS and
# change CC and LD to gcc. Add -lsocket, -lnsl to LDTAIL.
# If you need <inttypes.h> copy sun-inttypes.h to inttypes.h.
#
#CC=cc
CFLAGS=-g -I.
LD=cc
LDFLAGS=
LDTAIL=
OFILES=\
authnone.o\
authrhosts.o\
authp9any.o\
convD2M.o\
convM2D.o\
convM2S.o\
convS2M.o\
des.o\
dirmodeconv.o\
doprint.o\
fcallconv.o\
oldfcall.o\
print.o\
random.o\
readn.o\
remotehost.o\
rune.o\
safecpy.o\
strecpy.o\
tokenize.o\
u9fs.o\
utfrune.o
HFILES=\
fcall.h\
plan9.h
u9fs: $(OFILES)
$(LD) $(LDFLAGS) -o u9fs $(OFILES) $(LDTAIL)
%.o: %.c $(HFILES)
$(CC) $(CFLAGS) -c $*.c
clean:
rm -f *.o u9fs
install: u9fs
cp u9fs ../../bin
.PHONY: clean install

521
oldfcall.c Normal file
View File

@ -0,0 +1,521 @@
#include <plan9.h>
#include <fcall.h>
#include <oldfcall.h>
/*
* routines to package the old protocol in the new structures.
*/
#define SHORT(x) p[0]=f->x; p[1]=f->x>>8; p += 2
#define LONG(x) p[0]=f->x; p[1]=f->x>>8; p[2]=f->x>>16; p[3]=f->x>>24; p += 4
#define VLONG(x) p[0]=f->x; p[1]=f->x>>8;\
p[2]=f->x>>16; p[3]=f->x>>24;\
p[4]=f->x>>32; p[5]=f->x>>40;\
p[6]=f->x>>48; p[7]=f->x>>56;\
p += 8
#define STRING(x,n) strecpy((char*)p, (char*)p+n, f->x); p += n;
#define FIXQID(q) q.path ^= (q.path>>33); q.path &= 0x7FFFFFFF; q.path |= (q.type&0x80)<<24
uint
oldhdrsize(uchar type)
{
switch(type){
default:
return 0;
case oldTnop:
return 3;
case oldTflush:
return 3+2;
case oldTclone:
return 3+2+2;
case oldTwalk:
return 3+2+28;
case oldTopen:
return 3+2+1;
case oldTcreate:
return 3+2+28+4+1;
case oldTread:
return 3+2+8+2;
case oldTwrite:
return 3+2+8+2+1;
case oldTclunk:
return 3+2;
case oldTremove:
return 3+2;
case oldTstat:
return 3+2;
case oldTwstat:
return 3+2+116;
case oldTsession:
return 3+8;
case oldTattach:
return 3+2+28+28+72+13;
}
}
uint
iosize(uchar *p)
{
if(p[0] != oldTwrite)
return 0;
return p[3+2+8] | (p[3+2+8+1]<<8);
}
uint
sizeS2M(Fcall *f)
{
switch(f->type)
{
default:
abort();
return 0;
/* no T messages */
/*
*/
case Rversion:
return 1+2;
/*
case Rsession:
return 1+2+8+28+48;
*/
case Rattach:
return 1+2+2+4+4+13;
case Rerror:
return 1+2+64;
case Rflush:
if(f->tag&0x8000)
return 1+2+8+28+48; /* session */
return 1+2;
/* assumes we don't ever see Tclwalk requests ... */
case Rwalk:
if(f->nwqid == 0)
return 1+2+2;
else
return 1+2+2+4+4;
case Ropen:
return 1+2+2+4+4;
case Rcreate:
return 1+2+2+4+4;
case Rread:
return 1+2+2+2+1+f->count;
case Rwrite:
return 1+2+2+2;
case Rclunk:
return 1+2+2;
case Rremove:
return 1+2+2;
case Rstat:
return 1+2+2+116;
case Rwstat:
return 1+2+2;
}
}
uint
convS2Mold(Fcall *f, uchar *ap, uint nap)
{
uchar *p;
if(nap < sizeS2M(f))
return 0;
p = ap;
switch(f->type)
{
default:
abort();
return 0;
/* no T messages */
/*
*/
case Rversion:
*p++ = oldRnop;
SHORT(tag);
break;
/*
case Rsession:
*p++ = oldRsession;
SHORT(tag);
if(f->nchal > 8)
f->nchal = 8;
memmove(p, f->chal, f->nchal);
p += f->nchal;
if(f->nchal < 8){
memset(p, 0, 8 - f->nchal);
p += 8 - f->nchal;
}
STRING(authid, 28);
STRING(authdom, 48);
break;
*/
case Rattach:
*p++ = oldRattach;
SHORT(tag);
SHORT(fid);
FIXQID(f->qid);
LONG(qid.path);
LONG(qid.vers);
memset(p, 0, 13);
p += 13;
break;
case Rerror:
*p++ = oldRerror;
SHORT(tag);
STRING(ename, 64);
break;
case Rflush:
if(f->tag&0x8000){
*p++ = oldRsession;
f->tag &= ~0x8000;
SHORT(tag);
memset(p, 0, 8+28+48);
p += 8+28+48;
}else{
*p++ = oldRflush;
SHORT(tag);
}
break;
/* assumes we don't ever see Tclwalk requests ... */
case Rwalk:
if(f->nwqid == 0){ /* successful clone */
*p++ = oldRclone;
SHORT(tag);
SHORT(fid);
}else{ /* successful 1-element walk */
*p++ = oldRwalk;
SHORT(tag);
SHORT(fid);
FIXQID(f->wqid[0]);
LONG(wqid[0].path);
LONG(wqid[0].vers);
}
break;
case Ropen:
*p++ = oldRopen;
SHORT(tag);
SHORT(fid);
FIXQID(f->qid);
LONG(qid.path);
LONG(qid.vers);
break;
case Rcreate:
*p++ = oldRcreate;
SHORT(tag);
SHORT(fid);
FIXQID(f->qid);
LONG(qid.path);
LONG(qid.vers);
break;
case Rread:
*p++ = oldRread;
SHORT(tag);
SHORT(fid);
SHORT(count);
p++; /* pad(1) */
memmove(p, f->data, f->count);
p += f->count;
break;
case Rwrite:
*p++ = oldRwrite;
SHORT(tag);
SHORT(fid);
SHORT(count);
break;
case Rclunk:
*p++ = oldRclunk;
SHORT(tag);
SHORT(fid);
break;
case Rremove:
*p++ = oldRremove;
SHORT(tag);
SHORT(fid);
break;
case Rstat:
*p++ = oldRstat;
SHORT(tag);
SHORT(fid);
memmove(p, f->stat, 116);
p += 116;
break;
case Rwstat:
*p++ = oldRwstat;
SHORT(tag);
SHORT(fid);
break;
}
return p - ap;
}
uint
sizeD2Mold(Dir *d)
{
return 116;
}
uint
convD2Mold(Dir *f, uchar *ap, uint nap)
{
uchar *p;
if(nap < 116)
return 0;
p = ap;
STRING(name, 28);
STRING(uid, 28);
STRING(gid, 28);
FIXQID(f->qid);
LONG(qid.path);
LONG(qid.vers);
LONG(mode);
LONG(atime);
LONG(mtime);
VLONG(length);
SHORT(type);
SHORT(dev);
return p - ap;
}
#undef SHORT
#undef LONG
#undef VLONG
#undef STRING
#define CHAR(x) f->x = *p++
#define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2
#define LONG(x) f->x = (p[0] | (p[1]<<8) |\
(p[2]<<16) | (p[3]<<24)); p += 4
#define VLONG(x) f->x = (ulong)(p[0] | (p[1]<<8) |\
(p[2]<<16) | (p[3]<<24)) |\
((vlong)(p[4] | (p[5]<<8) |\
(p[6]<<16) | (p[7]<<24)) << 32); p += 8
#define STRING(x,n) f->x = (char*)p; p += n
uint
convM2Sold(uchar *ap, uint nap, Fcall *f)
{
uchar *p, *q, *ep;
p = ap;
ep = p + nap;
if(p+3 > ep)
return 0;
switch(*p++){
case oldTnop:
f->type = Tversion;
SHORT(tag);
f->msize = 0;
f->version = "9P1";
break;
case oldTflush:
f->type = Tflush;
SHORT(tag);
if(p+2 > ep)
return 0;
SHORT(oldtag);
break;
case oldTclone:
f->type = Twalk;
SHORT(tag);
if(p+2+2 > ep)
return 0;
SHORT(fid);
SHORT(newfid);
f->nwname = 0;
break;
case oldTwalk:
f->type = Twalk;
SHORT(tag);
if(p+2+28 > ep)
return 0;
SHORT(fid);
f->newfid = f->fid;
f->nwname = 1;
f->wname[0] = (char*)p;
p += 28;
break;
case oldTopen:
f->type = Topen;
SHORT(tag);
if(p+2+1 > ep)
return 0;
SHORT(fid);
CHAR(mode);
break;
case oldTcreate:
f->type = Tcreate;
SHORT(tag);
if(p+2+28+4+1 > ep)
return 0;
SHORT(fid);
f->name = (char*)p;
p += 28;
LONG(perm);
CHAR(mode);
break;
case oldTread:
f->type = Tread;
SHORT(tag);
if(p+2+8+2 > ep)
return 0;
SHORT(fid);
VLONG(offset);
SHORT(count);
break;
case oldTwrite:
f->type = Twrite;
SHORT(tag);
if(p+2+8+2+1 > ep)
return 0;
SHORT(fid);
VLONG(offset);
SHORT(count);
p++; /* pad(1) */
if(p+f->count > ep)
return 0;
f->data = (char*)p;
p += f->count;
break;
case oldTclunk:
f->type = Tclunk;
SHORT(tag);
if(p+2 > ep)
return 0;
SHORT(fid);
break;
case oldTremove:
f->type = Tremove;
SHORT(tag);
if(p+2 > ep)
return 0;
SHORT(fid);
break;
case oldTstat:
f->type = Tstat;
f->nstat = 116;
SHORT(tag);
if(p+2 > ep)
return 0;
SHORT(fid);
break;
case oldTwstat:
f->type = Twstat;
SHORT(tag);
if(p+2+116 > ep)
return 0;
SHORT(fid);
f->stat = p;
q = p+28*3+5*4;
memset(q, 0xFF, 8); /* clear length to ``don't care'' */
p += 116;
break;
/*
case oldTsession:
f->type = Tsession;
SHORT(tag);
if(p+8 > ep)
return 0;
f->chal = p;
p += 8;
f->nchal = 8;
break;
*/
case oldTsession:
f->type = Tflush;
SHORT(tag);
f->tag |= 0x8000;
f->oldtag = f->tag;
p += 8;
break;
case oldTattach:
f->type = Tattach;
SHORT(tag);
if(p+2+28+28+72+13 > ep)
return 0;
SHORT(fid);
STRING(uname, 28);
STRING(aname, 28);
p += 72+13;
f->afid = NOFID;
break;
default:
return 0;
}
return p-ap;
}
uint
convM2Dold(uchar *ap, uint nap, Dir *f, char *strs)
{
uchar *p;
USED(strs);
if(nap < 116)
return 0;
p = (uchar*)ap;
STRING(name, 28);
STRING(uid, 28);
STRING(gid, 28);
LONG(qid.path);
LONG(qid.vers);
LONG(mode);
LONG(atime);
LONG(mtime);
VLONG(length);
SHORT(type);
SHORT(dev);
f->qid.type = (f->mode>>24)&0xF0;
return p - (uchar*)ap;
}

50
oldfcall.h Normal file
View File

@ -0,0 +1,50 @@
uint convM2Dold(uchar*, uint, Dir*, char*);
uint convD2Mold(Dir*, uchar*, uint);
uint sizeD2Mold(Dir*);
uint convM2Sold(uchar*, uint, Fcall*);
uint convS2Mold(Fcall*, uchar*, uint);
uint oldhdrsize(uchar);
uint iosize(uchar*);
enum
{
oldTnop = 50,
oldRnop,
oldTosession = 52, /* illegal */
oldRosession, /* illegal */
oldTerror = 54, /* illegal */
oldRerror,
oldTflush = 56,
oldRflush,
oldToattach = 58, /* illegal */
oldRoattach, /* illegal */
oldTclone = 60,
oldRclone,
oldTwalk = 62,
oldRwalk,
oldTopen = 64,
oldRopen,
oldTcreate = 66,
oldRcreate,
oldTread = 68,
oldRread,
oldTwrite = 70,
oldRwrite,
oldTclunk = 72,
oldRclunk,
oldTremove = 74,
oldRremove,
oldTstat = 76,
oldRstat,
oldTwstat = 78,
oldRwstat,
oldTclwalk = 80,
oldRclwalk,
oldTauth = 82, /* illegal */
oldRauth, /* illegal */
oldTsession = 84,
oldRsession,
oldTattach = 86,
oldRattach,
oldTmax
};

198
plan9.h Normal file
View File

@ -0,0 +1,198 @@
/* magic to get SUSV2 standard, including pread, pwrite*/
#define _XOPEN_SOURCE 500
/* magic to get 64-bit pread/pwrite */
#define _LARGEFILE64_SOURCE
/* magic to get 64-bit stat on Linux, maybe others */
#define _FILE_OFFSET_BITS 64
#ifdef sgi
#define _BSD_TYPES 1 /* for struct timeval */
#include <sys/select.h>
#define _BSD_SOURCE 1 /* for ruserok */
/*
* SGI IRIX 5.x doesn't allow inclusion of both inttypes.h and
* sys/types.h. These definitions are the ones we need from
* inttypes.h that aren't in sys/types.h.
*
* Unlike most of our #ifdef's, IRIX5X must be set in the makefile.
*/
#ifdef IRIX5X
#define __inttypes_INCLUDED
typedef unsigned int uint32_t;
typedef signed long long int int64_t;
typedef unsigned long long int uint64_t;
#endif /* IRIX5X */
#endif /* sgi */
#ifdef sun /* sparc and __svr4__ are also defined on the offending machine */
#define __EXTENSIONS__ 1 /* for struct timeval */
#endif
#include <inttypes.h> /* for int64_t et al. */
#include <stdarg.h> /* for va_list, vararg macros */
#ifndef va_copy
#ifdef __va_copy
#define va_copy __va_copy
#else
#define va_copy(d, s) memmove(&(d), &(s), sizeof(va_list))
#endif /* __va_copy */
#endif /* va_copy */
#include <sys/types.h>
#include <string.h> /* for memmove */
#include <unistd.h> /* for write */
#define ulong p9ulong /* because sys/types.h has some of these sometimes */
#define ushort p9ushort
#define uchar p9uchar
#define uint p9uint
#define vlong p9vlong
#define uvlong p9uvlong
#define u32int p9u32int
typedef unsigned char uchar;
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef unsigned int uint;
typedef int64_t vlong;
typedef uint64_t uvlong;
typedef uint32_t u32int;
typedef uint64_t u64int;
typedef ushort Rune;
#define nil ((void*)0)
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
#ifndef offsetof
#define offsetof(s, m) (ulong)(&(((s*)0)->m))
#endif
#define assert(x) if(x);else _assert("x")
extern char *argv0;
#define ARGBEGIN for((void)(argv0||(argv0=*argv)),argv++,argc--;\
argv[0] && argv[0][0]=='-' && argv[0][1];\
argc--, argv++) {\
char *_args, *_argt;\
Rune _argc;\
_args = &argv[0][1];\
if(_args[0]=='-' && _args[1]==0){\
argc--; argv++; break;\
}\
_argc = 0;\
while(*_args && (_args += chartorune(&_argc, _args)))\
switch(_argc)
#define ARGEND SET(_argt);USED(_argt);USED(_argc);USED(_args);}\
USED(argv);USED(argc);
#define ARGF() (_argt=_args, _args="",\
(*_argt? _argt: argv[1]? (argc--, *++argv): 0))
#define EARGF(x) (_argt=_args, _args="",\
(*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
#define ARGC() _argc
#define SET(x) (x) = 0
#define USED(x) (void)(x)
enum
{
UTFmax = 3, /* maximum bytes per rune */
Runesync = 0x80, /* cannot represent part of a UTF sequence (<) */
Runeself = 0x80, /* rune and UTF sequences are the same (<) */
Runeerror = 0x80 /* decoding error in UTF */
};
extern int runetochar(char*, Rune*);
extern int chartorune(Rune*, char*);
extern int runelen(long);
extern int utflen(char*);
extern char* strecpy(char*, char*, char*);
extern int tokenize(char*, char**, int);
extern int getfields(char*, char**, int, int, char*);
/*
* print routines
*/
typedef struct Fconv Fconv;
struct Fconv
{
char* out; /* pointer to next output */
char* eout; /* pointer to end */
int f1;
int f2;
int f3;
int chr;
};
extern char* doprint(char*, char*, char*, va_list *argp);
extern int print(char*, ...);
extern char* seprint(char*, char*, char*, ...);
extern int snprint(char*, int, char*, ...);
extern int sprint(char*, char*, ...);
extern int fprint(int, char*, ...);
extern int fmtinstall(int, int (*)(va_list*, Fconv*));
extern int numbconv(va_list*, Fconv*);
extern void strconv(char*, Fconv*);
extern int fltconv(va_list*, Fconv*);
#define OREAD 0 /* open for read */
#define OWRITE 1 /* write */
#define ORDWR 2 /* read and write */
#define OEXEC 3 /* execute, == read but check execute permission */
#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
#define OCEXEC 32 /* or'ed in, close on exec */
#define ORCLOSE 64 /* or'ed in, remove on close */
#define OEXCL 0x1000 /* or'ed in, exclusive use */
/* bits in Qid.type */
#define QTDIR 0x80 /* type bit for directories */
#define QTAPPEND 0x40 /* type bit for append only files */
#define QTEXCL 0x20 /* type bit for exclusive use files */
#define QTMOUNT 0x10 /* type bit for mounted channel */
#define QTAUTH 0x08
#define QTFILE 0x00 /* plain file */
/* bits in Dir.mode */
#define DMDIR 0x80000000 /* mode bit for directories */
#define DMAPPEND 0x40000000 /* mode bit for append only files */
#define DMEXCL 0x20000000 /* mode bit for exclusive use files */
#define DMMOUNT 0x10000000 /* mode bit for mounted channel */
#define DMREAD 0x4 /* mode bit for read permission */
#define DMWRITE 0x2 /* mode bit for write permission */
#define DMEXEC 0x1 /* mode bit for execute permission */
typedef
struct Qid
{
vlong path;
ulong vers;
uchar type;
} Qid;
typedef
struct Dir {
/* system-modified data */
ushort type; /* server type */
uint dev; /* server subtype */
/* file data */
Qid qid; /* unique id from server */
ulong mode; /* permissions */
ulong atime; /* last read time */
ulong mtime; /* last write time */
vlong length; /* file length: see <u.h> */
char *name; /* last element of path */
char *uid; /* owner name */
char *gid; /* group name */
char *muid; /* last modifier name */
} Dir;
long readn(int, void*, long);
void remotehost(char*, int);
enum {
NAMELEN = 28,
ERRLEN = 64
};
/* DES */
#define DESKEYLEN 7
void key_setup(char key[DESKEYLEN], char expandedkey[128]);
void block_cipher(char expandedkey[128], char buf[8], int decrypting);

87
print.c Normal file
View File

@ -0,0 +1,87 @@
#include <plan9.h>
#define SIZE 4096
extern int printcol;
int
print(char *fmt, ...)
{
char buf[SIZE], *out;
va_list arg, temp;
int n;
va_start(arg, fmt);
va_copy(temp, arg);
out = doprint(buf, buf+SIZE, fmt, &temp);
va_end(temp);
va_end(arg);
n = write(1, buf, (long)(out-buf));
return n;
}
int
fprint(int f, char *fmt, ...)
{
char buf[SIZE], *out;
va_list arg, temp;
int n;
va_start(arg, fmt);
va_copy(temp, arg);
out = doprint(buf, buf+SIZE, fmt, &temp);
va_end(temp);
va_end(arg);
n = write(f, buf, (long)(out-buf));
return n;
}
int
sprint(char *buf, char *fmt, ...)
{
char *out;
va_list arg, temp;
int scol;
scol = printcol;
va_start(arg, fmt);
va_copy(temp, arg);
out = doprint(buf, buf+SIZE, fmt, &temp);
va_end(temp);
va_end(arg);
printcol = scol;
return out-buf;
}
int
snprint(char *buf, int len, char *fmt, ...)
{
char *out;
va_list arg, temp;
int scol;
scol = printcol;
va_start(arg, fmt);
va_copy(temp, arg);
out = doprint(buf, buf+len, fmt, &temp);
va_end(temp);
va_end(arg);
printcol = scol;
return out-buf;
}
char*
seprint(char *buf, char *e, char *fmt, ...)
{
char *out;
va_list arg, temp;
int scol;
scol = printcol;
va_start(arg, fmt);
va_copy(temp, arg);
out = doprint(buf, e, fmt, &temp);
va_end(temp);
va_end(arg);
printcol = scol;
return out;
}

58
random.c Normal file
View File

@ -0,0 +1,58 @@
#include <plan9.h>
#include <fcall.h>
#include <u9fs.h>
#include <stdlib.h>
#include <sys/time.h>
#include <fcntl.h>
static long
getseed(void)
{
struct timeval tv;
long seed;
int fd, len;
len = 0;
fd = open("/dev/urandom", O_RDONLY);
if(fd > 0){
len = readn(fd, &seed, sizeof(seed));
close(fd);
}
if(len != sizeof(seed)){
gettimeofday(&tv, nil);
seed = tv.tv_sec ^ tv.tv_usec ^ (getpid()<<8);
}
return seed;
}
static int seeded;
void
randombytes(uchar *r, uint nr)
{
int i;
ulong l;
if(!seeded){
seeded=1;
srand48(getseed());
}
for(i=0; i+4<=nr; i+=4,r+=4){
l = (ulong)mrand48();
r[0] = l;
r[1] = l>>8;
r[2] = l>>16;
r[3] = l>>24;
}
if(i<nr){
l = (ulong)mrand48();
switch(nr-i){
case 3:
r[2] = l>>16;
case 2:
r[1] = l>>8;
case 1:
r[0] = l;
}
}
}

21
readn.c Normal file
View File

@ -0,0 +1,21 @@
#include <plan9.h>
long
readn(int f, void *av, long n)
{
char *a;
long m, t;
a = av;
t = 0;
while(t < n){
m = read(f, a+t, n-t);
if(m <= 0){
if(t == 0)
return m;
break;
}
t += m;
}
return t;
}

32
remotehost.c Normal file
View File

@ -0,0 +1,32 @@
#include <sys/types.h>
#include <sys/socket.h> /* various networking crud */
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <netdb.h>
#include <plan9.h>
void
getremotehostname(char *name, int nname)
{
struct sockaddr_in sock;
struct hostent *hp;
uint len;
int on;
strecpy(name, name+nname, "unknown");
len = sizeof sock;
if(getpeername(0, (struct sockaddr*)&sock, (void*)&len) < 0)
return;
hp = gethostbyaddr((char *)&sock.sin_addr, sizeof (struct in_addr),
sock.sin_family);
if(hp == 0)
return;
strecpy(name, name+nname, hp->h_name);
on = 1;
setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char*)&on, sizeof(on));
on = 1;
setsockopt(0, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
}

148
rune.c Normal file
View File

@ -0,0 +1,148 @@
#include <plan9.h>
char *argv0;
enum
{
Bit1 = 7,
Bitx = 6,
Bit2 = 5,
Bit3 = 4,
Bit4 = 3,
T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */
Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */
T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */
T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */
T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */
Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */
Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */
Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */
Maskx = (1<<Bitx)-1, /* 0011 1111 */
Testx = Maskx ^ 0xFF, /* 1100 0000 */
Bad = Runeerror
};
int
chartorune(Rune *rune, char *str)
{
int c, c1, c2;
long l;
/*
* one character sequence
* 00000-0007F => T1
*/
c = *(uchar*)str;
if(c < Tx) {
*rune = c;
return 1;
}
/*
* two character sequence
* 0080-07FF => T2 Tx
*/
c1 = *(uchar*)(str+1) ^ Tx;
if(c1 & Testx)
goto bad;
if(c < T3) {
if(c < T2)
goto bad;
l = ((c << Bitx) | c1) & Rune2;
if(l <= Rune1)
goto bad;
*rune = l;
return 2;
}
/*
* three character sequence
* 0800-FFFF => T3 Tx Tx
*/
c2 = *(uchar*)(str+2) ^ Tx;
if(c2 & Testx)
goto bad;
if(c < T4) {
l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
if(l <= Rune2)
goto bad;
*rune = l;
return 3;
}
/*
* bad decoding
*/
bad:
*rune = Bad;
return 1;
}
int
runetochar(char *str, Rune *rune)
{
long c;
/*
* one character sequence
* 00000-0007F => 00-7F
*/
c = *rune;
if(c <= Rune1) {
str[0] = c;
return 1;
}
/*
* two character sequence
* 0080-07FF => T2 Tx
*/
if(c <= Rune2) {
str[0] = T2 | (c >> 1*Bitx);
str[1] = Tx | (c & Maskx);
return 2;
}
/*
* three character sequence
* 0800-FFFF => T3 Tx Tx
*/
str[0] = T3 | (c >> 2*Bitx);
str[1] = Tx | ((c >> 1*Bitx) & Maskx);
str[2] = Tx | (c & Maskx);
return 3;
}
int
runelen(long c)
{
Rune rune;
char str[10];
rune = c;
return runetochar(str, &rune);
}
int
utflen(char *s)
{
int c;
long n;
Rune rune;
n = 0;
for(;;) {
c = *(uchar*)s;
if(c < Runeself) {
if(c == 0)
return n;
s++;
} else
s += chartorune(&rune, s);
n++;
}
return 0;
}

12
safecpy.c Normal file
View File

@ -0,0 +1,12 @@
#include <stdio.h>
void
safecpy(char *to, char *from, int tolen)
{
int fromlen;
memset(to, 0, tolen);
fromlen = from ? strlen(from) : 0;
if (fromlen > tolen)
fromlen = tolen;
memcpy(to, from, fromlen);
}

14
strecpy.c Normal file
View File

@ -0,0 +1,14 @@
#include <plan9.h>
char*
strecpy(char *to, char *e, char *from)
{
if(to >= e)
return to;
to = memccpy(to, from, '\0', e - to);
if(to == nil){
to = e - 1;
*to = '\0';
}
return to;
}

16
sun-inttypes.h Normal file
View File

@ -0,0 +1,16 @@
/* inttypes.h for SunOS cuff.link.cs.cmu.edu 5.5.1 Generic_103640-29 sun4u sparc SUNW,Ultra-Enterprise */
#ifndef INTTYPES_H
#define INTTYPES_H
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef long int intptr_t;
typedef unsigned long int uintptr_t;
#endif

42
tokenize.c Normal file
View File

@ -0,0 +1,42 @@
#include <plan9.h>
int
getfields(char *str, char **args, int max, int mflag, char *set)
{
Rune r;
int nr, intok, narg;
if(max <= 0)
return 0;
narg = 0;
args[narg] = str;
if(!mflag)
narg++;
intok = 0;
for(;; str += nr) {
nr = chartorune(&r, str);
if(r == 0)
break;
if(utfrune(set, r)) {
if(narg >= max)
break;
*str = 0;
intok = 0;
args[narg] = str + nr;
if(!mflag)
narg++;
} else {
if(!intok && mflag)
narg++;
intok = 1;
}
}
return narg;
}
int
tokenize(char *str, char **args, int max)
{
return getfields(str, args, max, 1, " \t\n\r");
}

1765
u9fs.c Normal file

File diff suppressed because it is too large Load Diff

30
u9fs.h Normal file
View File

@ -0,0 +1,30 @@
typedef struct Auth Auth;
struct Auth {
char *name;
char* (*auth)(Fcall*, Fcall*);
char* (*attach)(Fcall*, Fcall*);
void (*init)(void);
char* (*read)(Fcall*, Fcall*);
char* (*write)(Fcall*, Fcall*);
char* (*clunk)(Fcall*, Fcall*);
};
extern char remotehostname[];
extern char Eauth[];
extern char *autharg;
extern Auth authp9any;
extern Auth authrhosts;
extern Auth authnone;
extern ulong truerand(void);
extern void randombytes(uchar*, uint);
extern ulong msize;
typedef struct Fid Fid;
Fid *newauthfid(int fid, void *magic, char **ep);
Fid *oldauthfid(int fid, void **magic, char **ep);
void safecpy(char *to, char *from, int len);

7
u9fsauth.h Normal file
View File

@ -0,0 +1,7 @@
typedef struct Auth Auth;
struct Auth {
char *name;
char *(*session)(Fcall*, Fcall*);
char *(*attach)(Fcall*, Fcall*);
};

29
utfrune.c Normal file
View File

@ -0,0 +1,29 @@
#include <plan9.h>
char*
utfrune(char *s, long c)
{
long c1;
Rune r;
int n;
if(c < Runesync) /* not part of utf sequence */
return strchr(s, c);
for(;;) {
c1 = *(uchar*)s;
if(c1 < Runeself) { /* one byte rune */
if(c1 == 0)
return 0;
if(c1 == c)
return s;
s++;
continue;
}
n = chartorune(&r, s);
if(r == c)
return s;
s += n;
}
return 0;
}