From mboxrd@z Thu Jan 1 00:00:00 1970 Message-ID: <01b44d51cc3bf724b4857f2e167b3825@plan9.bell-labs.com> From: "Russ Cox" To: 9fans@cse.psu.edu Subject: Re: [9fans] fidtab revisited In-Reply-To: <20030217073038.BCFD19653.mta2-rme.xtra.co.nz@[210.54.206.123]> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Date: Mon, 17 Feb 2003 09:32:49 -0500 Topicbox-Message-UUID: 64dfd8d2-eacb-11e9-9e20-41e7f4b1d025 Pack and unpack were inspired by my 1998 attempts at writing an SMB client for Plan 9. The packets are these grotesque little blobs that have a certain amount of reason to them internally but not enough to make it easy to parse. The little mini-language made the code a lot shorter but in the end, a lot harder to understand and debug. I've since tossed it out and written traditional packet routines, though even that hasn't been enough to salvage the project (yet). The minilanguage for smb was nice mainly because there are redundant count fields scattered throughout the packet, and the assembler takes care of those automatically. 9P doesn't really need a packet assembler because things are so simple. The packet assembler would be just as long as the simple implementation. There's also something therapeutic about how direct that code is. (I've been playing with an Sun RPC compiler recently; trust me on this.) Here are some examples from the 1998 SMB code. The # separates request from reply formats. Inside each half, the | separates the "word" section from the "data" section. of the packet. *X and *D variable sized data in various guises. A appears to be a string. Russ static int PCsession(void) { ushort action; int l; l = strlen(smb.passwd); if(dosmb(SmbSessionX, Niltid, 1, "hhhhhlhl|*Xaaaa#hhh|", 0xff, 0, 7000, 1, 0, 0, l, 0, l, smb.passwd, "rsc", "rsc-land", "plan9", "plan9", nil, nil, &action) < 0) return -1; chat("action=%x...", action); return 0; } static int PCtreecon(char *tree) { ushort tid; char str[1024]; smb.tree = strdup(tree); /* FIXME */ snprint(str, sizeof str, "\\\\%s\\%s", smb.servername, tree); strupr(str); chat("treecon(%s)...", str); if(dosmb(SmbTreeConn, Niltid, 1, "|AAA#hh|", str, smb.passwd, "A:", nil, &tid) < 0) return -1; return tid; } static int PCopen(char *fname, int mode) { char str[1024]; int fd; mode = (4<<4)|mode; /* no locking */ snprint(str, sizeof str, "%s", fname); /* FIXME XXX estrdup */ strupr(str); chat("\nopen(%s, 0x%x)...", str, mode); if(dosmb(SmbOpen, smb.tid, 1, "hh|A#hhllh|", mode, 0, str, &fd, nil, nil, nil, nil) < 0) return -1; return fd; } static int PCread(int fd, void *v, int off, int n) { if(dosmb(SmbRead, smb.tid, 1, "hhlh|#hll|*D", fd, n, off, 0, nil, nil, nil, &n, v) < 0) return -1; return n; } static int PCwrite(int fd, void *v, int off, int n) { if(dosmb(SmbWrite, smb.tid, 1, "hhlh|*D#h|", fd, n, off, 0, n, v, &n) < 0) return -1; return n; } static int PCcreate(char *fname, int mode, int perm) { int t, fd; USED(mode); t = time(0); perm = (perm & 0200) ? 0x20: 0x21; if(dosmb(SmbCreate, smb.tid, 1, "hl|A#h|", perm, t, fname, &fd) < 0) return -1; return fd; }