/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright (c) 1991, 1999 by Sun Microsystems, Inc. * All rights reserved. */ #ident "%Z%%M% %I% %E% SMI" /* SunOS */ #include #include #include #include #include #include #include #include #include #include #include "snoop.h" #include "snoop_nfs.h" #include #include #include #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif extern jmp_buf xdr_err; static void nfscall3(int); static void nfsreply3(int); static char *perms(int); static char *filetype(int); static char *sum_access(void); static char *sum_readdirres(void); static char *sum_readdirplusres(void); static char *sum_createhow(void); static char *sum_stablehow(void); static void detail_sattr3(void); static void detail_diropargs3(void); static void detail_readdirres(void); static void detail_readdirplusres(void); static void detail_fattr3(void); static void detail_access(void); static void detail_mode(int); static void detail_wcc_attr(void); static void detail_pre_op_attr(char *); static void detail_wcc_data(char *); static void skip_postop(void); static void skip_wcc_data(void); static void skip_sattr3(void); #define DONT_CHANGE 0 #define SET_TO_SERVER_TIME 1 #define SET_TO_CLIENT_TIME 2 #define UNCHECKED 0 #define GUARDED 1 #define EXCLUSIVE 2 #define ACCESS3_READ 0x0001 #define ACCESS3_LOOKUP 0x0002 #define ACCESS3_MODIFY 0x0004 #define ACCESS3_EXTEND 0x0008 #define ACCESS3_DELETE 0x0010 #define ACCESS3_EXECUTE 0x0020 #define UNSTABLE 0 #define DATA_SYNC 1 #define FILE_SYNC 2 #define NF3REG 1 /* regular file */ #define NF3DIR 2 /* directory */ #define NF3BLK 3 /* block special */ #define NF3CHR 4 /* character special */ #define NF3LNK 5 /* symbolic link */ #define NF3SOCK 6 /* unix domain socket */ #define NF3FIFO 7 /* named pipe */ #define NFS3_FHSIZE 64 static char *procnames_short[] = { "NULL3", /* 0 */ "GETATTR3", /* 1 */ "SETATTR3", /* 2 */ "LOOKUP3", /* 3 */ "ACCESS3", /* 4 */ "READLINK3", /* 5 */ "READ3", /* 6 */ "WRITE3", /* 7 */ "CREATE3", /* 8 */ "MKDIR3", /* 9 */ "SYMLINK3", /* 10 */ "MKNOD3", /* 11 */ "REMOVE3", /* 12 */ "RMDIR3", /* 13 */ "RENAME3", /* 14 */ "LINK3", /* 15 */ "READDIR3", /* 16 */ "READDIRPLUS3", /* 17 */ "FSSTAT3", /* 18 */ "FSINFO3", /* 19 */ "PATHCONF3", /* 20 */ "COMMIT3", /* 21 */ }; static char *procnames_long[] = { "Null procedure", /* 0 */ "Get file attributes", /* 1 */ "Set file attributes", /* 2 */ "Look up file name", /* 3 */ "Check access permission", /* 4 */ "Read from symbolic link", /* 5 */ "Read from file", /* 6 */ "Write to file", /* 7 */ "Create file", /* 8 */ "Make directory", /* 9 */ "Make symbolic link", /* 10 */ "Make special file", /* 11 */ "Remove file", /* 12 */ "Remove directory", /* 13 */ "Rename", /* 14 */ "Link", /* 15 */ "Read from directory", /* 16 */ "Read from directory - plus", /* 17 */ "Get filesystem statistics", /* 18 */ "Get filesystem information", /* 19 */ "Get POSIX information", /* 20 */ "Commit to stable storage", /* 21 */ }; #define MAXPROC 21 void interpret_nfs3(flags, type, xid, vers, proc, data, len) int flags, type, xid, vers, proc; char *data; int len; { char *line; char buff[NFS_MAXPATHLEN + 1]; /* protocol allows longer */ u_longlong_t off; int sz, how; char *fh, *name; if (proc < 0 || proc > MAXPROC) return; if (flags & F_SUM) { line = get_sum_line(); if (type == CALL) { (void) sprintf(line, "NFS C %s", procnames_short[proc]); line += strlen(line); switch (proc) { case NFSPROC3_GETATTR: case NFSPROC3_READLINK: case NFSPROC3_FSSTAT: case NFSPROC3_FSINFO: case NFSPROC3_PATHCONF: (void) sprintf(line, sum_nfsfh3()); break; case NFSPROC3_SETATTR: (void) sprintf(line, sum_nfsfh3()); break; case NFSPROC3_READDIR: fh = sum_nfsfh3(); off = getxdr_u_longlong(); (void) getxdr_u_longlong(); sz = getxdr_u_long(); (void) sprintf(line, "%s Cookie=%llu for %lu", fh, off, sz); break; case NFSPROC3_READDIRPLUS: fh = sum_nfsfh3(); off = getxdr_u_longlong(); (void) getxdr_u_longlong(); sz = getxdr_u_long(); (void) sprintf(line, "%s Cookie=%llu for %lu/%lu", fh, off, sz, getxdr_u_long()); break; case NFSPROC3_ACCESS: fh = sum_nfsfh3(); (void) sprintf(line, "%s (%s)", fh, sum_access()); break; case NFSPROC3_LOOKUP: case NFSPROC3_REMOVE: case NFSPROC3_RMDIR: case NFSPROC3_MKDIR: fh = sum_nfsfh3(); (void) sprintf(line, "%s %s", fh, getxdr_string(buff, NFS_MAXPATHLEN)); break; case NFSPROC3_CREATE: fh = sum_nfsfh3(); name = getxdr_string(buff, NFS_MAXPATHLEN); (void) sprintf(line, "%s (%s) %s", fh, sum_createhow(), name); break; case NFSPROC3_MKNOD: fh = sum_nfsfh3(); name = getxdr_string(buff, NFS_MAXPATHLEN); how = getxdr_long(); (void) sprintf(line, "%s (%s) %s", fh, filetype(how), name); break; case NFSPROC3_READ: fh = sum_nfsfh3(); off = getxdr_u_longlong(); sz = getxdr_u_long(); (void) sprintf(line, "%s at %llu for %lu", fh, off, sz); break; case NFSPROC3_WRITE: fh = sum_nfsfh3(); off = getxdr_u_longlong(); sz = getxdr_u_long(); (void) sprintf(line, "%s at %llu for %lu (%s)", fh, off, sz, sum_stablehow()); break; case NFSPROC3_SYMLINK: fh = sum_nfsfh3(); (void) sprintf(line, "%s %s", fh, getxdr_string(buff, NFS_MAXPATHLEN)); skip_sattr3(); line += strlen(line); (void) sprintf(line, " to %s", getxdr_string(buff, NFS_MAXPATHLEN)); break; case NFSPROC3_RENAME: fh = sum_nfsfh3(); (void) sprintf(line, "%s %s", fh, getxdr_string(buff, NFS_MAXPATHLEN)); line += strlen(line); fh = sum_nfsfh3(); (void) sprintf(line, " to%s %s", fh, getxdr_string(buff, NFS_MAXPATHLEN)); break; case NFSPROC3_LINK: fh = sum_nfsfh3(); (void) sprintf(line, "%s", fh); line += strlen(line); fh = sum_nfsfh3(); (void) sprintf(line, " to%s %s", fh, getxdr_string(buff, NFS_MAXPATHLEN)); break; case NFSPROC3_COMMIT: fh = sum_nfsfh3(); off = getxdr_u_longlong(); sz = getxdr_u_long(); (void) sprintf(line, "%s at %llu for %lu", fh, off, sz); break; default: break; } check_retransmit(line, xid); } else { (void) sprintf(line, "NFS R %s ", procnames_short[proc]); line += strlen(line); switch (proc) { case NFSPROC3_LOOKUP: if (sum_nfsstat3(line) == NFS3_OK) (void) strcat(line, sum_nfsfh3()); break; case NFSPROC3_CREATE: case NFSPROC3_MKDIR: case NFSPROC3_SYMLINK: case NFSPROC3_MKNOD: if (sum_nfsstat3(line) == NFS3_OK) { if (getxdr_bool()) (void) strcat(line, sum_nfsfh3()); } break; case NFSPROC3_READLINK: if (sum_nfsstat3(line) == NFS3_OK) { line += strlen(line); skip_postop(); (void) sprintf(line, " (Path=%s)", getxdr_string(buff, NFS_MAXPATHLEN)); } break; case NFSPROC3_GETATTR: case NFSPROC3_SETATTR: case NFSPROC3_REMOVE: case NFSPROC3_RMDIR: case NFSPROC3_RENAME: case NFSPROC3_LINK: case NFSPROC3_FSSTAT: case NFSPROC3_FSINFO: case NFSPROC3_PATHCONF: (void) sum_nfsstat3(line); break; case NFSPROC3_ACCESS: if (sum_nfsstat3(line) == NFS3_OK) { line += strlen(line); skip_postop(); (void) sprintf(line, " (%s)", sum_access()); } break; case NFSPROC3_WRITE: if (sum_nfsstat3(line) == NFS3_OK) { line += strlen(line); skip_wcc_data(); sz = getxdr_u_long(); (void) sprintf(line, " %d (%s)", sz, sum_stablehow()); } break; case NFSPROC3_READDIR: if (sum_nfsstat3(line) == NFS3_OK) (void) strcat(line, sum_readdirres()); break; case NFSPROC3_READ: if (sum_nfsstat3(line) == NFS3_OK) { line += strlen(line); skip_postop(); (void) sprintf(line, " (%lu bytes)", getxdr_u_long()); if (getxdr_bool()) (void) strcat(line, " EOF"); } break; case NFSPROC3_READDIRPLUS: if (sum_nfsstat3(line) == NFS3_OK) (void) strcat(line, sum_readdirplusres()); break; case NFSPROC3_COMMIT: (void) sum_nfsstat3(line); break; default: break; } } } if (flags & F_DTAIL) { show_header("NFS: ", "Sun NFS", len); show_space(); (void) sprintf(get_line(0, 0), "Proc = %d (%s)", proc, procnames_long[proc]); if (type == CALL) nfscall3(proc); else nfsreply3(proc); show_trailer(); } } /* * Print out version 3 NFS call packets */ static void nfscall3(proc) int proc; { int h; switch (proc) { case NFSPROC3_GETATTR: case NFSPROC3_READLINK: case NFSPROC3_FSINFO: case NFSPROC3_FSSTAT: case NFSPROC3_PATHCONF: detail_nfsfh3(); break; case NFSPROC3_SETATTR: detail_nfsfh3(); detail_sattr3(); if (getxdr_bool()) (void) showxdr_date_ns("Guard = %s"); break; case NFSPROC3_LOOKUP: case NFSPROC3_REMOVE: case NFSPROC3_RMDIR: detail_diropargs3(); break; case NFSPROC3_ACCESS: detail_nfsfh3(); detail_access(); break; case NFSPROC3_MKDIR: detail_diropargs3(); detail_sattr3(); break; case NFSPROC3_CREATE: detail_diropargs3(); h = getxdr_u_long(); if (h == EXCLUSIVE) showxdr_hex(8, "Guard = %s"); else { (void) sprintf(get_line(0, 0), "Method = %s", h == UNCHECKED ? "Unchecked" : "Guarded"); detail_sattr3(); } break; case NFSPROC3_MKNOD: detail_diropargs3(); h = getxdr_u_long(); (void) sprintf(get_line(0, 0), "File type = %s", filetype(h)); switch (h) { case NF3CHR: case NF3BLK: detail_sattr3(); showxdr_u_long("Major = %lu"); showxdr_u_long("Minor = %lu"); break; case NF3SOCK: case NF3FIFO: detail_sattr3(); break; } break; case NFSPROC3_WRITE: detail_nfsfh3(); (void) showxdr_u_longlong("Offset = %llu"); (void) showxdr_u_long("Size = %lu"); (void) sprintf(get_line(0, 0), "Stable = %s", sum_stablehow()); break; case NFSPROC3_RENAME: detail_diropargs3(); detail_diropargs3(); break; case NFSPROC3_LINK: detail_nfsfh3(); detail_diropargs3(); break; case NFSPROC3_SYMLINK: detail_diropargs3(); detail_sattr3(); (void) showxdr_string(MAXPATHLEN, "Path = %s"); break; case NFSPROC3_READDIR: detail_nfsfh3(); (void) showxdr_u_longlong("Cookie = %llu"); (void) showxdr_hex(8, "Verifier = %s"); (void) showxdr_u_long("Count = %lu"); break; case NFSPROC3_READDIRPLUS: detail_nfsfh3(); (void) showxdr_u_longlong("Cookie = %llu"); (void) showxdr_hex(8, "Verifier = %s"); (void) showxdr_u_long("Dircount = %lu"); (void) showxdr_u_long("Maxcount = %lu"); break; case NFSPROC3_READ: case NFSPROC3_COMMIT: detail_nfsfh3(); (void) showxdr_u_longlong("Offset = %llu"); (void) showxdr_long("Count = %lu"); break; default: break; } } /* * Print out version 3 NFS reply packets */ static void nfsreply3(proc) int proc; { int bits; switch (proc) { case NFSPROC3_GETATTR: if (detail_nfsstat3() == NFS3_OK) { detail_fattr3(); } break; case NFSPROC3_SETATTR: (void) detail_nfsstat3(); detail_wcc_data(""); break; case NFSPROC3_WRITE: if (detail_nfsstat3() == NFS3_OK) { detail_wcc_data(""); (void) showxdr_u_long("Count = %lu bytes written"); (void) sprintf(get_line(0, 0), "Stable = %s", sum_stablehow()); (void) showxdr_hex(8, "Verifier = %s"); } else detail_wcc_data(""); break; case NFSPROC3_LOOKUP: if (detail_nfsstat3() == NFS3_OK) { detail_nfsfh3(); detail_post_op_attr("(object)"); } detail_post_op_attr("(directory)"); break; case NFSPROC3_CREATE: case NFSPROC3_MKDIR: case NFSPROC3_SYMLINK: case NFSPROC3_MKNOD: if (detail_nfsstat3() == NFS3_OK) { if (getxdr_bool()) detail_nfsfh3(); else (void) sprintf(get_line(0, 0), "(No file handle available)"); detail_post_op_attr(""); } detail_wcc_data(""); break; case NFSPROC3_READLINK: if (detail_nfsstat3() == NFS3_OK) { detail_post_op_attr(""); (void) showxdr_string(MAXPATHLEN, "Path = %s"); } else detail_post_op_attr(""); break; case NFSPROC3_READ: if (detail_nfsstat3() == NFS3_OK) { detail_post_op_attr(""); (void) showxdr_u_long("Count = %lu bytes read"); (void) showxdr_bool("End of file = %s"); } else detail_post_op_attr(""); break; case NFSPROC3_ACCESS: if (detail_nfsstat3() == NFS3_OK) { detail_post_op_attr(""); (void) sprintf(get_line(0, 0), "Access = %s", sum_access()); } else detail_post_op_attr(""); break; case NFSPROC3_REMOVE: case NFSPROC3_RMDIR: (void) detail_nfsstat3(); detail_wcc_data(""); break; case NFSPROC3_RENAME: (void) detail_nfsstat3(); detail_wcc_data("(from directory)"); detail_wcc_data("(to directory)"); break; case NFSPROC3_LINK: (void) detail_nfsstat3(); detail_post_op_attr(""); detail_wcc_data(""); break; case NFSPROC3_READDIR: if (detail_nfsstat3() == NFS3_OK) { detail_readdirres(); } else detail_post_op_attr(""); break; case NFSPROC3_READDIRPLUS: if (detail_nfsstat3() == NFS3_OK) { detail_readdirplusres(); } else detail_post_op_attr(""); break; case NFSPROC3_FSSTAT: if (detail_nfsstat3() == NFS3_OK) { detail_post_op_attr(""); (void) showxdr_u_longlong( "Total space = %llu bytes"); (void) showxdr_u_longlong( "Available space = %llu bytes"); (void) showxdr_u_longlong( "Available space - this user = %llu bytes"); (void) showxdr_u_longlong( "Total file slots = %llu"); (void) showxdr_u_longlong( "Available file slots = %llu"); (void) showxdr_u_longlong( "Available file slots - this user = %llu"); (void) showxdr_u_long("Invariant time = %lu sec"); } else detail_post_op_attr(""); break; case NFSPROC3_FSINFO: if (detail_nfsstat3() == NFS3_OK) { detail_post_op_attr(""); (void) show_line("Read transfer sizes:"); (void) showxdr_u_long(" Maximum = %lu bytes"); (void) showxdr_u_long(" Preferred = %lu bytes"); (void) showxdr_u_long( " Suggested multiple = %lu bytes"); (void) show_line("Write transfer sizes:"); (void) showxdr_u_long(" Maximum = %lu bytes"); (void) showxdr_u_long(" Preferred = %lu bytes"); (void) showxdr_u_long( " Suggested multiple = %lu bytes"); (void) show_line("Directory read size:"); (void) showxdr_u_long(" Preferred = %lu bytes"); (void) show_line("File system limits:"); (void) showxdr_u_longlong( " Max file size = %llu bytes"); (void) showxdr_date_ns( " Server minimum time discrimination = %s sec"); bits = showxdr_u_long("Properties = 0x%02x"); (void) sprintf(get_line(0, 0), " %s", getflag(bits, FSF3_LINK, "Hard links supported", "(hard links not supported)")); (void) sprintf(get_line(0, 0), " %s", getflag(bits, FSF3_SYMLINK, "Symbolic links supported", "(symbolic links not supported)")); (void) sprintf(get_line(0, 0), " %s", getflag(bits, FSF3_HOMOGENEOUS, "Pathconf cannot vary per file", "(pathconf can vary per file)")); (void) sprintf(get_line(0, 0), " %s", getflag(bits, FSF3_CANSETTIME, "Server can always set file times", "(server cannot always set file times)")); } else detail_post_op_attr(""); break; case NFSPROC3_PATHCONF: if (detail_nfsstat3() == NFS3_OK) { detail_post_op_attr(""); (void) showxdr_u_long("Link max = %lu"); (void) showxdr_u_long("Name max = %lu"); (void) showxdr_bool("No trunc = %s"); (void) showxdr_bool("Chown restricted = %s"); (void) showxdr_bool("Case insensitive = %s"); (void) showxdr_bool("Case preserving = %s"); } else detail_post_op_attr(""); break; case NFSPROC3_COMMIT: if (detail_nfsstat3() == NFS3_OK) { detail_wcc_data(""); (void) showxdr_hex(8, "Verifier = %s"); } else detail_wcc_data(""); break; default: break; } } static void detail_diropargs3() { detail_nfsfh3(); (void) showxdr_string(MAXPATHLEN, "File name = %s"); } int sum_nfsstat3(line) char *line; { ulong_t status; char *p; status = getxdr_long(); switch (status) { case NFS3_OK: p = "OK"; break; case NFS3ERR_PERM: p = "Not owner"; break; case NFS3ERR_NOENT: p = "No such file or directory"; break; case NFS3ERR_IO: p = "I/O error"; break; case NFS3ERR_NXIO: p = "No such device or address"; break; case NFS3ERR_ACCES: p = "Permission denied"; break; case NFS3ERR_EXIST: p = "File exists"; break; case NFS3ERR_XDEV: p = "Attempted cross-device link"; break; case NFS3ERR_NODEV: p = "No such device"; break; case NFS3ERR_NOTDIR: p = "Not a directory"; break; case NFS3ERR_ISDIR: p = "Is a directory"; break; case NFS3ERR_INVAL: p = "Invalid argument"; break; case NFS3ERR_FBIG: p = "File too large"; break; case NFS3ERR_NOSPC: p = "No space left on device"; break; case NFS3ERR_ROFS: p = "Read-only file system"; break; case NFS3ERR_MLINK: p = "Too many links"; break; case NFS3ERR_NAMETOOLONG:p = "File name too long"; break; case NFS3ERR_NOTEMPTY: p = "Directory not empty"; break; case NFS3ERR_DQUOT: p = "Disc quota exceeded"; break; case NFS3ERR_STALE: p = "Stale NFS file handle"; break; case NFS3ERR_REMOTE: p = "Too many levels of remote in path"; break; case NFS3ERR_BADHANDLE: p = "Illegal NFS file handle"; break; case NFS3ERR_NOT_SYNC: p = "Update synch mismatch"; break; case NFS3ERR_BAD_COOKIE:p = "Readdir cookie is stale"; break; case NFS3ERR_NOTSUPP: p = "Operation not supported"; break; case NFS3ERR_TOOSMALL: p = "Buffer/request too small"; break; case NFS3ERR_SERVERFAULT:p = "Server fault"; break; case NFS3ERR_BADTYPE: p = "Bad type"; break; case NFS3ERR_JUKEBOX: p = "File is temporarily unavailable"; break; default: p = "(unknown error)"; break; } (void) strcpy(line, p); return (status); } int detail_nfsstat3() { ulong_t status; char buff[64]; int pos; pos = getxdr_pos(); status = sum_nfsstat3(buff); (void) sprintf(get_line(pos, getxdr_pos()), "Status = %d (%s)", status, buff); return ((int)status); } static void skip_postop() { if (getxdr_bool()) xdr_skip(21 * 4); /* XDR size of fattr3 */ } static void skip_wcc_data() { if (getxdr_bool() > 0) xdr_skip(3 * 8); skip_postop(); } static void skip_sattr3() { if (getxdr_bool() > 0) xdr_skip(4); /* mode */ if (getxdr_bool() > 0) xdr_skip(4); /* uid */ if (getxdr_bool() > 0) xdr_skip(4); /* gid */ if (getxdr_bool() > 0) xdr_skip(8); /* size */ if (getxdr_bool() > 0) xdr_skip(8); /* atime */ if (getxdr_bool() > 0) xdr_skip(8); /* mtime */ } char * sum_nfsfh3() { int len; int fh; static char buff[16]; len = getxdr_long(); fh = sum_filehandle(len); (void) sprintf(buff, " FH=%04X", fh & 0xFFFF); return (buff); } void detail_nfsfh3() { int pos; int i, l, len; int fh; len = getxdr_long(); pos = getxdr_pos(); fh = sum_filehandle(len); setxdr_pos(pos); (void) sprintf(get_line(0, 0), "File handle = [%04X]", fh & 0xFFFF); i = 0; while (i < len) { l = MIN(len - i, 32); (void) showxdr_hex(l, " %s"); i += l; } } static char * sum_access() { int bits; static char buff[64]; bits = getxdr_u_long(); buff[0] = '\0'; if (bits & ACCESS3_READ) (void) strcat(buff, "read,"); if (bits & ACCESS3_LOOKUP) (void) strcat(buff, "lookup,"); if (bits & ACCESS3_MODIFY) (void) strcat(buff, "modify,"); if (bits & ACCESS3_EXTEND) (void) strcat(buff, "extend,"); if (bits & ACCESS3_DELETE) (void) strcat(buff, "delete,"); if (bits & ACCESS3_EXECUTE) (void) strcat(buff, "execute,"); if (buff[0] != '\0') buff[strlen(buff) - 1] = '\0'; return (buff); } static void detail_access() { uint_t bits; bits = showxdr_u_long("Access bits = 0x%08x"); (void) sprintf(get_line(0, 0), " %s", getflag(bits, ACCESS3_READ, "Read", "(no read)")); (void) sprintf(get_line(0, 0), " %s", getflag(bits, ACCESS3_LOOKUP, "Lookup", "(no lookup)")); (void) sprintf(get_line(0, 0), " %s", getflag(bits, ACCESS3_MODIFY, "Modify", "(no modify)")); (void) sprintf(get_line(0, 0), " %s", getflag(bits, ACCESS3_EXTEND, "Extend", "(no extend)")); (void) sprintf(get_line(0, 0), " %s", getflag(bits, ACCESS3_DELETE, "Delete", "(no delete)")); (void) sprintf(get_line(0, 0), " %s", getflag(bits, ACCESS3_EXECUTE, "Execute", "(no execute)")); } static void detail_mode(mode) int mode; { (void) sprintf(get_line(0, 0), " Mode = 0%o", mode); (void) sprintf(get_line(0, 0), " Setuid = %d, Setgid = %d, Sticky = %d", (mode & S_ISUID) != 0, (mode & S_ISGID) != 0, (mode & S_ISVTX) != 0); (void) sprintf(get_line(0, 0), " Owner's permissions = %s", perms(mode >> 6 & 0x7)); (void) sprintf(get_line(0, 0), " Group's permissions = %s", perms(mode >> 3 & 0x7)); (void) sprintf(get_line(0, 0), " Other's permissions = %s", perms(mode & 0x7)); } static void detail_fattr3() { uint_t fltype, mode, nlinks, uid, gid; uint_t major, minor; u_longlong_t size, used, fsid, fileid; fltype = getxdr_u_long(); mode = getxdr_u_long(); nlinks = getxdr_u_long(); uid = getxdr_u_long(); gid = getxdr_u_long(); size = getxdr_u_longlong(); used = getxdr_u_longlong(); major = getxdr_u_long(); minor = getxdr_u_long(); fsid = getxdr_u_longlong(); fileid = getxdr_u_longlong(); (void) sprintf(get_line(0, 0), " File type = %d (%s)", fltype, filetype(fltype)); detail_mode(mode); (void) sprintf(get_line(0, 0), " Link count = %u, User ID = %u, Group ID = %u", nlinks, uid, gid); (void) sprintf(get_line(0, 0), " File size = %llu, Used = %llu", size, used); (void) sprintf(get_line(0, 0), " Special: Major = %u, Minor = %u", major, minor); (void) sprintf(get_line(0, 0), " File system id = %llu, File id = %llu", fsid, fileid); (void) showxdr_date_ns(" Last access time = %s"); (void) showxdr_date_ns(" Modification time = %s"); (void) showxdr_date_ns(" Attribute change time = %s"); (void) show_line(""); } static void detail_sattr3() { int t; if (getxdr_bool()) detail_mode(getxdr_u_long()); else (void) sprintf(get_line(0, 0), "Mode = (not set)"); if (getxdr_bool()) (void) showxdr_long("User ID = %d"); else (void) sprintf(get_line(0, 0), "User ID = (not set)"); if (getxdr_bool()) (void) showxdr_long("Group ID = %d"); else (void) sprintf(get_line(0, 0), "Group ID = (not set)"); if (getxdr_bool()) (void) showxdr_u_longlong("Size = %llu"); else (void) sprintf(get_line(0, 0), "Size = (not set)"); if ((t = getxdr_u_long()) == SET_TO_CLIENT_TIME) (void) showxdr_date("Access time = %s (set to client time)"); else if (t == SET_TO_SERVER_TIME) (void) sprintf(get_line(0, 0), "Access time = (set to server time)"); else (void) sprintf(get_line(0, 0), "Access time = (do not set)"); if ((t = getxdr_u_long()) == SET_TO_CLIENT_TIME) { (void) showxdr_date( "Modification time = %s (set to client time)"); } else if (t == SET_TO_SERVER_TIME) (void) sprintf(get_line(0, 0), "Modification time = (set to server time)"); else (void) sprintf(get_line(0, 0), "Modification time = (do not set)"); (void) show_line(""); } static char * filetype(n) int n; { switch (n) { case NF3REG: return ("Regular File"); case NF3DIR: return ("Directory"); case NF3BLK: return ("Block special"); case NF3CHR: return ("Character special"); case NF3LNK: return ("Symbolic Link"); case NF3SOCK: return ("Unix domain socket"); case NF3FIFO: return ("Named pipe"); default: return ("?"); } /* NOTREACHED */ } static char * perms(n) int n; { static char buff[4]; buff[0] = n & 4 ? 'r' : '-'; buff[1] = n & 2 ? 'w' : '-'; buff[2] = n & 1 ? 'x' : '-'; buff[3] = '\0'; return (buff); } static void detail_wcc_attr() { (void) showxdr_u_longlong(" Size = %llu bytes"); (void) showxdr_date_ns(" Modification time = %s"); (void) showxdr_date_ns(" Attribute change time = %s"); (void) show_line(""); } static void detail_pre_op_attr(str) char *str; { if (getxdr_bool()) { (void) sprintf(get_line(0, 0), "Pre-operation attributes: %s", str); detail_wcc_attr(); } else (void) sprintf(get_line(0, 0), "Pre-operation attributes: %s (not available)", str); } void detail_post_op_attr(str) char *str; { if (getxdr_bool()) { (void) sprintf(get_line(0, 0), "Post-operation attributes: %s", str); detail_fattr3(); } else (void) sprintf(get_line(0, 0), "Post-operation attributes: %s (not available)", str); } static void detail_wcc_data(str) char *str; { detail_pre_op_attr(str); detail_post_op_attr(str); } static char * sum_readdirres() { static char buff[NFS_MAXNAMLEN + 1]; /* protocol allows longer names */ static int entries; entries = 0; if (setjmp(xdr_err)) { (void) sprintf(buff, " %d+ entries (incomplete)", entries); return (buff); } skip_postop(); xdr_skip(8); /* cookieverf */ while (getxdr_bool()) { entries++; xdr_skip(8); /* fileid */ (void) getxdr_string(buff, NFS_MAXNAMLEN); /* name */ xdr_skip(8); /* cookie */ } (void) sprintf(buff, " %d entries (%s)", entries, getxdr_bool() ? "No more" : "More"); return (buff); } static char * sum_readdirplusres() { static char buff[NFS_MAXNAMLEN + 1]; /* protocol allows longer */ static int entries; int skip; entries = 0; if (setjmp(xdr_err)) { (void) sprintf(buff, " %d+ entries (incomplete)", entries); return (buff); } skip_postop(); xdr_skip(8); /* cookieverf */ while (getxdr_bool()) { entries++; xdr_skip(8); /* fileid */ (void) getxdr_string(buff, NFS_MAXNAMLEN); /* name */ xdr_skip(8); /* cookie */ skip_postop(); /* post-op */ if (getxdr_bool()) { skip = getxdr_long(); xdr_skip(RNDUP(skip)); /* fhandle */ } } (void) sprintf(buff, " %d entries (%s)", entries, getxdr_bool() ? "No more" : "More"); return (buff); } static void detail_readdirres() { static int entries; u_longlong_t fileid, cookie; char *name; char buff[NFS_MAXNAMLEN + 1]; /* protocol allows longer names */ entries = 0; detail_post_op_attr(""); (void) showxdr_hex(8, "Cookie verifier = %s"); (void) show_line(""); (void) sprintf(get_line(0, 0), " File id Cookie Name"); if (setjmp(xdr_err)) { (void) sprintf(get_line(0, 0), " %d+ entries. (Frame is incomplete)", entries); return; } while (getxdr_bool()) { entries++; fileid = getxdr_u_longlong(); name = (char *)getxdr_string(buff, NFS_MAXNAMLEN); cookie = getxdr_u_longlong(); (void) sprintf(get_line(0, 0), " %10llu %10llu %s", fileid, cookie, name); } (void) sprintf(get_line(0, 0), " %d entries", entries); (void) showxdr_bool("EOF = %s"); } static void detail_readdirplusres() { static int entries; entries = 0; detail_post_op_attr(""); (void) showxdr_hex(8, "Cookie verifier = %s"); (void) show_line(""); if (setjmp(xdr_err)) { (void) sprintf(get_line(0, 0), " %d+ entries. (Frame is incomplete)", entries); return; } while (getxdr_bool()) { entries++; (void) sprintf(get_line(0, 0), "------------------ entry #%d", entries); (void) showxdr_u_longlong("File ID = %llu"); (void) showxdr_string(NFS_MAXNAMLEN, "Name = %s"); (void) showxdr_u_longlong("Cookie = %llu"); detail_post_op_attr(""); if (getxdr_bool()) detail_nfsfh3(); else (void) sprintf(get_line(0, 0), "(No file handle available)"); } (void) show_line(""); (void) sprintf(get_line(0, 0), " %d entries", entries); (void) showxdr_bool("EOF = %s"); } static char * sum_createhow() { long how; how = getxdr_long(); switch (how) { case UNCHECKED: return ("UNCHECKED"); case GUARDED: return ("GUARDED"); case EXCLUSIVE: return ("EXCLUSIVE"); default: return ("?"); } /* NOTREACHED */ } static char * sum_stablehow() { long stable; stable = getxdr_long(); switch (stable) { case UNSTABLE: return ("ASYNC"); case DATA_SYNC: return ("DSYNC"); case FILE_SYNC: return ("FSYNC"); default: return ("?"); } /* NOTREACHED */ }