]> git.wh0rd.org - dump.git/blobdiff - restore/tape.c
Fix big endian issues with EA/ACL
[dump.git] / restore / tape.c
index e82b780aeb9ebd12851ed0e3b35132cf627b371a..c74e3909f10e46cf1f1ae026573f5d9cfab56bde 100644 (file)
@@ -42,7 +42,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-       "$Id: tape.c,v 1.77 2004/01/27 10:18:17 stelian Exp $";
+       "$Id: tape.c,v 1.90 2005/06/08 13:24:11 stelian Exp $";
 #endif /* not lint */
 
 #include <config.h>
@@ -167,7 +167,10 @@ static void         xtrlnkskip __P((char *, size_t));
 static void     xtrmap __P((char *, size_t));
 static void     xtrmapskip __P((char *, size_t));
 static void     xtrskip __P((char *, size_t));
+static void     xtrxattr __P((char *, size_t));
 static void     setmagtapein __P((void));
+static int      extractattr __P((char *));
+static void     compareattr __P((char *));
 
 #if defined(HAVE_ZLIB) || defined(HAVE_BZLIB) || defined(HAVE_LZO)
 static void    newcomprbuf __P((int));
@@ -194,6 +197,9 @@ static void xtrcmpskip __P((char *, size_t));
 static int readmapflag;
 static int readingmaps;                /* set to 1 while reading the maps */
 
+static char xattrbuf[XATTR_MAXSIZE];
+static int xattrlen;
+
 #ifdef DUMP_MACOSX
 static DumpFinderInfo  gFndrInfo;
 #endif
@@ -340,6 +346,7 @@ setup(void)
 #endif
        FLUSHTAPEBUF();
        findtapeblksize();
+       cvtflag = 0;
        if (gethead(&spcl) == FAIL) {
                blkcnt--; /* push back this block */
                blksread--;
@@ -840,14 +847,19 @@ extractfile(struct entry *ep, int doremove)
                return (GOOD);
 
        case IFDIR:
+       {
+               int ret;
                if (mflag) {
                        if (ep == NULL || ep->e_flags & EXTRACT)
                                panic("unextracted directory %s\n", name);
                        skipfile();
                        return (GOOD);
                }
-               Vprintf(stdout, "extract file %s\n", name);
-               return (genliteraldir(name, curfile.ino));
+               Vprintf(stdout, "extract dir %s\n", name);
+               ret = genliteraldir(name, curfile.ino);
+               extractattr(name);
+               return ret;
+       }
 
        case IFLNK:
        {
@@ -873,6 +885,7 @@ extractfile(struct entry *ep, int doremove)
 #ifdef HAVE_LCHOWN
                (void) lchown(name, luid, lgid);
 #endif
+               extractattr(name);
                return (GOOD);
        }
 
@@ -895,7 +908,7 @@ extractfile(struct entry *ep, int doremove)
                (void) chmod(name, mode);
                if (flags)
 #ifdef  __linux__
-                       (void) fsetflags(name, flags);
+                       (void) lsetflags(name, flags);
 #else
 #ifdef sunos
                        {
@@ -907,6 +920,7 @@ extractfile(struct entry *ep, int doremove)
 #endif
 #endif
                skipfile();
+               extractattr(name);
                utimes(name, timep);
                return (GOOD);
 
@@ -931,8 +945,8 @@ extractfile(struct entry *ep, int doremove)
                if (flags)
 #ifdef __linux__
                        {
-                       warn("%s: fsetflags called on a special file", name);
-                       (void) fsetflags(name, flags);
+                       warn("%s: lsetflags called on a special file", name);
+                       (void) lsetflags(name, flags);
                        }
 #else
 #ifdef sunos
@@ -948,6 +962,7 @@ extractfile(struct entry *ep, int doremove)
 #endif
 #endif
                skipfile();
+               extractattr(name);
                utimes(name, timep);
                return (GOOD);
 
@@ -979,7 +994,7 @@ extractfile(struct entry *ep, int doremove)
                (void) chmod(name, mode);
                if (flags)
 #ifdef __linux__
-                       (void) fsetflags(name, flags);
+                       (void) lsetflags(name, flags);
 #else
 #ifdef sunos
                        {
@@ -990,6 +1005,7 @@ extractfile(struct entry *ep, int doremove)
                        (void) chflags(name, flags);
 #endif
 #endif
+               extractattr(name);
                utimes(name, timep);
                return (GOOD);
        }
@@ -997,6 +1013,44 @@ extractfile(struct entry *ep, int doremove)
        /* NOTREACHED */
 }
 
+static int
+extractattr(char *path)
+{
+       while (spcl.c_flags & DR_EXTATTRIBUTES) {
+               switch (spcl.c_extattributes) {
+               case EXT_MACOSFNDRINFO:
+#ifdef DUMP_MACOSX
+                       (void)extractfinderinfoufs(path);
+#else
+                       msg("MacOSX not supported in this version, skipping\n");
+                       skipfile();
+#endif
+                       break;
+               case EXT_MACOSRESFORK:
+#ifdef DUMP_MACOSX
+                       (void)extractresourceufs(path);
+#else
+                       msg("MacOSX not supported in this version, skipping\n");
+                       skipfile();
+#endif
+                       break;
+               case EXT_XATTR: {
+                       char xattr[XATTR_MAXSIZE];
+                       
+                       if (readxattr(xattr) == GOOD) {
+                               xattr_extract(path, xattr);
+                               break;
+                       }
+               }
+               default:
+                       msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes);
+                       skipfile();
+                       break;
+               }
+       }
+       return GOOD;
+}
+
 #ifdef DUMP_MACOSX
 int
 extractfinderinfoufs(char *name)
@@ -1009,7 +1063,6 @@ extractfinderinfoufs(char *name)
        u_int32_t       uid;
        u_int32_t       gid;
        char    path[MAXPATHLEN], fname[MAXPATHLEN];
-       int toto;
 
        curfile.name = name;
        curfile.action = USING;
@@ -1161,7 +1214,7 @@ extractresourceufs(char *name)
                (void) fchown(ofile, uid, gid);
                (void) fchmod(ofile, mode);
                (void) close(ofile);
-               (void) fsetflags(oFileRsrc, flags);
+               (void) lsetflags(oFileRsrc, flags);
                utimes(oFileRsrc, timep);
                return (GOOD);
        }
@@ -1169,6 +1222,29 @@ extractresourceufs(char *name)
 }
 #endif /* DUMP_MACOSX */
 
+int
+readxattr(char *buffer)
+{
+       if (dflag)
+               msg("reading EA data for inode %lu\n", curfile.ino);
+
+       curfile.name = "EA block";
+       if (curfile.dip->di_size > XATTR_MAXSIZE) {
+               fprintf(stderr, "EA size too big (%ld)", (long)curfile.dip->di_size);
+               skipfile();
+               return (FAIL);
+       }
+       
+       memset(xattrbuf, 0, XATTR_MAXSIZE);
+       xattrlen = 0;
+
+       getfile(xtrxattr, xtrnull);
+
+       memcpy(buffer, xattrbuf, XATTR_MAXSIZE);
+
+       return (GOOD);
+}
+
 /*
  * skip over bit maps on the tape
  */
@@ -1191,6 +1267,17 @@ skipfile(void)
        getfile(xtrnull, xtrnull);
 }
 
+/*
+ * skip over any extended attributes.
+ */
+void
+skipxattr(void)
+{
+
+       while (spcl.c_flags & DR_EXTATTRIBUTES)
+               skipfile();
+}
+
 /*
  * Extract a file from the tape.
  * When an allocated block is found it is passed to the fill function;
@@ -1290,8 +1377,6 @@ xtrfile(char *buf, size_t size)
 static void
 xtrfilefinderinfo(char *buf, size_t size)
 {
-       if (Nflag)
-               return;
        bcopy(buf, &gFndrInfo, size);
 }
 #endif /* DUMP_MACOSX */
@@ -1317,10 +1402,13 @@ xtrlnkfile(char *buf, size_t size)
 {
 
        pathlen += size;
-       if (pathlen > MAXPATHLEN)
+       if (pathlen > MAXPATHLEN) {
+               buf[size - 1] = '\0';
                errx(1, "symbolic link name: %s->%s%s; too long %d",
                    curfile.name, lnkbuf, buf, pathlen);
+       }
        (void) strcat(lnkbuf, buf);
+       lnkbuf[pathlen] = '\0';
 }
 
 /*
@@ -1424,9 +1512,20 @@ xtrcmpskip(UNUSED(char *buf), size_t size)
 }
 #endif /* COMPARE_ONTHEFLY */
 
+static void
+xtrxattr(char *buf, size_t size)
+{
+       if (xattrlen + size > XATTR_MAXSIZE) {
+               fprintf(stderr, "EA size too big (%ld)", (long)xattrlen + size);
+               return;
+       }
+       memcpy(xattrbuf + xattrlen, buf, size);
+       xattrlen += size;
+}
+
 #if !COMPARE_ONTHEFLY
 static int
-do_cmpfiles(int fd_tape, int fd_disk, long size)
+do_cmpfiles(int fd_tape, int fd_disk, OFF_T size)
 {
        static char buf_tape[BUFSIZ];
        static char buf_disk[BUFSIZ];
@@ -1468,15 +1567,15 @@ cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk)
        int fd_tape, fd_disk;
 
        if (STAT(tapefile, &sbuf_tape) != 0) {
-               panic("Can't lstat tmp file %s: %s\n", tapefile,
+               panic("can't lstat tmp file %s: %s\n", tapefile,
                      strerror(errno));
                do_compare_error;
        }
 
        if (sbuf_disk->st_size != sbuf_tape.st_size) {
                fprintf(stderr,
-                       "%s: size changed from %ld to %ld.\n",
-                       diskfile, (long)sbuf_tape.st_size, (long)sbuf_disk->st_size);
+                       "%s: size changed from %lld to %lld.\n",
+                       diskfile, (long long)sbuf_tape.st_size, (long long)sbuf_disk->st_size);
                do_compare_error;
 #ifdef COMPARE_FAIL_KEEP_FILE
                return (0);
@@ -1486,12 +1585,12 @@ cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk)
        }
 
        if ((fd_tape = OPEN(tapefile, O_RDONLY)) < 0) {
-               panic("Can't open %s: %s\n", tapefile, strerror(errno));
+               panic("can't open %s: %s\n", tapefile, strerror(errno));
                do_compare_error;
        }
        if ((fd_disk = OPEN(diskfile, O_RDONLY)) < 0) {
                close(fd_tape);
-               panic("Can't open %s: %s\n", diskfile, strerror(errno));
+               panic("can't open %s: %s\n", diskfile, strerror(errno));
                do_compare_error;
        }
 
@@ -1536,6 +1635,43 @@ cmpfiles(char *tapefile, char *diskfile, struct STAT *sbuf_disk)
 }
 #endif /* !COMPARE_ONTHEFLY */
 
+static void
+compareattr(char *name)
+{
+       int xattr_done = 0;
+       
+       while (spcl.c_flags & DR_EXTATTRIBUTES) {
+               switch (spcl.c_extattributes) {
+               case EXT_MACOSFNDRINFO:
+                       msg("MacOSX not supported for comparision in this version, skipping\n");
+                       skipfile();
+                       break;
+               case EXT_MACOSRESFORK:
+                       msg("MacOSX not supported for comparision in this version, skipping\n");
+                       skipfile();
+                       break;
+               case EXT_XATTR: {
+                       char xattr[XATTR_MAXSIZE];
+
+                       if (readxattr(xattr) == GOOD) {
+                               if (xattr_compare(name, xattr) == FAIL)
+                                       do_compare_error;
+                               xattr_done = 1;
+                       }
+                       else
+                               do_compare_error;
+                       break;
+               }
+               default:
+                       msg("unexpected inode extension %ld, skipping\n", spcl.c_extattributes);
+                       skipfile();
+                       break;
+               }
+       }
+       if (!xattr_done && xattr_compare(name, NULL) == FAIL)
+               do_compare_error;
+}
+
 #if !COMPARE_ONTHEFLY
 static char tmpfilename[MAXPATHLEN];
 #endif
@@ -1543,17 +1679,23 @@ static char tmpfilename[MAXPATHLEN];
 void
 comparefile(char *name)
 {
-       unsigned int mode;
+       mode_t mode;
+       uid_t uid;
+       uid_t gid;
+       unsigned int flags;
+       unsigned long newflags;
        struct STAT sb;
        int r;
 #if !COMPARE_ONTHEFLY
        static char *tmpfile = NULL;
        struct STAT stemp;
 #endif
-
        curfile.name = name;
        curfile.action = USING;
        mode = curfile.dip->di_mode;
+       flags = curfile.dip->di_flags;
+       uid = curfile.dip->di_uid;
+       gid =  curfile.dip->di_gid;
 
        if ((mode & IFMT) == IFSOCK) {
                Vprintf(stdout, "skipped socket %s\n", name);
@@ -1562,20 +1704,45 @@ comparefile(char *name)
        }
 
        if ((r = LSTAT(name, &sb)) != 0) {
-               warn("%s: does not exist (%d)", name, r);
+               warn("unable to stat %s", name);
                do_compare_error;
                skipfile();
                return;
        }
 
-       Vprintf(stdout, "comparing %s (size: %ld, mode: 0%o)\n", name,
-               (long)sb.st_size, mode);
+       Vprintf(stdout, "comparing %s (size: %lld, mode: 0%o)\n", name,
+               (long long)sb.st_size, mode);
 
        if (sb.st_mode != mode) {
                fprintf(stderr, "%s: mode changed from 0%o to 0%o.\n",
                        name, mode & 07777, sb.st_mode & 07777);
                do_compare_error;
        }
+       if (sb.st_uid != uid) {
+               fprintf(stderr, "%s: uid changed from %d to %d.\n",
+                       name, uid, sb.st_uid);
+               do_compare_error;
+       }
+       if (sb.st_gid != gid) {
+               fprintf(stderr, "%s: gid changed from %d to %d.\n",
+                       name, gid, sb.st_gid);
+               do_compare_error;
+       }
+#ifdef  __linux__
+       if (lgetflags(name, &newflags) < 0) {
+               if (flags != 0) {
+                       warn("%s: lgetflags failed", name);
+                       do_compare_error;
+               }
+       }
+       else {
+               if (newflags != flags) {
+                       fprintf(stderr, "%s: flags changed from 0x%08x to 0x%08lx.\n",
+                               name, flags, newflags);
+                       do_compare_error;
+               }
+       }
+#endif
        if (spcl.c_flags & DR_METAONLY) {
                skipfile();
                return;
@@ -1591,6 +1758,7 @@ comparefile(char *name)
 
        case IFDIR:
                skipfile();
+               compareattr(name);
                return;
 
        case IFLNK: {
@@ -1614,7 +1782,7 @@ comparefile(char *name)
                        return;
                }
                if ((lsize = readlink(name, lbuf, MAXPATHLEN)) < 0) {
-                       panic("readlink of %s failed: %s", name,
+                       panic("readlink of %s failed: %s\n", name,
                              strerror(errno));
                        do_compare_error;
                }
@@ -1626,6 +1794,7 @@ comparefile(char *name)
                        do_compare_error;
                        return;
                }
+               compareattr(name);
                return;
        }
 
@@ -1643,19 +1812,20 @@ comparefile(char *name)
                        fprintf(stderr,
                                "%s: device changed from %d,%d to %d,%d.\n",
                                name,
-                               ((int)curfile.dip->di_rdev >> 8) & 0xff,
-                               (int)curfile.dip->di_rdev & 0xff,
-                               ((int)sb.st_rdev >> 8) & 0xff,
-                               (int)sb.st_rdev & 0xff);
+                               major(curfile.dip->di_rdev),
+                               minor(curfile.dip->di_rdev),
+                               major(sb.st_rdev),
+                               minor(sb.st_rdev));
                        do_compare_error;
                }
                skipfile();
+               compareattr(name);
                return;
 
        case IFREG:
 #if COMPARE_ONTHEFLY
                if ((ifile = OPEN(name, O_RDONLY)) < 0) {
-                       panic("Can't open %s: %s\n", name, strerror(errno));
+                       warn("can't open %s", name);
                        skipfile();
                        do_compare_error;
                }
@@ -1698,6 +1868,7 @@ comparefile(char *name)
                unlink(tmpfile);
 #endif
 #endif /* COMPARE_ONTHEFLY */
+               compareattr(name);
                return;
        }
        /* NOTREACHED */
@@ -2063,9 +2234,6 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize)
        /* zflag gets set in setup() from the dump header          */
        int cresult, blocklen;        
        unsigned long worklen;
-#ifdef HAVE_BZLIB
-       unsigned int worklen2;
-#endif
        char *output = NULL,*reason = NULL, *lengtherr = NULL;              
        
        /* build a length error message */
@@ -2112,7 +2280,7 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize)
 #ifndef HAVE_BZLIB
                        errx(1,"This restore version doesn't support bzlib decompression");
 #else
-                       worklen2 = worklen;
+                       unsigned int worklen2 = worklen;
                        cresult = BZ2_bzBuffToBuffDecompress(
                                        comprbuf, &worklen2, 
                                        tpbin->buf, blocklen, 0, 0);
@@ -2145,8 +2313,10 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize)
 #ifndef HAVE_LZO
                        errx(1,"This restore version doesn't support lzo decompression");
 #else
+                       lzo_uint worklen2 = worklen;
                        cresult = lzo1x_decompress(tpbin->buf, blocklen,
-                                                   comprbuf, (lzo_uintp) &worklen,NULL);
+                                                   comprbuf, &worklen2, NULL);
+                       worklen = worklen2;
                        output = comprbuf;
                        switch (cresult) {
                                case LZO_E_OK:
@@ -2176,7 +2346,7 @@ decompress_tapebuf(struct tapebuf *tpbin, int readsize)
        }
        if (reason) {
                if (lengtherr)
-                       fprintf(stderr, "%s compressed block: %d expected: %d\n",
+                       fprintf(stderr, "%s compressed block: %d expected: %u\n",
                                lengtherr, readsize, tpbin->length + PREFIXSIZE);
                fprintf(stderr, "decompression error, block %ld: %s\n",
                        tpblksread+1, reason);
@@ -2243,6 +2413,7 @@ findtapeblksize(void)
                errx(1, "Tape read error on first record");
 
        memcpy(&spclpt, tapebuf, TP_BSIZE);
+       cvtflag = 0;
        if (converthead(&spclpt) == FAIL) {
                cvtflag++;
                if (converthead(&spclpt) == FAIL) {
@@ -2453,38 +2624,51 @@ converthead(struct s_spcl *buf)
                if (checksum((int *)buf) == FAIL)
                        return (FAIL);
                if (Bcvt)
-                       swabst((u_char *)"8i4s31i528bi192b3i", (u_char *)buf);
+                       swabst((u_char *)"8i4s1l29i528bi192b4i", (u_char *)buf);
                goto good;
        }
        memcpy(&u_ospcl.s_ospcl, buf, TP_BSIZE);
-       memset((char *)buf, 0, (long)TP_BSIZE);
-       buf->c_type = u_ospcl.s_ospcl.c_type;
-       buf->c_date = u_ospcl.s_ospcl.c_date;
-       buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
-       buf->c_volume = u_ospcl.s_ospcl.c_volume;
-       buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
-       buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
-       buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
-       buf->c_magic = u_ospcl.s_ospcl.c_magic;
-       buf->c_dinode.di_mode = u_ospcl.s_ospcl.c_dinode.odi_mode;
-       buf->c_dinode.di_nlink = u_ospcl.s_ospcl.c_dinode.odi_nlink;
-       buf->c_dinode.di_uid = u_ospcl.s_ospcl.c_dinode.odi_uid;
-       buf->c_dinode.di_gid = u_ospcl.s_ospcl.c_dinode.odi_gid;
-       buf->c_dinode.di_size = u_ospcl.s_ospcl.c_dinode.odi_size;
-       buf->c_dinode.di_rdev = u_ospcl.s_ospcl.c_dinode.odi_rdev;
+       if (checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
+               return(FAIL);
+       if (u_ospcl.s_ospcl.c_magic == OFS_MAGIC) {
+               memset((char *)buf, 0, (long)TP_BSIZE);
+               buf->c_type = u_ospcl.s_ospcl.c_type;
+               buf->c_date = u_ospcl.s_ospcl.c_date;
+               buf->c_ddate = u_ospcl.s_ospcl.c_ddate;
+               buf->c_volume = u_ospcl.s_ospcl.c_volume;
+               buf->c_tapea = u_ospcl.s_ospcl.c_tapea;
+               buf->c_inumber = u_ospcl.s_ospcl.c_inumber;
+               buf->c_checksum = u_ospcl.s_ospcl.c_checksum;
+               buf->c_magic = u_ospcl.s_ospcl.c_magic;
+               buf->c_dinode.di_mode = u_ospcl.s_ospcl.c_dinode.odi_mode;
+               buf->c_dinode.di_nlink = u_ospcl.s_ospcl.c_dinode.odi_nlink;
+               buf->c_dinode.di_uid = u_ospcl.s_ospcl.c_dinode.odi_uid;
+               buf->c_dinode.di_gid = u_ospcl.s_ospcl.c_dinode.odi_gid;
+               buf->c_dinode.di_size = u_ospcl.s_ospcl.c_dinode.odi_size;
+               buf->c_dinode.di_rdev = u_ospcl.s_ospcl.c_dinode.odi_rdev;
 #if defined(__linux__) || defined(sunos)
-       buf->c_dinode.di_atime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_atime;
-       buf->c_dinode.di_mtime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_mtime;
-       buf->c_dinode.di_ctime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_ctime;
+               buf->c_dinode.di_atime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_atime;
+               buf->c_dinode.di_mtime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_mtime;
+               buf->c_dinode.di_ctime.tv_sec = u_ospcl.s_ospcl.c_dinode.odi_ctime;
 #else  /* __linux__ || sunos */
-       buf->c_dinode.di_atime = u_ospcl.s_ospcl.c_dinode.odi_atime;
-       buf->c_dinode.di_mtime = u_ospcl.s_ospcl.c_dinode.odi_mtime;
-       buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime;
+               buf->c_dinode.di_atime = u_ospcl.s_ospcl.c_dinode.odi_atime;
+               buf->c_dinode.di_mtime = u_ospcl.s_ospcl.c_dinode.odi_mtime;
+               buf->c_dinode.di_ctime = u_ospcl.s_ospcl.c_dinode.odi_ctime;
 #endif /* __linux__ || sunos */
-       buf->c_count = u_ospcl.s_ospcl.c_count;
-       memmove(buf->c_addr, u_ospcl.s_ospcl.c_fill, (long)256);
-       if (u_ospcl.s_ospcl.c_magic != OFS_MAGIC ||
-           checksum((int *)(&u_ospcl.s_ospcl)) == FAIL)
+               buf->c_count = u_ospcl.s_ospcl.c_count;
+               memmove(buf->c_addr, u_ospcl.s_ospcl.c_fill, (long)256);
+       }
+       else if (u_ospcl.s_ospcl.c_magic == FS_UFS2_MAGIC) {
+               buf->c_date = (int32_t)(*(int64_t *)&u_ospcl.dummy[896]);
+               buf->c_ddate = (int32_t)(*(int64_t *)&u_ospcl.dummy[904]);
+               buf->c_tapea = (int32_t)(*(int64_t *)&u_ospcl.dummy[912]);
+               buf->c_firstrec = (int32_t)(*(int64_t *)&u_ospcl.dummy[920]);
+               buf->c_ntrec = 0;
+               buf->c_extattributes = 0;
+               buf->c_flags |= DR_NEWINODEFMT;
+               ufs2flag = 1;
+       }
+       else
                return(FAIL);
        buf->c_magic = NFS_MAGIC;