URI: 
       tmerge - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 83ab7d88962d717ca5729e7337706b6e4da48af6
   DIR parent 00a8743cd85fcb605a06382387ac526e7fe8bf36
  HTML Author: Russ Cox <rsc@swtch.com>
       Date:   Tue, 27 Nov 2007 15:39:06 -0500
       
       merge
       
       Diffstat:
         M .cvsignore                          |       1 +
         M bin/9fs                             |      11 ++++++++---
         M lib/moveplan9.files                 |       1 +
         M mail/lib/validateattachment         |       4 ++++
         M src/cmd/9p.c                        |       2 +-
         M src/cmd/9pfuse/fuse.c               |      11 ++++++++++-
         M src/cmd/9pfuse/main.c               |      19 ++++++++++++++-----
         M src/cmd/acme/cols.c                 |       9 +++++----
         M src/cmd/acme/look.c                 |       4 ++--
         M src/cmd/upas/nfs/imap.c             |      10 ++++++++--
         M src/cmd/upas/vf/unvf.c              |       2 +-
         M src/cmd/vbackup/diskcat.c           |       2 +-
         M src/cmd/vbackup/diskftp.c           |       2 +-
         M src/cmd/vbackup/disknfs.c           |       2 +-
         M src/cmd/vbackup/vbackup.c           |       2 +-
         M src/cmd/vbackup/vcat.c              |       2 +-
         M src/cmd/vbackup/vftp.c              |       2 +-
         M src/lib9/_p9dir.c                   |       2 +-
         M src/lib9/getns.c                    |       5 +++++
         M src/libdiskfs/ext2.c                |     238 ++++++++++++++++++++++---------
         M src/libdiskfs/ext2.h                |      15 +++++----------
       
       21 files changed, 239 insertions(+), 107 deletions(-)
       ---
   DIR diff --git a/.cvsignore b/.cvsignore
       t@@ -1,2 +1,3 @@
       +9pm
        config
        install.log
   DIR diff --git a/bin/9fs b/bin/9fs
       t@@ -6,18 +6,23 @@ if(! ~ $#* 1){
        }
        
        fn srv1 {
       +        flag=()
       +        if(~ $1 -*){
       +                flag=$1
       +                shift
       +        }
                if(! 9p stat $1 >/dev/null >[2=1]){
                        rm -f $ns/$1
       -                srv -a $2 $1
       +                srv $flag $2 $1
                }
        }
        
        ns=`{namespace}
        switch($1){
        case tip
       -        srv1 tip utumno.tip9ug.jp
       +        srv1 -a tip utumno.tip9ug.jp
        case sources
       -        srv1 sources sources.cs.bell-labs.com
       +        srv1 -n sources sources.cs.bell-labs.com
        case *
                srv1 $1 $1
        }
   DIR diff --git a/lib/moveplan9.files b/lib/moveplan9.files
       t@@ -24,5 +24,6 @@ bin/vwhois
        bin/vmount
        bin/yesterday
        man/mkindex
       +tmac/tmac.an
        tmac/tmac.anhtml
        tmac/tmac.pm
   DIR diff --git a/mail/lib/validateattachment b/mail/lib/validateattachment
       t@@ -54,6 +54,10 @@ case *'zip archive'*
                # but the errors look like
                # unzip: reading data for philw.doc.scr failed: ...
                # so we can still catch these.
       +        if(! unzip -tsf $file >[2=1] >/dev/null){
       +                echo corrupt zip file!
       +                exit $discard
       +        }
                if(unzip -tsf $file >[2=1] | grep -si '      |\.(scr|exe|pif|bat|com)$'){
                        echo executables inside zip file!
                        exit $discard
   DIR diff --git a/src/cmd/9p.c b/src/cmd/9p.c
       t@@ -538,7 +538,7 @@ xls(int argc, char **argv)
                                }
                                if(sort)
                                        qsort(d, n, sizeof d[0], dircmp);
       -                        for(j=0; j<5; j++)
       +                        for(j=0; j<4; j++)
                                        len[j] = 0;
                                for(i=0; i<n; i++){
                                        d[i].type = 'M';
   DIR diff --git a/src/cmd/9pfuse/fuse.c b/src/cmd/9pfuse/fuse.c
       t@@ -804,6 +804,8 @@ mountfuse(char *mtpt)
                                "/Contents/Resources/load_fusefs", 0) < 0 &&
                           access(f="/Library/Extensions/fusefs.kext"
                                   "/Contents/Resources/load_fusefs", 0) < 0 &&
       +                   access(f="/Library/Filesystems"
       +                                  "/fusefs.fs/Support/load_fusefs", 0) < 0 &&
                           access(f="/System/Library/Filesystems"
                                 "/fusefs.fs/Support/load_fusefs", 0) < 0){
                                   werrstr("cannot find load_fusefs");
       t@@ -843,8 +845,15 @@ mountfuse(char *mtpt)
                        /*
                         * Different versions of MacFUSE put the
                         * mount_fusefs binary in different places.
       -                 * Try both.
       +                 * Try all.
                         */
       +                /* Leopard location */
       +                putenv("MOUNT_FUSEFS_DAEMON_PATH",
       +                           "/Library/Filesystems/fusefs.fs/Support/mount_fusefs");
       +                execl("/Library/Filesystems/fusefs.fs/Support/mount_fusefs",
       +                          "mount_fusefs", buf, mtpt, nil);
       +
       +                /* possible Tiger locations */
                        execl("/System/Library/Filesystems/fusefs.fs/mount_fusefs",
                                "mount_fusefs", buf, mtpt, nil);
                        execl("/System/Library/Filesystems/fusefs.fs/Support/mount_fusefs",
   DIR diff --git a/src/cmd/9pfuse/main.c b/src/cmd/9pfuse/main.c
       t@@ -22,12 +22,21 @@
        #ifndef O_DIRECTORY
        #define O_DIRECTORY 0
        #endif
       +
        #ifndef O_LARGEFILE
       -#if defined(__linux__)
       -#define O_LARGEFILE 0100000  /* Sigh */
       -#else
       -#define O_LARGEFILE 0
       +#  if defined(__linux__)
       +#    define O_LARGEFILE 0100000  /* Sigh */
       +#  else
       +#    define O_LARGEFILE 0
       +#  endif
        #endif
       +
       +#ifndef O_CLOEXEC
       +#  if defined(__linux__)
       +#    define O_CLOEXEC 02000000  /* Sigh */
       +#  else
       +#    define O_CLOEXEC 0
       +#  endif
        #endif
        
        
       t@@ -552,7 +561,7 @@ _fuseopen(FuseMsg *m, int isdir)
                flags = in->flags;
                openmode = flags&3;
                flags &= ~3;
       -        flags &= ~(O_DIRECTORY|O_NONBLOCK|O_LARGEFILE);
       +        flags &= ~(O_DIRECTORY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC);
                if(flags & O_TRUNC){
                        openmode |= OTRUNC;
                        flags &= ~O_TRUNC;
   DIR diff --git a/src/cmd/acme/cols.c b/src/cmd/acme/cols.c
       t@@ -534,11 +534,12 @@ colwhich(Column *c, Point p)
                for(i=0; i<c->nw; i++){
                        w = c->w[i];
                        if(ptinrect(p, w->r)){
       -                        if(ptinrect(p, w->tagtop) || ptinrect(p, w->tag.fr.r))
       +                        if(ptinrect(p, w->tagtop) || ptinrect(p, w->tag.all))
                                        return &w->tag;
       -                        if(ptinrect(p, w->body.scrollr) || ptinrect(p, w->body.fr.r))
       -                                return &w->body;
       -                        return nil;
       +                        /* exclude partial line at bottom */
       +                        if(p.x >= w->body.scrollr.max.x && p.y >= w->body.fr.r.max.y)
       +                                return nil;
       +                        return &w->body;
                        }
                }
                return nil;
   DIR diff --git a/src/cmd/acme/look.c b/src/cmd/acme/look.c
       t@@ -365,11 +365,11 @@ search(Text *ct, Rune *r, uint n)
                                fbuffree(s);
                                return TRUE;
                        }
       -                if(around && q>=ct->q1)
       -                        break;
                        --nb;
                        b++;
                        q++;
       +                if(around && q>=ct->q1)
       +                        break;
                }
                fbuffree(s);
                return FALSE;
   DIR diff --git a/src/cmd/upas/nfs/imap.c b/src/cmd/upas/nfs/imap.c
       t@@ -569,13 +569,19 @@ int
        imapcopylist(Imap *z, char *nbox, Msg **m, uint nm)
        {
                int rv;
       -        char *name;
       +        char *name, *p;
                
                if(nm == 0)
                        return 0;
        
                qlock(&z->lk);
       -        name = esmprint("%Z", nbox);
       +        if(strcmp(nbox, "mbox") == 0)
       +                name = estrdup("INBOX");
       +        else{
       +                p = esmprint("%s%s", z->root, nbox);
       +                name = esmprint("%Z", p);
       +                free(p);
       +        }
                rv = imaplistcmd(z, m[0]->box, "UID COPY", m, nm, name);
                free(name);
                qunlock(&z->lk);
   DIR diff --git a/src/cmd/upas/vf/unvf.c b/src/cmd/upas/vf/unvf.c
       t@@ -24,7 +24,7 @@ main(void)
                while((p = Brdstr(&b, '\n', 1)) != nil){
                        if(p[0] == 0)
                                break;
       -                if(strncmp(p, "Content-Transfer-Encoding: ", 27) == 0)
       +                if(cistrncmp(p, "Content-Transfer-Encoding: ", 27) == 0)
                                encoding = strdup(p+27);
                        free(p);
                }
   DIR diff --git a/src/cmd/vbackup/diskcat.c b/src/cmd/vbackup/diskcat.c
       t@@ -33,7 +33,7 @@ main(int argc, char **argv)
                if((disk = diskcache(disk, 16384, 16)) == nil)
                        sysfatal("diskcache: %r");
                if((fsys = fsysopen(disk)) == nil)
       -                sysfatal("ffsopen: %r");
       +                sysfatal("fsysopen: %r");
        
                zero = emalloc(fsys->blocksize);
                fprint(2, "%d blocks total\n", fsys->nblock);
   DIR diff --git a/src/cmd/vbackup/diskftp.c b/src/cmd/vbackup/diskftp.c
       t@@ -72,7 +72,7 @@ threadmain(int argc, char **argv)
                if((disk = diskcache(disk, 16384, 16)) == nil)
                        sysfatal("diskcache: %r");
                if((fsys = fsysopen(disk)) == nil)
       -                sysfatal("ffsopen: %r");
       +                sysfatal("fsysopen: %r");
        
                allowall = 1;
                memset(&au, 0, sizeof au);
   DIR diff --git a/src/cmd/vbackup/disknfs.c b/src/cmd/vbackup/disknfs.c
       t@@ -67,7 +67,7 @@ threadmain(int argc, char **argv)
                        sysfatal("diskcache: %r");
        
                if((fsys = fsysopen(disk)) == nil)
       -                sysfatal("ffsopen: %r");
       +                sysfatal("fsysopen: %r");
        
                nfs3chan = chancreate(sizeof(SunMsg*), 0);
                mountchan = chancreate(sizeof(SunMsg*), 0);
   DIR diff --git a/src/cmd/vbackup/vbackup.c b/src/cmd/vbackup/vbackup.c
       t@@ -164,7 +164,7 @@ threadmain(int argc, char **argv)
                if((disk = diskcache(disk, 32768, 2*MAXQ+16)) == nil)
                        sysfatal("diskcache: %r");
                if((fsys = fsysopen(disk)) == nil)
       -                sysfatal("ffsopen: %r");
       +                sysfatal("fsysopen: %r");
        
                /*
                 * connect to venti
   DIR diff --git a/src/cmd/vbackup/vcat.c b/src/cmd/vbackup/vcat.c
       t@@ -52,7 +52,7 @@ threadmain(int argc, char **argv)
                if((disk = diskopenventi(c, score)) == nil)
                        sysfatal("diskopenventi: %r");
                if((fsys = fsysopen(disk)) == nil)
       -                sysfatal("ffsopen: %r");
       +                sysfatal("fsysopen: %r");
        
                zero = emalloc(fsys->blocksize);
                fprint(2, "%d blocks total\n", fsys->nblock);
   DIR diff --git a/src/cmd/vbackup/vftp.c b/src/cmd/vbackup/vftp.c
       t@@ -418,7 +418,7 @@ threadmain(int argc, char **argv)
                                sysfatal("diskopenventi: %r");
                }
                if((fsys = fsysopen(disk)) == nil)
       -                sysfatal("ffsopen: %r");
       +                sysfatal("fsysopen: %r");
        
                fprint(2, "block size %d\n", fsys->blocksize);
                buf = emalloc(fsys->blocksize);
   DIR diff --git a/src/lib9/_p9dir.c b/src/lib9/_p9dir.c
       t@@ -252,7 +252,7 @@ _p9dir(struct stat *lst, struct stat *st, char *name, Dir *d, char **str, char *
                                close(fd);
                        }
        #endif
       -#if defined(__FreeBSD__)
       +#if defined(DIOCGMEDIASIZE)
                        if(isdisk(st)){
                                int fd;
                                off_t mediasize;
   DIR diff --git a/src/lib9/getns.c b/src/lib9/getns.c
       t@@ -42,6 +42,11 @@ nsfromdisplay(void)
                        if(strcmp(p, ".0") == 0)
                                *p = 0;
                }
       +        
       +        /* turn /tmp/launch/:0 into _tmp_launch_:0 (OS X 10.5) */
       +        for(p=disp; *p; p++)
       +                if(*p == '/')
       +                        *p = '_';
        
                p = smprint("/tmp/ns.%s.%s", getuser(), disp);
                free(disp);
   DIR diff --git a/src/libdiskfs/ext2.c b/src/libdiskfs/ext2.c
       t@@ -6,6 +6,11 @@
        #include <diskfs.h>
        #include "ext2.h"
        
       +static void parsedirent(Dirent*, uchar*);
       +static void parseinode(Inode*, uchar*);
       +static void parsegroup(Group*, uchar*);
       +static void parsesuper(Super*, uchar*);
       +
        #define debug 0
        
        static int ext2sync(Fsys*);
       t@@ -63,31 +68,29 @@ ext2close(Fsys *fsys)
                free(fsys);
        }
        
       -static Group*
       -ext2group(Ext2 *fs, u32int i, Block **pb)
       +static int
       +ext2group(Ext2 *fs, u32int i, Group *g)
        {
                Block *b;
                u64int addr;
       -        Group *g;
        
                if(i >= fs->ngroup)
       -                return nil;
       +                return -1;
        
                addr = fs->groupaddr + i/fs->descperblock;
                b = diskread(fs->disk, fs->blocksize, addr*fs->blocksize);
                if(b == nil)
       -                return nil;
       -        g = (Group*)(b->data+i%fs->descperblock*GroupSize);
       -        *pb = b;
       -        return g;
       +                return -1;
       +        parsegroup(g, b->data+i%fs->descperblock*GroupSize);
       +        blockput(b);
       +        return 0;
        }
        
        static Block*
        ext2blockread(Fsys *fsys, u64int vbno)
        {
                Block *bitb;
       -        Group *g;
       -        Block *gb;
       +        Group g;
                uchar *bits;
                u32int bno, boff, bitblock;
                u64int bitpos;
       t@@ -108,7 +111,7 @@ ext2blockread(Fsys *fsys, u64int vbno)
                        return nil;
        
                bno -= fs->firstblock;
       -        if((g = ext2group(fs, bno/fs->blockspergroup, &gb)) == nil){
       +        if(ext2group(fs, bno/fs->blockspergroup, &g) < 0){
                        if(debug)
                                fprint(2, "loading group: %r...");
                        return nil;
       t@@ -117,18 +120,17 @@ ext2blockread(Fsys *fsys, u64int vbno)
                if(debug)
                        fprint(2, "ext2 group %d: bitblock=%ud inodebitblock=%ud inodeaddr=%ud freeblocks=%ud freeinodes=%ud useddirs=%ud\n",
                                (int)(bno/fs->blockspergroup),
       -                        g->bitblock,
       -                        g->inodebitblock,
       -                        g->inodeaddr,
       -                        g->freeblockscount,
       -                        g->freeinodescount,
       -                        g->useddirscount);
       +                        g.bitblock,
       +                        g.inodebitblock,
       +                        g.inodeaddr,
       +                        g.freeblockscount,
       +                        g.freeinodescount,
       +                        g.useddirscount);
                if(debug)
       -                fprint(2, "group %d bitblock=%d...", bno/fs->blockspergroup, g->bitblock);
       +                fprint(2, "group %d bitblock=%d...", bno/fs->blockspergroup, g.bitblock);
        */
       -        bitblock = g->bitblock;
       +        bitblock = g.bitblock;
                bitpos = (u64int)bitblock*fs->blocksize;
       -        blockput(gb);
        
                if((bitb = diskread(fs->disk, fs->blocksize, bitpos)) == nil){
                        if(debug)
       t@@ -253,33 +255,33 @@ static int
        ext2sync(Fsys *fsys)
        {
                int i;
       -        Group *g;
       +        Group g;
                Block *b;
       -        Super *super;
       +        Super super;
                Ext2 *fs;
                Disk *disk;
        
                fs = fsys->priv;
                disk = fs->disk;
                if((b = diskread(disk, SBSIZE, SBOFF)) == nil)
       -                goto error;
       -        super = (Super*)b->data;
       -        if(checksuper(super) < 0)
       -                goto error;
       -        fs->blocksize = MINBLOCKSIZE<<super->logblocksize;
       -        fs->nblock = super->nblock;
       -        fs->ngroup = (super->nblock+super->blockspergroup-1)
       -                / super->blockspergroup;
       -        fs->inospergroup = super->inospergroup;
       -        fs->blockspergroup = super->blockspergroup;
       +                return -1;
       +        parsesuper(&super, b->data);
       +        blockput(b);
       +        if(checksuper(&super) < 0)
       +                return -1;
       +        fs->blocksize = MINBLOCKSIZE<<super.logblocksize;
       +        fs->nblock = super.nblock;
       +        fs->ngroup = (super.nblock+super.blockspergroup-1)
       +                / super.blockspergroup;
       +        fs->inospergroup = super.inospergroup;
       +        fs->blockspergroup = super.blockspergroup;
                fs->inosperblock = fs->blocksize / InodeSize;
                if(fs->blocksize == SBOFF)
                        fs->groupaddr = 2;
                else
                        fs->groupaddr = 1;
                fs->descperblock = fs->blocksize / GroupSize;
       -        fs->firstblock = super->firstdatablock;
       -        blockput(b);
       +        fs->firstblock = super.firstdatablock;
        
                fsys->blocksize = fs->blocksize;
                fsys->nblock = fs->nblock;
       t@@ -288,16 +290,10 @@ ext2sync(Fsys *fsys)
        
                if(0){
                        for(i=0; i<fs->ngroup; i++)
       -                        if((g = ext2group(fs, i, &b)) != nil){
       -                                fprint(2, "grp %d: bitblock=%d\n", i, g->bitblock);
       -                                blockput(b);
       -                        }
       +                        if(ext2group(fs, i, &g) >= 0)
       +                                fprint(2, "grp %d: bitblock=%d\n", i, g.bitblock);
                }
                return 0;
       -
       -error:
       -        blockput(b);
       -        return -1;
        }
        
        static void
       t@@ -323,8 +319,8 @@ handle2ino(Ext2 *fs, Nfs3Handle *h, u32int *pinum, Inode *ino)
                uint ioff;
                u32int inum;
                u32int addr;
       -        Block *gb, *b;
       -        Group *g;
       +        Block *b;
       +        Group g;
        
                if(h->len != 4)
                        return Nfs3ErrBadHandle;
       t@@ -335,13 +331,12 @@ handle2ino(Ext2 *fs, Nfs3Handle *h, u32int *pinum, Inode *ino)
                if(i >= fs->ngroup)
                        return Nfs3ErrBadHandle;
                ioff = (inum-1) % fs->inospergroup;
       -        if((g = ext2group(fs, i, &gb)) == nil)
       +        if(ext2group(fs, i, &g) < 0)
                        return Nfs3ErrIo;
       -        addr = g->inodeaddr + ioff/fs->inosperblock;
       -        blockput(gb);
       +        addr = g.inodeaddr + ioff/fs->inosperblock;
                if((b = diskread(fs->disk, fs->blocksize, (u64int)addr*fs->blocksize)) == nil)
                        return Nfs3ErrIo;
       -        *ino = ((Inode*)b->data)[ioff%fs->inosperblock];
       +        parseinode(ino, b->data+InodeSize*(ioff%fs->inosperblock));
                blockput(b);
                return Nfs3Ok;
        }
       t@@ -505,7 +500,7 @@ ext2lookup(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char *name, Nfs3Handle *n
                u32int nblock;
                u32int i;
                uchar *p, *ep;
       -        Dirent *de;
       +        Dirent de;
                Inode ino;
                Block *b;
                Ext2 *fs;
       t@@ -538,27 +533,27 @@ ext2lookup(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char *name, Nfs3Handle *n
                        p = b->data;
                        ep = p+b->len;
                        while(p < ep){
       -                        de = (Dirent*)p;
       -                        if(de->reclen == 0){
       +                        parsedirent(&de, p);
       +                        if(de.reclen == 0){
                                        if(debug)
                                                fprint(2, "reclen 0 at offset %d of %d\n", (int)(p-b->data), b->len);
                                        break;
                                }
       -                        p += de->reclen;
       +                        p += de.reclen;
                                if(p > ep){
                                        if(debug)
       -                                        fprint(2, "bad len %d at offset %d of %d\n", de->reclen, (int)(p-b->data), b->len);
       +                                        fprint(2, "bad len %d at offset %d of %d\n", de.reclen, (int)(p-b->data), b->len);
                                        break;
                                }
       -                        if(de->ino == 0)
       +                        if(de.ino == 0)
                                        continue;
       -                        if(4+2+2+de->namlen > de->reclen){
       +                        if(4+2+2+de.namlen > de.reclen){
                                        if(debug)
       -                                        fprint(2, "bad namelen %d at offset %d of %d\n", de->namlen, (int)(p-b->data), b->len);
       +                                        fprint(2, "bad namelen %d at offset %d of %d\n", de.namlen, (int)(p-b->data), b->len);
                                        break;
                                }
       -                        if(de->namlen == len && memcmp(de->name, name, len) == 0){
       -                                mkhandle(nh, de->ino);
       +                        if(de.namlen == len && memcmp(de.name, name, len) == 0){
       +                                mkhandle(nh, de.ino);
                                        blockput(b);
                                        return Nfs3Ok;
                                }
       t@@ -575,7 +570,7 @@ ext2readdir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int coo
                u32int i;
                int off, done;
                uchar *data, *dp, *dep, *p, *ep, *ndp;
       -        Dirent *de;
       +        Dirent de;
                Inode ino;
                Block *b;
                Ext2 *fs;
       t@@ -622,30 +617,30 @@ ext2readdir(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, u32int count, u64int coo
                        ep = p+b->len;
                        memset(&e, 0, sizeof e);
                        while(p < ep){
       -                        de = (Dirent*)p;
       -                        if(de->reclen == 0){
       +                        parsedirent(&de, p);
       +                        if(de.reclen == 0){
                                        if(debug) fprint(2, "reclen 0 at offset %d of %d\n", (int)(p-b->data), b->len);
                                        break;
                                }
       -                        p += de->reclen;
       +                        p += de.reclen;
                                if(p > ep){
       -                                if(debug) fprint(2, "reclen %d at offset %d of %d\n", de->reclen, (int)(p-b->data), b->len);
       +                                if(debug) fprint(2, "reclen %d at offset %d of %d\n", de.reclen, (int)(p-b->data), b->len);
                                        break;
                                }
       -                        if(de->ino == 0){
       +                        if(de.ino == 0){
                                        if(debug) fprint(2, "zero inode\n");
                                        continue;
                                }
       -                        if(4+2+2+de->namlen > de->reclen){
       -                                if(debug) fprint(2, "bad namlen %d reclen %d at offset %d of %d\n", de->namlen, de->reclen, (int)(p-b->data), b->len);
       +                        if(4+2+2+de.namlen > de.reclen){
       +                                if(debug) fprint(2, "bad namlen %d reclen %d at offset %d of %d\n", de.namlen, de.reclen, (int)(p-b->data), b->len);
                                        break;
                                }
       -                        if(debug) print("%.*s/%d ", de->namlen, de->name, (int)de->ino);
       -                        if((uchar*)de - b->data < off)
       +                        if(debug) print("%.*s/%d ", de.namlen, de.name, (int)de.ino);
       +                        if(p-de.reclen - b->data < off)
                                        continue;
       -                        e.fileid = de->ino;
       -                        e.name = de->name;
       -                        e.namelen = de->namlen;
       +                        e.fileid = de.ino;
       +                        e.name = de.name;
       +                        e.namelen = de.namlen;
                                e.cookie = (u64int)i*fs->blocksize + (p - b->data);
                                if(nfs3entrypack(dp, dep, &ndp, &e) < 0){
                                        done = 1;
       t@@ -778,3 +773,104 @@ ext2readlink(Fsys *fsys, SunAuthUnix *au, Nfs3Handle *h, char **link)
                return Nfs3Ok;
        }
        
       +/*
       + * Ext2 is always little-endian, even on big-endian machines.
       + */
       +
       +static u32int
       +l32(uchar *p)
       +{
       +        return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
       +}
       +
       +static u16int
       +l16(uchar *p)
       +{
       +        return p[0] | (p[1]<<8);
       +}
       +
       +static u8int
       +l8(uchar *p)
       +{
       +        return p[0];
       +}
       +
       +static void
       +parsedirent(Dirent *de, uchar *p)
       +{
       +        de->ino = l32(p);
       +        de->reclen = l16(p+4);
       +        de->namlen = l8(p+6);
       +        /* 1 byte pad */
       +        de->name = (char*)p+8;
       +}
       +
       +static void
       +parseinode(Inode *ino, uchar *p)
       +{
       +        int i;
       +
       +        ino->mode = l16(p);
       +        ino->uid = l16(p+2);
       +        ino->size = l32(p+4);
       +        ino->atime = l32(p+8);
       +        ino->ctime = l32(p+12);
       +        ino->mtime = l32(p+16);
       +        ino->dtime = l32(p+20);
       +        ino->gid = l16(p+24);
       +        ino->nlink = l16(p+26);
       +        ino->nblock = l32(p+28);
       +        ino->flags = l32(p+32);
       +        /* 4 byte osd1 */
       +        for(i=0; i<NBLOCKS; i++)
       +                ino->block[i] = l32(p+40+i*4);
       +        ino->version = l32(p+100);
       +        ino->fileacl = l32(p+104);
       +        ino->diracl = l32(p+108);
       +        ino->faddr = l32(p+112);
       +        /* 12 byte osd2 */
       +}
       +
       +static void
       +parsegroup(Group *g, uchar *p)
       +{
       +        g->bitblock = l32(p);
       +        g->inodebitblock = l32(p+4);
       +        g->inodeaddr = l32(p+8);
       +        g->freeblockscount = l16(p+12);
       +        g->freeinodescount = l16(p+14);
       +        g->useddirscount = l16(p+16);
       +        /* 2 byte pad */
       +        /* 12 byte reserved */
       +}
       +
       +static void
       +parsesuper(Super *s, uchar *p)
       +{
       +        s->ninode = l32(p);
       +        s->nblock = l32(p+4);
       +        s->rblockcount = l32(p+8);
       +        s->freeblockcount = l32(p+12);
       +        s->freeinodecount = l32(p+16);
       +        s->firstdatablock = l32(p+20);
       +        s->logblocksize = l32(p+24);
       +        s->logfragsize = l32(p+28);
       +        s->blockspergroup = l32(p+32);
       +        s->fragpergroup = l32(p+36);
       +        s->inospergroup = l32(p+40);
       +        s->mtime = l32(p+44);
       +        s->wtime = l32(p+48);
       +        s->mntcount = l16(p+52);
       +        s->maxmntcount = l16(p+54);
       +        s->magic = l16(p+56);
       +        s->state = l16(p+58);
       +        s->errors = l16(p+60);
       +        /* 2 byte pad */
       +        s->lastcheck = l32(p+64);
       +        s->checkinterval = l32(p+68);
       +        s->creatoros = l32(p+72);
       +        s->revlevel = l32(p+76);
       +        s->defresuid = l16(p+80);
       +        s->defresgid = l16(p+82);
       +        /* 940 byte reserved */
       +}
   DIR diff --git a/src/libdiskfs/ext2.h b/src/libdiskfs/ext2.h
       t@@ -51,7 +51,7 @@ enum
        
        
        /*
       - * Super block on-disk format.
       + * Super block
         */
        struct Super
        {
       t@@ -84,7 +84,7 @@ struct Super
        };
        
        /*
       - * Block group on-disk format.
       + * Block group
         */
        struct Group
        {
       t@@ -94,8 +94,6 @@ struct Group
                u16int        freeblockscount;        /* Free blocks count */
                u16int        freeinodescount;        /* Free inodes count */
                u16int        useddirscount;        /* Directories count */
       -        u16int        pad;
       -        u32int        reserved[3];
        };
        enum
        {
       t@@ -103,7 +101,7 @@ enum
        };
        
        /*
       - * Structure of an inode on the disk
       + * Inode
         */
        struct Inode
        {
       t@@ -118,13 +116,11 @@ struct Inode
                u16int        nlink;        /* Links count */
                u32int        nblock;        /* Blocks count */
                u32int        flags;                /* File flags */
       -        u32int        osd1;                                
                u32int        block[NBLOCKS];/* Pointers to blocks */
                u32int        version;        /* File version (for NFS) */
                u32int        fileacl;        /* File ACL */
                u32int        diracl;        /* Directory ACL or high size bits */
                u32int        faddr;                /* Fragment address */
       -        uchar        osd2[12];
        };
        enum
        {
       t@@ -132,15 +128,14 @@ enum
        };
        
        /*
       - * Directory entry on-disk structure.
       + * Directory entry
         */
        struct Dirent
        {
                u32int        ino;                        /* Inode number */
                u16int        reclen;                /* Directory entry length */
                u8int        namlen;                /* Name length */
       -        u8int        pad;
       -        char        name[NAMELEN];        /* File name */
       +        char        *name;        /* File name */
        };
        enum
        {