1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 24 */ 25 26 /* 27 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 #include <ctype.h> 32 #include <string.h> 33 #include <strings.h> 34 #include <stdlib.h> 35 #include <sys/types.h> 36 #include <sys/errno.h> 37 #include <sys/tiuser.h> 38 #include <setjmp.h> 39 40 #include <rpc/types.h> 41 #include <rpc/xdr.h> 42 #include <rpc/auth.h> 43 #include <rpc/clnt.h> 44 #include <rpc/rpc_msg.h> 45 #include "snoop.h" 46 47 #include <sys/stat.h> 48 #include <sys/param.h> 49 #include <sys/sysmacros.h> 50 #include <rpcsvc/nfs_prot.h> 51 /* use the same nfs4_prot.h as the xdr code */ 52 #include "rpcsvc/nfs4_prot.h" 53 54 /* 55 * XXX With NFS v2 and v3, we only need to xdr the pieces that we care 56 * about. Anything else we can ignore and just skip to the next packet. 57 * So all the stuff that deals directly with XDR lives in snoop_display.c 58 * With v4, we need to XDR entire structures so that we can skip over 59 * uninteresting bits in a compound array, so we call XDR directly from 60 * here. We need to rethink how we're going to structure XDR access. Do 61 * we continue to hide it all in snoop_display.c, or do we expose it to all 62 * the protocol modules? 63 */ 64 extern XDR xdrm; 65 66 #ifndef MIN 67 #define MIN(a, b) ((a) < (b) ? (a) : (b)) 68 #endif 69 70 /* 71 * Maximum number of characters to display in compound4 summary line. 72 */ 73 #define SUM_COMPND_MAX 100 74 75 /* 76 * Maximum number of recognized attributes. 77 */ 78 #define MAX_ATTRIBUTES 56 79 80 /* 81 * This data structure provides a more convenient way to access an 82 * attribute bitmask. map[N] = value of bit N in a bitmap4. 83 * It's defined as a struct so as to step around all the weird rules in C 84 * about arrays, pointers, passing them as arguments, etc. 85 */ 86 87 typedef struct { 88 char map[MAX_ATTRIBUTES]; 89 } unpkd_attrmap_t; 90 91 92 static void sumarg_cb_getattr(char *buf, size_t buflen, void *obj); 93 static void dtlarg_cb_getattr(void *obj); 94 static void sumarg_cb_recall(char *buf, size_t buflen, void *obj); 95 static void dtlarg_cb_recall(void *obj); 96 97 98 static void sumarg_access(char *buf, size_t buflen, void *obj); 99 static void dtlarg_access(void *obj); 100 static void sumarg_close(char *buf, size_t buflen, void *obj); 101 static void dtlarg_close(void *obj); 102 static void sumarg_commit(char *buf, size_t buflen, void *obj); 103 static void dtlarg_commit(void *obj); 104 static void sumarg_compnt(char *buf, size_t buflen, void *obj); 105 static void dtlarg_compnt(void *obj); 106 static void sumarg_create(char *buf, size_t buflen, void *obj); 107 static void dtlarg_create(void *obj); 108 static void sumarg_delprge(char *buf, size_t buflen, void *obj); 109 static void dtlarg_delprge(void *obj); 110 static void sumarg_delret(char *buf, size_t buflen, void *obj); 111 static void dtlarg_delret(void *obj); 112 static void sumarg_getattr(char *buf, size_t buflen, void *obj); 113 static void dtlarg_getattr(void *obj); 114 static void sumarg_link(char *buf, size_t buflen, void *obj); 115 static void dtlarg_link(void *obj); 116 static void sum_open_to_lock_owner(char *buf, int buflen, 117 open_to_lock_owner4 *own); 118 static void sum_exist_lock_owner(char *buf, int buflen, 119 exist_lock_owner4 *own); 120 static void sum_locker(char *buf, size_t buflen, locker4 *lk); 121 static void sumarg_lock(char *buf, size_t buflen, void *obj); 122 static void detail_open_to_lock_owner(open_to_lock_owner4 *own); 123 static void detail_exist_lock_owner(exist_lock_owner4 *own); 124 static void detail_locker(locker4 *lk); 125 static void dtlarg_lock(void *obj); 126 static void sumarg_lockt(char *buf, size_t buflen, void *obj); 127 static void dtlarg_lockt(void *obj); 128 static void sumarg_locku(char *buf, size_t buflen, void *obj); 129 static void dtlarg_locku(void *obj); 130 static void sumarg_lookup(char *buf, size_t buflen, void *obj); 131 static void dtlarg_lookup(void *obj); 132 static void sumarg_open(char *buf, size_t buflen, void *obj); 133 static void dtlarg_open(void *obj); 134 static void sumarg_openattr(char *buf, size_t buflen, void *obj); 135 static void dtlarg_openattr(void *obj); 136 static void sumarg_open_confirm(char *buf, size_t buflen, void *obj); 137 static void dtlarg_open_confirm(void *obj); 138 static void sumarg_open_downgrd(char *buf, size_t buflen, void *obj); 139 static void dtlarg_open_downgrd(void *obj); 140 static void sumarg_putfh(char *buf, size_t buflen, void *obj); 141 static void dtlarg_putfh(void *obj); 142 static void sumarg_read(char *buf, size_t buflen, void *obj); 143 static void dtlarg_read(void *obj); 144 static void sumarg_readdir(char *buf, size_t buflen, void *obj); 145 static void dtlarg_readdir(void *obj); 146 static void sumarg_release_lkown(char *buf, size_t buflen, void *obj); 147 static void dtlarg_release_lkown(void *obj); 148 static void sumarg_rename(char *buf, size_t buflen, void *obj); 149 static void dtlarg_rename(void *obj); 150 static void sumarg_renew(char *buf, size_t buflen, void *obj); 151 static void dtlarg_renew(void *buf); 152 static void sumarg_secinfo(char *buf, size_t buflen, void *obj); 153 static void dtlarg_secinfo(void *obj); 154 static void sumarg_setattr(char *buf, size_t buflen, void *obj); 155 static void dtlarg_setattr(void *obj); 156 static void sumarg_setclid(char *buf, size_t buflen, void *obj); 157 static void dtlarg_setclid(void *obj); 158 static void sumarg_setclid_cfm(char *buf, size_t buflen, void *obj); 159 static void dtlarg_setclid_cfm(void *obj); 160 static void dtlarg_verify(void *obj); 161 static void sumarg_write(char *buf, size_t buflen, void *obj); 162 static void dtlarg_write(void *obj); 163 164 static void sumres_cb_getattr(char *buf, size_t buflen, void *obj); 165 static void dtlres_cb_getattr(void *obj); 166 167 static void sumres_access(char *buf, size_t buflen, void *obj); 168 static void dtlres_access(void *obj); 169 static void sumres_close(char *buf, size_t buflen, void *obj); 170 static void dtlres_close(void *obj); 171 static void sumres_commit(char *buf, size_t buflen, void *obj); 172 static void dtlres_commit(void *obj); 173 static void dtlres_create(void *obj); 174 static void sumres_getattr(char *buf, size_t buflen, void *obj); 175 static void dtlres_getattr(void *obj); 176 static void sumres_getfh(char *buf, size_t buflen, void *obj); 177 static void dtlres_getfh(void *obj); 178 static void dtlres_link(void *obj); 179 static void sumres_lock(char *buf, size_t buflen, void *obj); 180 static void dtlres_lock(void *obj); 181 static void sumres_lockt(char *buf, size_t buflen, void *obj); 182 static void dtlres_lockt(void *obj); 183 static void sumres_locku(char *buf, size_t buflen, void *obj); 184 static void dtlres_locku(void *obj); 185 static void sumres_open(char *buf, size_t buflen, void *obj); 186 static void dtlres_open(void *obj); 187 static void sumres_open_confirm(char *buf, size_t buflen, void *obj); 188 static void dtlres_open_confirm(void *obj); 189 static void sumres_open_downgrd(char *buf, size_t buflen, void *obj); 190 static void dtlres_open_downgrd(void *obj); 191 static void sumres_read(char *buf, size_t buflen, void *obj); 192 static void dtlres_read(void *obj); 193 static void sumres_readdir(char *buf, size_t buflen, void *obj); 194 static void dtlres_readdir(void *obj); 195 static void sumres_readlnk(char *buf, size_t buflen, void *obj); 196 static void dtlres_readlnk(void *obj); 197 static void dtlres_remove(void *obj); 198 static void dtlres_rename(void *obj); 199 static void sumres_secinfo(char *buf, size_t buflen, void *obj); 200 static void dtlres_secinfo(void *obj); 201 static void sumres_setattr(char *buf, size_t buflen, void *obj); 202 static void dtlres_setattr(void *obj); 203 static void sumres_setclid(char *buf, size_t buflen, void *obj); 204 static void dtlres_setclid(void *obj); 205 static void sumres_write(char *buf, size_t buflen, void *obj); 206 static void dtlres_write(void *obj); 207 static void sum_nfsstat4(char *buf, size_t buflen, void *obj); 208 static void dtl_nfsstat4(void *obj); 209 static uint32_t adler16(void *, int); 210 static void nfs4_xdr_skip(int nbytes); 211 static char *sum_lock_type_name(enum nfs_lock_type4 type); 212 213 int nfs4_pkt_start; 214 int nfs4_pkt_len; 215 int nfs4_skip_bytes; 216 int nfs4_fragged_rpc; 217 char *nfs4err_fragrpc = "<Fragmented RPC>"; 218 char *nfs4err_xdrfrag = "<XDR Error or Fragmented RPC>"; 219 220 /* 221 * need a way to enable this if current testcases are parsing snoop 222 * error text. -- maybe an env var would do as temp workaround until 223 * testcases changed to grep for new error text. 224 */ 225 int nfs4_use_old_error_text = 0; 226 227 /* 228 * Information about each operation that can appear in a compound call. 229 * The function pointers are to formatting functions for summary arguments 230 * and results, and detail arguments & results. 231 */ 232 233 typedef struct { 234 char *name; 235 void (*sumarg)(char *, size_t, void *); 236 void (*sumres)(char *, size_t, void *); 237 void (*dtlarg)(void *); 238 void (*dtlres)(void *); 239 } op_info_t; 240 241 static op_info_t cb_opcode_info[] = { 242 {"OP_ZERO", NULL, NULL, NULL, NULL}, /* 0 */ 243 {"OP_ONE", NULL, NULL, NULL, NULL}, 244 {"OP_TWO", NULL, NULL, NULL, NULL}, /* minor vers */ 245 {"CB_GETATTR", 246 sumarg_cb_getattr, sumres_cb_getattr, 247 dtlarg_cb_getattr, dtlres_cb_getattr}, 248 {"CB_RECALL", 249 sumarg_cb_recall, sum_nfsstat4, 250 dtlarg_cb_recall, dtl_nfsstat4}, 251 }; 252 static uint_t cb_num_opcodes = ARRAY_SIZE(cb_opcode_info); 253 254 static op_info_t opcode_info[] = { 255 {"OP_ZERO", NULL, NULL, NULL, NULL}, /* 0 */ 256 {"OP_ONE", NULL, NULL, NULL, NULL}, 257 {"OP_TWO", NULL, NULL, NULL, NULL}, /* minor vers */ 258 {"ACCESS", 259 sumarg_access, sumres_access, dtlarg_access, dtlres_access}, 260 {"CLOSE", 261 sumarg_close, sumres_close, dtlarg_close, dtlres_close}, 262 {"COMMIT", 263 sumarg_commit, sumres_commit, dtlarg_commit, dtlres_commit}, 264 {"CREATE", /* 5 */ 265 sumarg_create, sum_nfsstat4, dtlarg_create, dtlres_create}, 266 {"DELEGPURGE", 267 sumarg_delprge, sum_nfsstat4, dtlarg_delprge, dtl_nfsstat4}, 268 {"DELEGRETURN", 269 sumarg_delret, sum_nfsstat4, dtlarg_delret, dtl_nfsstat4}, 270 {"GETATTR", 271 sumarg_getattr, sumres_getattr, dtlarg_getattr, dtlres_getattr}, 272 {"GETFH", 273 NULL, sumres_getfh, NULL, dtlres_getfh}, 274 {"LINK", /* 10 */ 275 sumarg_link, sum_nfsstat4, dtlarg_link, dtlres_link}, 276 {"LOCK", 277 sumarg_lock, sumres_lock, dtlarg_lock, dtlres_lock}, 278 {"LOCKT", 279 sumarg_lockt, sumres_lockt, dtlarg_lockt, dtlres_lockt}, 280 {"LOCKU", 281 sumarg_locku, sumres_locku, dtlarg_locku, dtlres_locku}, 282 {"LOOKUP", 283 sumarg_lookup, sum_nfsstat4, dtlarg_lookup, dtl_nfsstat4}, 284 {"LOOKUPP", /* 15 */ 285 NULL, sum_nfsstat4, NULL, dtl_nfsstat4}, 286 {"NVERIFY", 287 NULL, sum_nfsstat4, dtlarg_verify, dtl_nfsstat4}, 288 {"OPEN", 289 sumarg_open, sumres_open, dtlarg_open, dtlres_open}, 290 {"OPENATTR", 291 sumarg_openattr, sum_nfsstat4, dtlarg_openattr, dtl_nfsstat4}, 292 {"OPEN_CONFIRM", 293 sumarg_open_confirm, 294 sumres_open_confirm, 295 dtlarg_open_confirm, 296 dtlres_open_confirm}, 297 {"OPEN_DOWNGRADE", 298 sumarg_open_downgrd, 299 sumres_open_downgrd, 300 dtlarg_open_downgrd, 301 dtlres_open_downgrd}, 302 {"PUTFH", 303 sumarg_putfh, sum_nfsstat4, dtlarg_putfh, dtl_nfsstat4}, 304 {"PUTPUBFH", /* 20 */ 305 NULL, sum_nfsstat4, NULL, dtl_nfsstat4}, 306 {"PUTROOTFH", 307 NULL, sum_nfsstat4, NULL, dtl_nfsstat4}, 308 {"READ", 309 sumarg_read, sumres_read, dtlarg_read, dtlres_read}, 310 {"READDIR", 311 sumarg_readdir, sumres_readdir, dtlarg_readdir, dtlres_readdir}, 312 {"READLINK", 313 NULL, sumres_readlnk, NULL, dtlres_readlnk}, 314 {"REMOVE", /* 25 */ 315 sumarg_compnt, sum_nfsstat4, dtlarg_compnt, dtlres_remove}, 316 {"RENAME", 317 sumarg_rename, sum_nfsstat4, dtlarg_rename, dtlres_rename}, 318 {"RENEW", 319 sumarg_renew, sum_nfsstat4, dtlarg_renew, dtl_nfsstat4}, 320 {"RESTOREFH", 321 NULL, sum_nfsstat4, NULL, dtl_nfsstat4}, 322 {"SAVEFH", 323 NULL, sum_nfsstat4, NULL, dtl_nfsstat4}, 324 {"SECINFO", /* 30 */ 325 sumarg_secinfo, sumres_secinfo, dtlarg_secinfo, dtlres_secinfo}, 326 {"SETATTR", 327 sumarg_setattr, sumres_setattr, dtlarg_setattr, dtlres_setattr}, 328 {"SETCLIENTID", 329 sumarg_setclid, sumres_setclid, dtlarg_setclid, dtlres_setclid}, 330 {"SETCLIENTID_CONFIRM", 331 sumarg_setclid_cfm, 332 sum_nfsstat4, 333 dtlarg_setclid_cfm, 334 dtl_nfsstat4}, 335 {"VERIFY", 336 NULL, sum_nfsstat4, dtlarg_verify, dtl_nfsstat4}, 337 {"WRITE", 338 sumarg_write, sumres_write, dtlarg_write, dtlres_write}, 339 {"RELEASE_LOCKOWNER", 340 sumarg_release_lkown, sum_nfsstat4, 341 dtlarg_release_lkown, dtl_nfsstat4}, 342 }; 343 static uint_t num_opcodes = ARRAY_SIZE(opcode_info); 344 345 /* 346 * File types. 347 */ 348 349 typedef struct { 350 char *short_name; /* for summary output */ 351 char *long_name; /* for detail output */ 352 } ftype_names_t; 353 354 static ftype_names_t ftype_names[] = { 355 {"Type 0", "Type 0"}, 356 {"REG", "Regular File"}, 357 {"DIR", "Directory"}, 358 {"BLK", "Block Device"}, 359 {"CHR", "Character Device"}, 360 {"LNK", "Symbolic Link"}, /* 5 */ 361 {"SOCK", "Socket"}, 362 {"FIFO", "FIFO"}, 363 {"ATTRDIR", "Attribute Directory"}, 364 {"NAMEDATTR", "Named Attribute"}, 365 }; 366 static uint_t num_ftypes = sizeof (ftype_names) / sizeof (ftype_names_t); 367 368 static ftype_names_t open_rflags[] = { 369 {"?", "UNKNOWN"}, /* 0 */ 370 {"CF", "CONFIRM"}, /* 1 */ 371 {"PL", "POSIX LOCK"}, /* 2 */ 372 {"?", "UNKNOWN"}, 373 }; 374 static uint_t num_open_rflags = 375 sizeof (open_rflags) / sizeof (ftype_names_t) - 1; 376 377 static char *get_flags(uint_t, ftype_names_t *, uint_t, int, char *); 378 379 #define sum_open_rflags(flag) \ 380 get_flags((flag), open_rflags, num_open_rflags, 1, " RF=") 381 382 #define detail_open_rflags(flag) \ 383 get_flags((flag), open_rflags, num_open_rflags, 0, NULL) 384 385 static void prt_supported_attrs(XDR *); 386 static void prt_type(XDR *); 387 static void prt_fh_expire_type(XDR *); 388 static void prt_change(XDR *); 389 static void prt_size(XDR *); 390 static void prt_link_support(XDR *); 391 static void prt_symlink_support(XDR *); 392 static void prt_named_attr(XDR *); 393 static void prt_fsid(XDR *); 394 static void prt_unique_handles(XDR *); 395 static void prt_lease_time(XDR *); 396 static void prt_rdattr_error(XDR *); 397 static void prt_acl(XDR *); 398 static void prt_aclsupport(XDR *); 399 static void prt_archive(XDR *); 400 static void prt_cansettime(XDR *); 401 static void prt_case_insensitive(XDR *); 402 static void prt_case_preserving(XDR *); 403 static void prt_chown_restricted(XDR *); 404 static void prt_filehandle(XDR *); 405 static void prt_fileid(XDR *); 406 static void prt_mounted_on_fileid(XDR *); 407 static void prt_files_avail(XDR *); 408 static void prt_files_free(XDR *); 409 static void prt_files_total(XDR *); 410 static void prt_fs_locations(XDR *); 411 static void prt_hidden(XDR *); 412 static void prt_homogeneous(XDR *); 413 static void prt_maxfilesize(XDR *); 414 static void prt_maxlink(XDR *); 415 static void prt_maxname(XDR *); 416 static void prt_maxread(XDR *); 417 static void prt_maxwrite(XDR *); 418 static void prt_mimetype(XDR *); 419 static void prt_mode(XDR *); 420 static void prt_no_trunc(XDR *); 421 static void prt_numlinks(XDR *); 422 static void prt_owner(XDR *); 423 static void prt_owner_group(XDR *); 424 static void prt_quota_avail_hard(XDR *); 425 static void prt_quota_avail_soft(XDR *); 426 static void prt_quota_used(XDR *); 427 static void prt_rawdev(XDR *); 428 static void prt_space_avail(XDR *); 429 static void prt_space_free(XDR *); 430 static void prt_space_total(XDR *); 431 static void prt_space_used(XDR *); 432 static void prt_system(XDR *); 433 static void prt_time_access(XDR *); 434 static void prt_time_access_set(XDR *); 435 static void prt_time_backup(XDR *); 436 static void prt_time_create(XDR *); 437 static void prt_time_delta(XDR *); 438 static void prt_time_metadata(XDR *); 439 static void prt_time_modify(XDR *); 440 static void prt_time_modify_set(XDR *); 441 442 443 444 /* 445 * Information for attributes. 446 * name name of the attribute. 447 * prt_details function to XDR decode the attribute and print it. 448 * 449 * XXX If this table ever gets extensively changed (including 450 * reorganization to track changes to the spec), it would probably be a 451 * good idea to change to a scheme where the table is mechanically 452 * generated. Look at $SRC/uts/common/rpcsvc for how this is done in the 453 * kernel. 454 */ 455 456 typedef struct { 457 char *name; 458 void (*prt_details)(XDR *); 459 } attr_info_t; 460 461 static attr_info_t attr_info[MAX_ATTRIBUTES] = { 462 {"SUPPORTED_ATTRS", prt_supported_attrs}, 463 {"TYPE", prt_type}, 464 {"FH_EXPIRE_TYPE", prt_fh_expire_type}, 465 {"CHANGE", prt_change}, 466 {"SIZE", prt_size}, 467 {"LINK_SUPPORT", prt_link_support}, /* 5 */ 468 {"SYMLINK_SUPPORT", prt_symlink_support}, 469 {"NAMED_ATTR", prt_named_attr}, 470 {"FSID", prt_fsid}, 471 {"UNIQUE_HANDLES", prt_unique_handles}, 472 {"LEASE_TIME", prt_lease_time}, /* 10 */ 473 {"RDATTR_ERROR", prt_rdattr_error}, 474 {"ACL", prt_acl}, 475 {"ACLSUPPORT", prt_aclsupport}, 476 {"ARCHIVE", prt_archive}, 477 {"CANSETTIME", prt_cansettime}, /* 15 */ 478 {"CASE_INSENSITIVE", prt_case_insensitive}, 479 {"CASE_PRESERVING", prt_case_preserving}, 480 {"CHOWN_RESTRICTED", prt_chown_restricted}, 481 {"FILEHANDLE", prt_filehandle}, 482 {"FILEID", prt_fileid}, /* 20 */ 483 {"FILES_AVAIL", prt_files_avail}, 484 {"FILES_FREE", prt_files_free}, 485 {"FILES_TOTAL", prt_files_total}, 486 {"FS_LOCATIONS", prt_fs_locations}, 487 {"HIDDEN", prt_hidden}, /* 25 */ 488 {"HOMOGENEOUS", prt_homogeneous}, 489 {"MAXFILESIZE", prt_maxfilesize}, 490 {"MAXLINK", prt_maxlink}, 491 {"MAXNAME", prt_maxname}, 492 {"MAXREAD", prt_maxread}, /* 30 */ 493 {"MAXWRITE", prt_maxwrite}, 494 {"MIMETYPE", prt_mimetype}, 495 {"MODE", prt_mode}, 496 {"NO_TRUNC", prt_no_trunc}, 497 {"NUMLINKS", prt_numlinks}, /* 35 */ 498 {"OWNER", prt_owner}, 499 {"OWNER_GROUP", prt_owner_group}, 500 {"QUOTA_AVAIL_HARD", prt_quota_avail_hard}, 501 {"QUOTA_AVAIL_SOFT", prt_quota_avail_soft}, 502 {"QUOTA_USED", prt_quota_used}, /* 40 */ 503 {"RAWDEV", prt_rawdev}, 504 {"SPACE_AVAIL", prt_space_avail}, 505 {"SPACE_FREE", prt_space_free}, 506 {"SPACE_TOTAL", prt_space_total}, 507 {"SPACE_USED", prt_space_used}, /* 45 */ 508 {"SYSTEM", prt_system}, 509 {"TIME_ACCESS", prt_time_access}, 510 {"TIME_ACCESS_SET", prt_time_access_set}, 511 {"TIME_BACKUP", prt_time_backup}, 512 {"TIME_CREATE", prt_time_create}, /* 50 */ 513 {"TIME_DELTA", prt_time_delta}, 514 {"TIME_METADATA", prt_time_metadata}, 515 {"TIME_MODIFY", prt_time_modify}, 516 {"TIME_MODIFY_SET", prt_time_modify_set}, 517 {"MOUNTED_ON_FILEID", prt_mounted_on_fileid}, 518 }; 519 520 extern char *get_sum_line(); 521 522 extern jmp_buf xdr_err; 523 524 static void sum_comp4res(char *, char *(*)(void)); 525 static char *sum_compound4args(void); 526 static char *sum_compound4res(void); 527 static char *sum_operand(nfs_argop4 *opp); 528 static char *sum_result(nfs_resop4 *resp); 529 530 static char *sum_cb_compound4args(void); 531 static char *sum_cb_compound4res(void); 532 static char *sum_cb_operand(nfs_cb_argop4 *opp); 533 static char *sum_cb_result(nfs_cb_resop4 *resp); 534 535 static void detail_acetype4(acetype4); 536 static void detail_uint32_bitmap(uint32_t, char *[], int); 537 static void detail_aceflag4(aceflag4); 538 static void detail_acemask4(acemask4); 539 static void detail_nfs_argop4(void); 540 static void detail_nfs_resop4(void); 541 static void detail_cb_argop4(void); 542 static void detail_cb_resop4(void); 543 544 static char *attr_name(uint_t); 545 static char *claim_name(enum open_claim_type4 claim_type); 546 static char *delegation_type_name(enum open_delegation_type4 type); 547 static char *flavor_name(uint_t flavor); 548 static char *gss_svc_name(rpc_gss_svc_t svc); 549 static char *limitby_name(enum limit_by4 limitby); 550 static char *lock_type_name(enum nfs_lock_type4); 551 static char *opcode_name(uint_t); 552 static char *cb_opcode_name(uint_t opnum); 553 static char *status_name(int); 554 static char *status_name_compat(int); 555 static char *status_name_pcol(int); 556 static char *sum_type_name(nfs_ftype4); 557 static void sum_access4(char *buf, size_t buflen, uint32_t bits); 558 static void detail_access4(char *, uint32_t); 559 static void sum_claim(char *buf, size_t buflen, open_claim4 *claim); 560 static void detail_claim(open_claim4 *claim); 561 static char *sum_clientid(clientid4 client); 562 static void detail_clientid(clientid4 client); 563 static char *_sum_stateid(stateid4 *, char *prefix); 564 static void sum_delegation(char *buf, size_t buflen, open_delegation4 *delp); 565 static void detail_delegation(open_delegation4 *delp); 566 static void detail_lock_owner(lock_owner4 *owner); 567 static void detail_open_owner(open_owner4 *owner); 568 static void sum_openflag(char *bufp, int buflen, openflag4 *flagp); 569 static char *get_deleg_typestr(open_delegation_type4 dt); 570 static void detail_openflag(openflag4 *flagp); 571 static void sum_name(char *buf, size_t buflen, open_claim4 *claim); 572 static void detail_rpcsec_gss(rpcsec_gss_info *); 573 static void detail_secinfo4(secinfo4 *infop); 574 static char *sum_space_limit(nfs_space_limit4 *limitp); 575 static void detail_space_limit(nfs_space_limit4 *limitp); 576 static char *detail_type_name(nfs_ftype4); 577 static char *createhow4_name(createhow4 *crtp); 578 579 580 static void showxdr_utf8string(char *); 581 static char *utf8localize(utf8string *); 582 static void utf8free(void); 583 static void sum_pathname4(char *, size_t, pathname4 *); 584 static void detail_pathname4(pathname4 *pathp, char *); 585 static void sum_compname4(char *buf, size_t buflen, component4 *comp); 586 static void detail_compname4(component4 *comp); 587 588 static void detail_fattr4(fattr4 *attrp); 589 static void detail_attr_bitmap(char *, bitmap4 *, unpkd_attrmap_t *); 590 static void sum_attr_bitmap(char *buf, size_t buflen, bitmap4 *mapp); 591 static void detail_fattr4_change(char *msg, fattr4_change chg); 592 static char *sum_fh4(nfs_fh4 *fhp); 593 static void detail_fh4(nfs_fh4 *fh); 594 595 #define fh4_hash(fh) adler16((fh)->nfs_fh4_val, (fh)->nfs_fh4_len) 596 #define stateid_hash(st) adler16((st)->other, sizeof ((st)->other)) 597 #define owner_hash(own) adler16((own)->owner_val, (own)->owner_len) 598 599 #define sum_deleg_stateid(st) _sum_stateid((st), "DST=") 600 #define sum_open_stateid(st) _sum_stateid((st), "OST=") 601 #define sum_lock_stateid(st) _sum_stateid((st), "LST=") 602 #define sum_stateid(st) _sum_stateid((st), "ST=") 603 604 #define detail_deleg_stateid(st) _detail_stateid((st), "Delegation ") 605 #define detail_open_stateid(st) _detail_stateid((st), "Open ") 606 #define detail_lock_stateid(st) _detail_stateid((st), "Lock ") 607 #define detail_stateid(st) _detail_stateid((st), "") 608 609 #define SPECIAL_STATEID0 "SPC0" 610 #define SPECIAL_STATEID1 "SPC1" 611 612 #define DONT_CHANGE 0 613 #define SET_TO_SERVER_TIME 1 614 #define SET_TO_CLIENT_TIME 2 615 616 static stateid4 spec_stateid_0 = 617 {0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; 618 static stateid4 spec_stateid_1 = 619 {0xFFFFFFFF, {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}}; 620 621 static char *procnames_short[] = { 622 "NULL4", /* 0 */ 623 "COMPOUND4" /* 1 */ 624 }; 625 626 static char *procnames_long[] = { 627 "Null procedure", /* 0 */ 628 "Compound", /* 1 */ 629 }; 630 631 static char *cb_procnames_short[] = { 632 "CB_NULL", /* 0 */ 633 "CB_COMPOUND" /* 1 */ 634 }; 635 636 static char *cb_procnames_long[] = { 637 "Null CallBack procedure", /* 0 */ 638 "CallBack compound", /* 1 */ 639 }; 640 641 static char *acetype4_names[] = { 642 "ACE4_ACCESS_ALLOWED_ACE_TYPE", 643 "ACE4_ACCESS_DENIED_ACE_TYPE", 644 "ACE4_SYSTEM_AUDIT_ACE_TYPE", 645 "ACE4_SYSTEM_ALARM_ACE_TYPE" 646 }; 647 #define ACETYPE4_NAMES_MAX (sizeof (acetype4_names) / sizeof (char *)) 648 649 static char *aceflag4_names[] = { 650 "ACE4_FILE_INHERIT_ACE", 651 "ACE4_DIRECTORY_INHERIT_ACE", 652 "ACE4_NO_PROPAGATE_INHERIT_ACE", 653 "ACE4_INHERIT_ONLY_ACE", 654 "ACE4_SUCCESSFUL_ACCESS_ACE_FLAG", 655 "ACE4_FAILED_ACCESS_ACE_FLAG", 656 "ACE4_IDENTIFIER_GROUP" 657 }; 658 #define ACEFLAG4_NAMES_MAX (sizeof (aceflag4_names) / sizeof (char *)) 659 660 static char *acemask4_names[] = { 661 "ACE4_READ_DATA/ACE4_LIST_DIRECTORY", 662 "ACE4_WRITE_DATA/ACE4_ADD_FILE", 663 "ACE4_APPEND_DATA/ACE4_ADD_SUBDIRECTORY", 664 "ACE4_READ_NAMED_ATTRS", 665 "ACE4_WRITE_NAMED_ATTRS", 666 "ACE4_EXECUTE", 667 "ACE4_DELETE_CHILD", 668 "ACE4_READ_ATTRIBUTES", 669 "ACE4_WRITE_ATTRIBUTES", 670 "UNDEFINED", /* 0x00000200 */ 671 "UNDEFINED", /* 0x00000400 */ 672 "UNDEFINED", /* 0x00000800 */ 673 "UNDEFINED", /* 0x00001000 */ 674 "UNDEFINED", /* 0x00002000 */ 675 "UNDEFINED", /* 0x00004000 */ 676 "UNDEFINED", /* 0x00008000 */ 677 "ACE4_DELETE", 678 "ACE4_READ_ACL", 679 "ACE4_WRITE_ACL", 680 "ACE4_WRITE_OWNER", 681 "ACE4_SYNCHRONIZE" 682 }; 683 #define ACEMASK4_NAMES_MAX (sizeof (acemask4_names) / sizeof (char *)) 684 685 #define MAXPROC 1 686 687 /*ARGSUSED*/ 688 void 689 interpret_nfs4_cb(int flags, int type, int xid, int vers, int proc, 690 char *data, int len) 691 { 692 char *line = NULL; 693 694 if (proc < 0 || proc > MAXPROC) 695 return; 696 697 if (flags & F_SUM) { 698 line = get_sum_line(); 699 700 if (type == CALL) { 701 (void) sprintf(line, "NFS C %s", 702 proc == CB_COMPOUND ? "CB4" : 703 cb_procnames_short[proc]); 704 line += strlen(line); 705 706 if (proc == CB_COMPOUND) { 707 static utf8string tag; 708 709 if (!xdr_utf8string(&xdrm, &tag)) 710 longjmp(xdr_err, 1); 711 sprintf(line, " (%.20s) %s", 712 utf8localize(&tag), 713 sum_cb_compound4args()); 714 xdr_free(xdr_utf8string, (char *)&tag); 715 } 716 check_retransmit(line, xid); 717 } else { 718 (void) sprintf(line, "NFS R %s ", 719 proc == CB_COMPOUND ? "CB4" : 720 cb_procnames_short[proc]); 721 line += strlen(line); 722 if (proc == CB_COMPOUND) 723 sum_comp4res(line, sum_cb_compound4res); 724 } 725 } 726 727 if (flags & F_DTAIL) { 728 show_header("NFS: ", "Sun NFS4 CallBack", len); 729 show_space(); 730 (void) sprintf(get_line(0, 0), "Proc = %d (%s)", 731 proc, cb_procnames_long[proc]); 732 if (proc == CB_COMPOUND) { 733 if (type == CALL) { 734 showxdr_utf8string("Tag = %s"); 735 detail_cb_argop4(); 736 } else { 737 nfsstat4 status; 738 739 status = getxdr_long(); 740 showxdr_utf8string("Tag = %s"); 741 sprintf(get_line(0, 0), "Status = %d (%s)", 742 status, status_name(status)); 743 detail_cb_resop4(); 744 } 745 } 746 show_trailer(); 747 } 748 749 utf8free(); /* cf. utf8localize() */ 750 } 751 752 753 /*ARGSUSED*/ 754 void 755 interpret_nfs4(int flags, int type, int xid, int vers, int proc, 756 char *data, int len) 757 { 758 char *line = NULL; 759 760 if (proc < 0 || proc > MAXPROC) 761 return; 762 763 nfs4_fragged_rpc = 0; 764 nfs4_pkt_len = len; 765 nfs4_pkt_start = xdr_getpos(&xdrm); 766 767 if (flags & F_SUM) { 768 line = get_sum_line(); 769 770 if (type == CALL) { 771 (void) sprintf(line, "NFS C %s", 772 proc == NFSPROC4_COMPOUND ? "4" : 773 procnames_short[proc]); 774 line += strlen(line); 775 776 if (proc == NFSPROC4_COMPOUND) { 777 static utf8string tag; 778 779 if (!xdr_utf8string(&xdrm, &tag)) 780 longjmp(xdr_err, 1); 781 sprintf(line, " (%.20s) %s", 782 utf8localize(&tag), 783 sum_compound4args()); 784 xdr_free(xdr_utf8string, (char *)&tag); 785 } 786 check_retransmit(line, xid); 787 } else { 788 (void) sprintf(line, "NFS R %s ", 789 proc == NFSPROC4_COMPOUND ? "4" : 790 procnames_short[proc]); 791 line += strlen(line); 792 793 if (proc == NFSPROC4_COMPOUND) 794 sum_comp4res(line, sum_compound4res); 795 } 796 } 797 798 if (flags & F_DTAIL) { 799 show_header("NFS: ", "Sun NFS", len); 800 show_space(); 801 (void) sprintf(get_line(0, 0), "Proc = %d (%s)", 802 proc, procnames_long[proc]); 803 if (proc == NFSPROC4_COMPOUND) { 804 if (type == CALL) { 805 showxdr_utf8string("Tag = %s"); 806 detail_nfs_argop4(); 807 } else { 808 nfsstat4 status; 809 810 status = getxdr_long(); 811 showxdr_utf8string("Tag = %s"); 812 sprintf(get_line(0, 0), "Status = %d (%s)", 813 status, status_name(status)); 814 detail_nfs_resop4(); 815 } 816 } 817 show_trailer(); 818 } 819 820 utf8free(); /* cf. utf8localize() */ 821 } 822 823 824 825 /* 826 * Return the names and arguments of the oplist elements, up to 827 * SUM_COMPND_MAX characters. If the elements don't fit, include a "..." 828 * at the end of the string. 829 */ 830 831 static char * 832 sum_compound4args(void) 833 { 834 static char buf[SUM_COMPND_MAX + 2]; /* 1 for null, 1 for overflow */ 835 int numops; 836 const size_t buflen = sizeof (buf); 837 char *bp; 838 nfs_argop4 one_op; 839 uint32_t minor_version; 840 841 buf[0] = '\0'; 842 843 if (setjmp(xdr_err)) { 844 bp = buf + strlen(buf); 845 snprintf(bp, buflen - (bp - buf), 846 nfs4_fragged_rpc ? nfs4err_fragrpc : nfs4err_xdrfrag); 847 return (buf); 848 } 849 850 /* 851 * might be nice to print minor version, but doesn't 852 * seem like very useful info for summary mode 853 */ 854 if (!xdr_uint32_t(&xdrm, &minor_version)) 855 longjmp(xdr_err, 1); 856 857 numops = getxdr_long(); 858 bp = buf; 859 while (numops-- > 0) { 860 char *operand; 861 862 bzero(&one_op, sizeof (one_op)); 863 864 if (!xdr_nfs_argop4(&xdrm, &one_op)) { 865 xdr_free(xdr_nfs_argop4, (char *)&one_op); 866 longjmp(xdr_err, 1); 867 } 868 snprintf(bp, buflen - (bp - buf), "%s ", 869 opcode_name(one_op.argop)); 870 bp += strlen(bp); 871 872 operand = sum_operand(&one_op); 873 if (strlen(operand) > 0) { 874 snprintf(bp, buflen - (bp - buf), "%s ", operand); 875 bp += strlen(bp); 876 } 877 878 /* nfs4_skip_bytes set by xdr_nfs4_argop4 */ 879 if (nfs4_skip_bytes != 0) 880 nfs4_xdr_skip(nfs4_skip_bytes); 881 882 xdr_free(xdr_nfs_argop4, (char *)&one_op); 883 884 /* add "..." if past the "end" of the buffer */ 885 if (bp - buf > SUM_COMPND_MAX) { 886 strcpy(buf + SUM_COMPND_MAX - strlen("..."), 887 "..."); 888 break; 889 } 890 } 891 892 return (buf); 893 } 894 895 static void 896 nfs4_xdr_skip(int nbytes) 897 { 898 int resid, off, len, cur_pos, new_pos; 899 900 len = RNDUP(nbytes); 901 cur_pos = xdr_getpos(&xdrm); 902 903 /* 904 * Time to skip over the rd/wr data. If the 905 * rd/wr data is completely contained in the first 906 * frag, we must skip over it to process the rest of 907 * the packet. 908 * 909 * nfs4_pkt_start: XDR position of start of NFS4 compound 910 * nfs4_pkt_len: number of bytes in pkt relative to 911 * nfs4_pkt_start 912 * 913 * cur_pos: current XDR position 914 * off: current XDR position relative to nfs4_pkt_start 915 * resid: number of unprocessed bytes in current pkt 916 * (relative to cur_pos/off) 917 * 918 * If nbytes <= resid, then we must skip over the rd/wr 919 * bytes so we can read the next op/compound in this 920 * packet. Otherwise, set the fragged flag so we can 921 * display the fragged_rpc message. 922 */ 923 off = cur_pos - nfs4_pkt_start; 924 resid = nfs4_pkt_len - off; 925 926 /* 927 * set nfs4_fragged_rpc if the requested number of "skip" 928 * bytes is larger than the bytes remaining in the XDR 929 * stream/current packet. The global is reset to 0 at 930 * start of interpret_nfs4. 931 */ 932 new_pos = cur_pos + ((nfs4_fragged_rpc = len > resid) ? resid : len); 933 934 /* there's nothing to do for error case (if it fails pkt is doomed) */ 935 xdr_setpos(&xdrm, new_pos); 936 } 937 938 939 /* 940 * Return the names and arguments of the oplist elements, up to 941 * SUM_COMPND_MAX characters. If the elements don't fit, include a "..." 942 * at the end of the string. 943 */ 944 static char * 945 sum_cb_compound4args(void) 946 { 947 static char buf[SUM_COMPND_MAX + 2]; /* 1 for null, 1 for overflow */ 948 int numops; 949 const size_t buflen = sizeof (buf); 950 char *bp; 951 nfs_cb_argop4 one_op; 952 uint32_t minor_version, callback_ident; 953 954 buf[0] = '\0'; 955 if (setjmp(xdr_err)) { 956 bp = buf + strlen(buf); 957 snprintf(bp, buflen - (bp - buf), "<XDR Error or Fragmented" 958 " RPC>"); 959 return (buf); 960 } 961 962 /* 963 * might be nice to print minor version, but doesn't 964 * seem like very useful info for summary mode 965 */ 966 if (!xdr_uint32_t(&xdrm, &minor_version)) 967 longjmp(xdr_err, 1); 968 969 /* print callback_ident */ 970 if (!xdr_uint32_t(&xdrm, &callback_ident)) 971 longjmp(xdr_err, 1); 972 snprintf(buf, buflen, "CBID=%u ", callback_ident); 973 974 bp = buf + strlen(buf); 975 numops = getxdr_long(); 976 977 while (numops-- > 0) { 978 char *operand; 979 980 bzero(&one_op, sizeof (one_op)); 981 if (!xdr_nfs_cb_argop4(&xdrm, &one_op)) { 982 xdr_free(xdr_nfs_cb_argop4, (char *)&one_op); 983 longjmp(xdr_err, 1); 984 } 985 986 snprintf(bp, buflen - (bp - buf), "%s ", 987 cb_opcode_name(one_op.argop)); 988 bp += strlen(bp); 989 operand = sum_cb_operand(&one_op); 990 if (strlen(operand) > 0) { 991 snprintf(bp, buflen - (bp - buf), "%s ", operand); 992 bp += strlen(bp); 993 } 994 995 xdr_free(xdr_nfs_cb_argop4, (char *)&one_op); 996 997 /* add "..." if past the "end" of the buffer */ 998 if (bp - buf > SUM_COMPND_MAX) { 999 strcpy(buf + SUM_COMPND_MAX - strlen("..."), 1000 "..."); 1001 break; 1002 } 1003 } 1004 1005 return (buf); 1006 } 1007 1008 /* 1009 * Return the summarized argument list for the given nfs_argop4. 1010 */ 1011 1012 static char * 1013 sum_operand(nfs_argop4 *opp) 1014 { 1015 static char buf[1024]; 1016 void (*fmtproc)(char *, size_t, void *); 1017 1018 buf[0] = '\0'; 1019 if (opp->argop < num_opcodes) { 1020 fmtproc = opcode_info[opp->argop].sumarg; 1021 if (fmtproc != NULL) 1022 fmtproc(buf, sizeof (buf), &opp->nfs_argop4_u); 1023 } 1024 1025 return (buf); 1026 } 1027 1028 /* 1029 * Return the summarized argument list for the given nfs_argop4. 1030 */ 1031 1032 static char * 1033 sum_cb_operand(nfs_cb_argop4 *opp) 1034 { 1035 static char buf[1024]; 1036 void (*fmtproc)(char *, size_t, void *); 1037 1038 buf[0] = '\0'; 1039 if (opp->argop < cb_num_opcodes) { 1040 fmtproc = cb_opcode_info[opp->argop].sumarg; 1041 if (fmtproc != NULL) 1042 fmtproc(buf, sizeof (buf), &opp->nfs_cb_argop4_u); 1043 } 1044 1045 return (buf); 1046 } 1047 1048 /* 1049 * Print details about the nfs_argop4 that is next in the XDR stream. 1050 */ 1051 1052 static void 1053 detail_nfs_argop4(void) 1054 { 1055 int numops; 1056 nfs_argop4 one_op; 1057 void (*fmtproc)(void *); 1058 uint32_t minor_version; 1059 1060 if (!xdr_uint32_t(&xdrm, &minor_version)) 1061 longjmp(xdr_err, 1); 1062 1063 (void) sprintf(get_line(0, 0), "Minor version = %u", 1064 minor_version); 1065 1066 numops = getxdr_long(); 1067 (void) sprintf(get_line(0, 0), "Number of operations = %d", 1068 numops); 1069 1070 while (numops-- > 0) { 1071 bzero(&one_op, sizeof (one_op)); 1072 1073 if (!xdr_nfs_argop4(&xdrm, &one_op)) { 1074 xdr_free(xdr_nfs_argop4, (char *)&one_op); 1075 longjmp(xdr_err, 1); 1076 } 1077 1078 get_line(0, 0); /* blank line to separate ops */ 1079 sprintf(get_line(0, 0), "Op = %d (%s)", 1080 one_op.argop, opcode_name(one_op.argop)); 1081 if (one_op.argop < num_opcodes) { 1082 fmtproc = opcode_info[one_op.argop].dtlarg; 1083 if (fmtproc != NULL) 1084 fmtproc(&one_op.nfs_argop4_u); 1085 } 1086 1087 /* nfs4_skip_bytes set by xdr_nfs_argop4() */ 1088 if (nfs4_skip_bytes) 1089 nfs4_xdr_skip(nfs4_skip_bytes); 1090 1091 xdr_free(xdr_nfs_argop4, (char *)&one_op); 1092 } 1093 } 1094 1095 1096 /* 1097 * Print details about the nfs_argop4 that is next in the XDR stream. 1098 */ 1099 static void 1100 detail_cb_argop4(void) 1101 { 1102 int numops; 1103 nfs_cb_argop4 one_op; 1104 void (*fmtproc)(void *); 1105 uint32_t minor_version, callback_ident; 1106 1107 if (!xdr_uint32_t(&xdrm, &minor_version)) 1108 longjmp(xdr_err, 1); 1109 (void) sprintf(get_line(0, 0), "Minor version = %u", 1110 minor_version); 1111 1112 if (!xdr_uint32_t(&xdrm, &callback_ident)) 1113 longjmp(xdr_err, 1); 1114 (void) sprintf(get_line(0, 0), "Callback Ident = %u", 1115 callback_ident); 1116 1117 numops = getxdr_long(); 1118 (void) sprintf(get_line(0, 0), "Number of operations = %d", 1119 numops); 1120 1121 while (numops-- > 0) { 1122 bzero(&one_op, sizeof (one_op)); 1123 if (!xdr_nfs_cb_argop4(&xdrm, &one_op)) { 1124 xdr_free(xdr_nfs_cb_argop4, (char *)&one_op); 1125 longjmp(xdr_err, 1); 1126 } 1127 1128 get_line(0, 0); /* blank line to separate ops */ 1129 sprintf(get_line(0, 0), "Op = %d (%s)", 1130 one_op.argop, cb_opcode_name(one_op.argop)); 1131 if (one_op.argop < cb_num_opcodes) { 1132 fmtproc = cb_opcode_info[one_op.argop].dtlarg; 1133 if (fmtproc != NULL) 1134 fmtproc(&one_op.nfs_cb_argop4_u); 1135 } 1136 1137 xdr_free(xdr_nfs_cb_argop4, (char *)&one_op); 1138 } 1139 } 1140 1141 /* 1142 * component_name: return a printable string for the given component4. I'm 1143 * leaving this as a separate function (as opposed to having the callers 1144 * call utf8localize() directly) in case the definition of component4 1145 * changes. 1146 */ 1147 1148 static char * 1149 component_name(component4 *cp) 1150 { 1151 return (utf8localize(cp)); 1152 } 1153 1154 /* 1155 * linktext_name. cf. component_name(). 1156 */ 1157 1158 static char * 1159 linktext_name(linktext4 *lp) 1160 { 1161 return (utf8localize((utf8string *)lp)); 1162 } 1163 1164 /* 1165 * stable_how4_name: return a string for "how". 1166 */ 1167 1168 static char * 1169 stable_how4_name(stable_how4 how) 1170 { 1171 char *result; 1172 1173 switch (how) { 1174 case UNSTABLE4: 1175 result = "ASYNC"; 1176 break; 1177 case DATA_SYNC4: 1178 result = "DSYNC"; 1179 break; 1180 case FILE_SYNC4: 1181 result = "FSYNC"; 1182 break; 1183 default: 1184 result = "?"; 1185 break; 1186 } 1187 1188 return (result); 1189 } 1190 1191 /* 1192 * sum_open_share_access: return a string corresponding to the 1193 * given OPEN share access bitmask. 1194 */ 1195 1196 static char * 1197 sum_open_share_access(int32_t mask) 1198 { 1199 char *result; 1200 1201 switch (mask) { 1202 case 0: 1203 result = "N"; 1204 break; 1205 case OPEN4_SHARE_ACCESS_READ: 1206 result = "R"; 1207 break; 1208 case OPEN4_SHARE_ACCESS_WRITE: 1209 result = "W"; 1210 break; 1211 case OPEN4_SHARE_ACCESS_BOTH: 1212 result = "RW"; 1213 break; 1214 default: 1215 result = "?"; 1216 break; 1217 } 1218 1219 return (result); 1220 } 1221 1222 /* 1223 * sum_open_share_deny: return a string corresponding to the 1224 * given OPEN share deny bitmask. 1225 */ 1226 1227 static char * 1228 sum_open_share_deny(int32_t mask) 1229 { 1230 char *result; 1231 1232 switch (mask) { 1233 case OPEN4_SHARE_DENY_NONE: 1234 result = "N"; 1235 break; 1236 case OPEN4_SHARE_DENY_READ: 1237 result = "R"; 1238 break; 1239 case OPEN4_SHARE_DENY_WRITE: 1240 result = "W"; 1241 break; 1242 case OPEN4_SHARE_DENY_BOTH: 1243 result = "RW"; 1244 break; 1245 default: 1246 result = "?"; 1247 break; 1248 } 1249 1250 return (result); 1251 } 1252 1253 static int 1254 special_stateid(stateid4 *stateid) 1255 { 1256 1257 if (! memcmp(stateid, &spec_stateid_0, sizeof (*stateid))) 1258 return (0); 1259 1260 if (! memcmp(stateid, &spec_stateid_1, sizeof (*stateid))) 1261 return (1); 1262 1263 return (-1); 1264 } 1265 1266 static char * 1267 _sum_stateid(stateid4 *stateid, char *prefix) 1268 { 1269 static char buf[32]; 1270 int spec; 1271 1272 if ((spec = special_stateid(stateid)) < 0) 1273 snprintf(buf, sizeof (buf), "%s%04X:%u", prefix, 1274 stateid_hash(stateid), stateid->seqid); 1275 else 1276 snprintf(buf, sizeof (buf), "%s%s", prefix, 1277 spec == 0 ? "SPC0" : (spec == 1 ? "SPC1" : "SPC?")); 1278 return (buf); 1279 } 1280 1281 static void 1282 _detail_stateid(stateid4 *stateid, char *prefix) 1283 { 1284 int spec; 1285 char seqstr[32] = {0}; 1286 1287 spec = special_stateid(stateid); 1288 1289 if (spec < 0) 1290 sprintf(get_line(0, 0), "%sState ID hash = %04X", 1291 prefix, stateid_hash(stateid)); 1292 else 1293 sprintf(get_line(0, 0), "%sState ID hash = %s", prefix, 1294 spec == 0 ? "SPECIAL_0" : 1295 (spec == 1 ? "SPECIAL_1" : "SPECIAL_?")); 1296 1297 sprintf(get_line(0, 0), " len = %u val = %s", 1298 sizeof (stateid->other), 1299 tohex(stateid->other, sizeof (stateid->other))); 1300 1301 /* 1302 * If spec 0/1 stateid, print seqid in hex; otherwise, 1303 * use decimal. This makes it more clear how spec stateids 1304 * are constructed [obvious that either all bits are 0, or all 1305 * bits are 1]. 1306 */ 1307 if (spec == -1) 1308 sprintf(seqstr, "%d", stateid->seqid); 1309 else 1310 sprintf(seqstr, "%08X", stateid->seqid); 1311 1312 sprintf(get_line(0, 0), " %sState ID Sequence ID = %s", 1313 prefix, seqstr); 1314 } 1315 1316 1317 static char * 1318 sum_lock_denied(LOCK4denied *denied) 1319 { 1320 static char buf[64]; 1321 1322 sprintf(buf, "%s %llu:%llu LO=%04X", 1323 sum_lock_type_name(denied->locktype), 1324 denied->offset, denied->length, 1325 owner_hash(&denied->owner.owner)); 1326 1327 return (buf); 1328 } 1329 1330 static void 1331 detail_lock_denied(LOCK4denied *denied) 1332 { 1333 sprintf(get_line(0, 0), "Type = %s", lock_type_name(denied->locktype)); 1334 detail_lock_owner(&denied->owner); 1335 sprintf(get_line(0, 0), "Offset = %llu", denied->offset); 1336 sprintf(get_line(0, 0), "Length = %llu", denied->length); 1337 } 1338 1339 /* 1340 * sum_createhow4: return the string name of "how". 1341 */ 1342 1343 static char * 1344 createhow4_name(createhow4 *crtp) 1345 { 1346 char *result; 1347 1348 switch (crtp->mode) { 1349 case UNCHECKED4: 1350 result = "UNCHECKED"; 1351 break; 1352 case GUARDED4: 1353 result = "GUARDED"; 1354 break; 1355 case EXCLUSIVE4: 1356 result = "EXCLUSIVE"; 1357 break; 1358 default: 1359 result = "?"; 1360 break; 1361 } 1362 1363 return (result); 1364 } 1365 1366 /* 1367 * detail_createhow4: print detail information about "how". 1368 */ 1369 1370 static void 1371 detail_createhow4(createhow4 *crtp) 1372 { 1373 sprintf(get_line(0, 0), "Method = %s", 1374 createhow4_name(crtp)); 1375 1376 switch (crtp->mode) { 1377 case UNCHECKED4: 1378 case GUARDED4: 1379 detail_fattr4(&crtp->createhow4_u.createattrs); 1380 break; 1381 case EXCLUSIVE4: 1382 sprintf(get_line(0, 0), " Verifier = %s", 1383 tohex(crtp->createhow4_u.createverf, 1384 NFS4_VERIFIER_SIZE)); 1385 break; 1386 } 1387 } 1388 1389 static void 1390 detail_createtype4(createtype4 *crtp) 1391 { 1392 sprintf(get_line(0, 0), "Type = %s", 1393 detail_type_name(crtp->type)); 1394 switch (crtp->type) { 1395 case NF4LNK: 1396 sprintf(get_line(0, 0), "Linkdata = %s", 1397 utf8localize((utf8string *)&crtp->createtype4_u.linkdata)); 1398 break; 1399 case NF4BLK: 1400 case NF4CHR: 1401 sprintf(get_line(0, 0), "Specdata1 = %04x Specdata2 = %04x", 1402 crtp->createtype4_u.devdata.specdata1, 1403 crtp->createtype4_u.devdata.specdata2); 1404 break; 1405 default: 1406 break; 1407 } 1408 } 1409 1410 static void 1411 sumarg_access(char *buf, size_t buflen, void *obj) 1412 { 1413 ACCESS4args *args = (ACCESS4args *)obj; 1414 1415 sum_access4(buf, buflen, args->access); 1416 } 1417 1418 static void 1419 dtlarg_access(void *obj) 1420 { 1421 ACCESS4args *args = (ACCESS4args *)obj; 1422 1423 detail_access4("Access bits", args->access); 1424 } 1425 1426 static void 1427 sumarg_close(char *buf, size_t buflen, void *obj) 1428 { 1429 CLOSE4args *args = (CLOSE4args *)obj; 1430 1431 snprintf(buf, buflen, "SQ=%u %s", 1432 args->seqid, sum_open_stateid(&args->open_stateid)); 1433 } 1434 1435 static void 1436 dtlarg_close(void *obj) 1437 { 1438 CLOSE4args *args = (CLOSE4args *)obj; 1439 1440 detail_open_stateid(&args->open_stateid); 1441 sprintf(get_line(0, 0), "Sequence ID = %u", args->seqid); 1442 } 1443 1444 static void 1445 sumarg_commit(char *buf, size_t buflen, void *obj) 1446 { 1447 COMMIT4args *args = (COMMIT4args *)obj; 1448 1449 snprintf(buf, buflen, "at %llu for %u ", args->offset, 1450 args->count); 1451 } 1452 1453 static void 1454 dtlarg_commit(void *obj) 1455 { 1456 COMMIT4args *args = (COMMIT4args *)obj; 1457 1458 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 1459 sprintf(get_line(0, 0), "Count = %u", args->count); 1460 } 1461 1462 static void 1463 sumarg_compnt(char *buf, size_t buflen, void *obj) 1464 { 1465 component4 *comp = (component4 *)obj; 1466 1467 snprintf(buf, buflen, "%s", component_name(comp)); 1468 } 1469 1470 static void 1471 dtlarg_compnt(void *obj) 1472 { 1473 component4 *comp = (component4 *)obj; 1474 1475 sprintf(get_line(0, 0), "Name = %s", component_name(comp)); 1476 } 1477 1478 static void 1479 sumarg_create(char *buf, size_t buflen, void *obj) 1480 { 1481 CREATE4args *args = (CREATE4args *)obj; 1482 1483 snprintf(buf, buflen, "%s %s ", component_name(&args->objname), 1484 sum_type_name(args->objtype.type)); 1485 } 1486 1487 static void 1488 dtlarg_create(void *obj) 1489 { 1490 CREATE4args *args = (CREATE4args *)obj; 1491 1492 sprintf(get_line(0, 0), "Name = %s", component_name(&args->objname)); 1493 detail_createtype4(&args->objtype); 1494 detail_fattr4(&args->createattrs); 1495 } 1496 1497 static void 1498 sumarg_delprge(char *buf, size_t buflen, void *obj) 1499 { 1500 DELEGPURGE4args *args = (DELEGPURGE4args *)obj; 1501 1502 snprintf(buf, buflen, "%s", sum_clientid(args->clientid)); 1503 } 1504 1505 static void 1506 dtlarg_delprge(void *obj) 1507 { 1508 DELEGPURGE4args *args = (DELEGPURGE4args *)obj; 1509 1510 detail_clientid(args->clientid); 1511 } 1512 1513 static void 1514 sumarg_delret(char *buf, size_t buflen, void *obj) 1515 { 1516 DELEGRETURN4args *args = (DELEGRETURN4args *)obj; 1517 1518 snprintf(buf, buflen, "%s", sum_deleg_stateid(&args->deleg_stateid)); 1519 } 1520 1521 static void 1522 dtlarg_delret(void *obj) 1523 { 1524 DELEGRETURN4args *args = (DELEGRETURN4args *)obj; 1525 1526 detail_deleg_stateid(&args->deleg_stateid); 1527 } 1528 1529 static void 1530 sumarg_getattr(char *buf, size_t buflen, void *obj) 1531 { 1532 GETATTR4args *args = (GETATTR4args *)obj; 1533 1534 sum_attr_bitmap(buf, buflen, &args->attr_request); 1535 } 1536 1537 static void 1538 dtlarg_getattr(void *obj) 1539 { 1540 GETATTR4args *args = (GETATTR4args *)obj; 1541 1542 detail_attr_bitmap("", &args->attr_request, NULL); 1543 } 1544 1545 static void 1546 sumarg_cb_getattr(char *buf, size_t buflen, void *obj) 1547 { 1548 CB_GETATTR4args *args = (CB_GETATTR4args *)obj; 1549 char *bp = buf; 1550 1551 snprintf(bp, buflen, "%s ", sum_fh4(&args->fh)); 1552 bp += strlen(bp); 1553 sum_attr_bitmap(bp, buflen - (bp - buf), &args->attr_request); 1554 } 1555 1556 static void 1557 dtlarg_cb_getattr(void *obj) 1558 { 1559 CB_GETATTR4args *args = (CB_GETATTR4args *)obj; 1560 1561 detail_fh4(&args->fh); 1562 detail_attr_bitmap("", &args->attr_request, NULL); 1563 } 1564 1565 static void 1566 sumarg_cb_recall(char *buf, size_t buflen, void *obj) 1567 { 1568 CB_RECALL4args *args = (CB_RECALL4args *)obj; 1569 char *bp = buf; 1570 1571 snprintf(bp, buflen, "%s %s TR=%s", sum_fh4(&args->fh), 1572 sum_stateid(&args->stateid), args->truncate ? "T" : "F"); 1573 } 1574 1575 static void 1576 dtlarg_cb_recall(void *obj) 1577 { 1578 CB_RECALL4args *args = (CB_RECALL4args *)obj; 1579 1580 detail_fh4(&args->fh); 1581 detail_stateid(&args->stateid); 1582 sprintf(get_line(0, 0), "Truncate = %s", 1583 args->truncate ? "True" : "False"); 1584 } 1585 1586 1587 /* 1588 * name openhow seqid claim access deny owner 1589 */ 1590 static void 1591 sumarg_open(char *buf, size_t buflen, void *obj) 1592 { 1593 OPEN4args *args = (OPEN4args *)obj; 1594 char *bp = buf; 1595 int blen = buflen, len; 1596 1597 sum_name(bp, buflen, &args->claim); 1598 bp += (len = strlen(bp)); 1599 blen -= len; 1600 1601 sum_openflag(bp, blen, &args->openhow); 1602 bp += (len = strlen(bp)); 1603 blen -= len; 1604 1605 snprintf(bp, blen, " SQ=%u", args->seqid); 1606 bp += (len = strlen(bp)); 1607 blen -= len; 1608 1609 sum_claim(bp, blen, &args->claim); 1610 bp += (len = strlen(bp)); 1611 blen -= len; 1612 1613 snprintf(bp, blen, " AC=%s DN=%s OO=%04X", 1614 sum_open_share_access(args->share_access), 1615 sum_open_share_deny(args->share_deny), 1616 owner_hash(&args->owner.owner)); 1617 } 1618 1619 static void 1620 dtlarg_open(void *obj) 1621 { 1622 OPEN4args *args = (OPEN4args *)obj; 1623 1624 detail_claim(&args->claim); 1625 detail_openflag(&args->openhow); 1626 detail_open_owner(&args->owner); 1627 sprintf(get_line(0, 0), "Sequence ID = %u", args->seqid); 1628 sprintf(get_line(0, 0), "Access = 0x%x (%s)", 1629 args->share_access, sum_open_share_access(args->share_access)); 1630 sprintf(get_line(0, 0), "Deny = 0x%x (%s)", 1631 args->share_deny, sum_open_share_access(args->share_deny)); 1632 } 1633 1634 static void 1635 sumarg_openattr(char *buf, size_t buflen, void *obj) 1636 { 1637 OPENATTR4args *args = (OPENATTR4args *)obj; 1638 1639 snprintf(buf, buflen, "CD=%s", 1640 args->createdir ? "T" : "F"); 1641 } 1642 1643 static void 1644 dtlarg_openattr(void *obj) 1645 { 1646 OPENATTR4args *args = (OPENATTR4args *)obj; 1647 1648 sprintf(get_line(0, 0), "CreateDir = %s", 1649 args->createdir ? "True" : "False"); 1650 } 1651 1652 static void 1653 sumarg_open_confirm(char *buf, size_t buflen, void *obj) 1654 { 1655 char *bp = buf; 1656 OPEN_CONFIRM4args *args = (OPEN_CONFIRM4args *)obj; 1657 1658 snprintf(bp, buflen, "SQ=%u %s", args->seqid, 1659 sum_open_stateid(&args->open_stateid)); 1660 } 1661 1662 static void 1663 dtlarg_open_confirm(void *obj) 1664 { 1665 OPEN_CONFIRM4args *args = (OPEN_CONFIRM4args *)obj; 1666 1667 sprintf(get_line(0, 0), "Sequence ID = %u", args->seqid); 1668 detail_open_stateid(&args->open_stateid); 1669 } 1670 1671 static void 1672 sumarg_open_downgrd(char *buf, size_t buflen, void *obj) 1673 { 1674 OPEN_DOWNGRADE4args *args = (OPEN_DOWNGRADE4args *)obj; 1675 1676 snprintf(buf, buflen, "SQ=%u %s AC=%s DN=%s", 1677 args->seqid, sum_open_stateid(&args->open_stateid), 1678 sum_open_share_access(args->share_access), 1679 sum_open_share_deny(args->share_deny)); 1680 } 1681 1682 static void 1683 dtlarg_open_downgrd(void *obj) 1684 { 1685 OPEN_DOWNGRADE4args *args = (OPEN_DOWNGRADE4args *)obj; 1686 1687 sprintf(get_line(0, 0), "Open Sequence ID = %u", args->seqid); 1688 detail_open_stateid(&args->open_stateid); 1689 sprintf(get_line(0, 0), "Access = 0x%x (%s)", 1690 args->share_access, sum_open_share_access(args->share_access)); 1691 sprintf(get_line(0, 0), "Deny = 0x%x (%s)", 1692 args->share_deny, sum_open_share_access(args->share_deny)); 1693 } 1694 1695 static void 1696 sumarg_putfh(char *buf, size_t buflen, void *obj) 1697 { 1698 PUTFH4args *args = (PUTFH4args *)obj; 1699 1700 snprintf(buf, buflen, "%s", sum_fh4(&args->object)); 1701 } 1702 1703 static void 1704 dtlarg_putfh(void *obj) 1705 { 1706 PUTFH4args *args = (PUTFH4args *)obj; 1707 1708 detail_fh4(&args->object); 1709 } 1710 1711 static void 1712 sumarg_link(char *buf, size_t buflen, void *obj) 1713 { 1714 LINK4args *args = (LINK4args *)obj; 1715 1716 snprintf(buf, buflen, "%s", component_name(&args->newname)); 1717 } 1718 1719 static void 1720 dtlarg_link(void *obj) 1721 { 1722 LINK4args *args = (LINK4args *)obj; 1723 1724 sprintf(get_line(0, 0), "New name = %s", 1725 component_name(&args->newname)); 1726 } 1727 1728 static void 1729 sum_open_to_lock_owner(char *buf, int buflen, open_to_lock_owner4 *own) 1730 { 1731 snprintf(buf, buflen, " OSQ=%u %s LSQ=%u LO=%04X", own->open_seqid, 1732 sum_open_stateid(&own->open_stateid), own->lock_seqid, 1733 owner_hash(&own->lock_owner.owner)); 1734 } 1735 1736 static void 1737 sum_exist_lock_owner(char *buf, int buflen, exist_lock_owner4 *own) 1738 { 1739 snprintf(buf, buflen, " LSQ=%u %s", own->lock_seqid, 1740 sum_lock_stateid(&own->lock_stateid)); 1741 } 1742 1743 static void 1744 sum_locker(char *buf, size_t len, locker4 *lk) 1745 { 1746 if (lk->new_lock_owner == TRUE) 1747 sum_open_to_lock_owner(buf, len, &lk->locker4_u.open_owner); 1748 else 1749 sum_exist_lock_owner(buf, len, &lk->locker4_u.lock_owner); 1750 } 1751 1752 static char * 1753 sum_lock_type_name(enum nfs_lock_type4 type) 1754 { 1755 char *result; 1756 1757 switch (type) { 1758 case READ_LT: 1759 result = "RD"; 1760 break; 1761 case WRITE_LT: 1762 result = "WR"; 1763 break; 1764 case READW_LT: 1765 result = "RDW"; 1766 break; 1767 case WRITEW_LT: 1768 result = "WRW"; 1769 break; 1770 default: 1771 result = "?"; 1772 break; 1773 } 1774 1775 return (result); 1776 } 1777 1778 static void 1779 sumarg_lock(char *buf, size_t buflen, void *obj) 1780 { 1781 LOCK4args *args = (LOCK4args *)obj; 1782 char *bp = buf; 1783 1784 snprintf(buf, buflen, "%s%s%llu:%llu", 1785 sum_lock_type_name(args->locktype), 1786 args->reclaim ? " reclaim " : " ", 1787 args->offset, args->length); 1788 1789 bp += strlen(buf); 1790 sum_locker(bp, buflen - (bp - buf), &args->locker); 1791 } 1792 1793 static void 1794 detail_open_to_lock_owner(open_to_lock_owner4 *own) 1795 { 1796 sprintf(get_line(0, 0), "Open Sequence ID = %u", own->open_seqid); 1797 detail_open_stateid(&own->open_stateid); 1798 sprintf(get_line(0, 0), "Lock Sequence ID = %u", own->lock_seqid); 1799 detail_lock_owner(&own->lock_owner); 1800 } 1801 1802 static void 1803 detail_exist_lock_owner(exist_lock_owner4 *own) 1804 { 1805 detail_lock_stateid(&own->lock_stateid); 1806 sprintf(get_line(0, 0), "Lock Sequence ID = %u", own->lock_seqid); 1807 } 1808 1809 static void 1810 detail_locker(locker4 *lk) 1811 { 1812 if (lk->new_lock_owner == TRUE) 1813 detail_open_to_lock_owner(&lk->locker4_u.open_owner); 1814 else 1815 detail_exist_lock_owner(&lk->locker4_u.lock_owner); 1816 } 1817 1818 static void 1819 dtlarg_lock(void *obj) 1820 { 1821 LOCK4args *args = (LOCK4args *)obj; 1822 1823 sprintf(get_line(0, 0), "Type = %s", lock_type_name(args->locktype)); 1824 sprintf(get_line(0, 0), "Reclaim = %s", 1825 args->reclaim ? "TRUE" : "FALSE"); 1826 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 1827 sprintf(get_line(0, 0), "Length = %llu", args->length); 1828 detail_locker(&args->locker); 1829 } 1830 1831 static void 1832 sumarg_lockt(char *buf, size_t buflen, void *obj) 1833 { 1834 LOCKT4args *args = (LOCKT4args *)obj; 1835 1836 snprintf(buf, buflen, "%s %llu:%llu", 1837 sum_lock_type_name(args->locktype), 1838 args->offset, args->length); 1839 } 1840 1841 static void 1842 dtlarg_lockt(void *obj) 1843 { 1844 LOCKT4args *args = (LOCKT4args *)obj; 1845 1846 sprintf(get_line(0, 0), "Type = %s", lock_type_name(args->locktype)); 1847 detail_lock_owner(&args->owner); 1848 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 1849 sprintf(get_line(0, 0), "Length = %llu", args->length); 1850 } 1851 1852 static void 1853 sumarg_locku(char *buf, size_t buflen, void *obj) 1854 { 1855 LOCKU4args *args = (LOCKU4args *)obj; 1856 1857 snprintf(buf, buflen, "%llu:%llu LSQ=%u %s", 1858 args->offset, args->length, args->seqid, 1859 sum_lock_stateid(&args->lock_stateid)); 1860 } 1861 1862 1863 static void 1864 dtlarg_locku(void *obj) 1865 { 1866 LOCKU4args *args = (LOCKU4args *)obj; 1867 1868 sprintf(get_line(0, 0), "Type = %s", lock_type_name(args->locktype)); 1869 sprintf(get_line(0, 0), "Sequence ID = %u", args->seqid); 1870 detail_lock_stateid(&args->lock_stateid); 1871 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 1872 sprintf(get_line(0, 0), "Length = %llu", args->length); 1873 } 1874 1875 static void 1876 sumarg_lookup(char *buf, size_t buflen, void *obj) 1877 { 1878 LOOKUP4args *args = (LOOKUP4args *)obj; 1879 1880 sum_compname4(buf, buflen, &args->objname); 1881 } 1882 1883 static void 1884 dtlarg_lookup(void *obj) 1885 { 1886 LOOKUP4args *args = (LOOKUP4args *)obj; 1887 1888 detail_compname4(&args->objname); 1889 } 1890 1891 static void 1892 sumarg_read(char *buf, size_t buflen, void *obj) 1893 { 1894 READ4args *args = (READ4args *)obj; 1895 1896 snprintf(buf, buflen, "%s at %llu for %u", 1897 sum_stateid(&args->stateid), args->offset, args->count); 1898 } 1899 1900 static void 1901 dtlarg_read(void *obj) 1902 { 1903 READ4args *args = (READ4args *)obj; 1904 1905 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 1906 sprintf(get_line(0, 0), "Count = %u", args->count); 1907 detail_stateid(&args->stateid); 1908 } 1909 1910 static void 1911 sumarg_readdir(char *buf, size_t buflen, void *obj) 1912 { 1913 READDIR4args *args = (READDIR4args *)obj; 1914 1915 snprintf(buf, buflen, "Cookie=%llu (%s) for %u/%u", 1916 args->cookie, tohex(args->cookieverf, NFS4_VERIFIER_SIZE), 1917 args->dircount, args->maxcount); 1918 } 1919 1920 static void 1921 dtlarg_readdir(void *obj) 1922 { 1923 READDIR4args *args = (READDIR4args *)obj; 1924 1925 sprintf(get_line(0, 0), "Cookie = %llu", args->cookie); 1926 sprintf(get_line(0, 0), "Verifier = %s", 1927 tohex(args->cookieverf, NFS4_VERIFIER_SIZE)); 1928 sprintf(get_line(0, 0), "Dircount = %u", args->dircount); 1929 sprintf(get_line(0, 0), "Maxcount = %u", args->maxcount); 1930 detail_attr_bitmap("", &args->attr_request, NULL); 1931 } 1932 1933 static void 1934 dtlarg_release_lkown(void *obj) 1935 { 1936 RELEASE_LOCKOWNER4args *args = (RELEASE_LOCKOWNER4args *)obj; 1937 1938 detail_lock_owner(&args->lock_owner); 1939 } 1940 1941 static void 1942 sumarg_release_lkown(char *buf, size_t buflen, void *obj) 1943 { 1944 RELEASE_LOCKOWNER4args *args = (RELEASE_LOCKOWNER4args *)obj; 1945 1946 snprintf(buf, buflen, "LO=%04X", owner_hash(&args->lock_owner.owner)); 1947 } 1948 1949 static void 1950 sumarg_rename(char *buf, size_t buflen, void *obj) 1951 { 1952 RENAME4args *args = (RENAME4args *)obj; 1953 1954 snprintf(buf, buflen, "%s to %s", 1955 component_name(&args->oldname), 1956 component_name(&args->newname)); 1957 } 1958 1959 static void 1960 dtlarg_rename(void *obj) 1961 { 1962 RENAME4args *args = (RENAME4args *)obj; 1963 1964 sprintf(get_line(0, 0), "Old name = %s", 1965 component_name(&args->oldname)); 1966 sprintf(get_line(0, 0), "New name = %s", 1967 component_name(&args->newname)); 1968 } 1969 1970 static void 1971 sumarg_renew(char *buf, size_t buflen, void *obj) 1972 { 1973 RENEW4args *args = (RENEW4args *)obj; 1974 1975 snprintf(buf, buflen, "%s", sum_clientid(args->clientid)); 1976 } 1977 static void 1978 dtlarg_renew(void *obj) 1979 { 1980 RENEW4args *args = (RENEW4args *)obj; 1981 1982 detail_clientid(args->clientid); 1983 } 1984 1985 static void 1986 sumarg_secinfo(char *buf, size_t buflen, void *obj) 1987 { 1988 SECINFO4args *args = (SECINFO4args *)obj; 1989 1990 snprintf(buf, buflen, "%s", 1991 component_name(&args->name)); 1992 } 1993 1994 static void 1995 dtlarg_secinfo(void *obj) 1996 { 1997 SECINFO4args *args = (SECINFO4args *)obj; 1998 1999 sprintf(get_line(0, 0), "Name = %s", 2000 component_name(&args->name)); 2001 } 2002 2003 static void 2004 sumarg_setattr(char *buf, size_t buflen, void *obj) 2005 { 2006 SETATTR4args *args = (SETATTR4args *)obj; 2007 2008 snprintf(buf, buflen, "%s", sum_stateid(&args->stateid)); 2009 } 2010 2011 static void 2012 dtlarg_setattr(void *obj) 2013 { 2014 SETATTR4args *args = (SETATTR4args *)obj; 2015 2016 detail_stateid(&args->stateid); 2017 detail_fattr4(&args->obj_attributes); 2018 } 2019 2020 static void 2021 sumarg_setclid(char *buf, size_t buflen, void *obj) 2022 { 2023 SETCLIENTID4args *args = (SETCLIENTID4args *)obj; 2024 2025 snprintf(buf, buflen, "Prog=%u ID=%s Addr=%s CBID=%u", 2026 args->callback.cb_program, 2027 args->callback.cb_location.r_netid, 2028 args->callback.cb_location.r_addr, args->callback_ident); 2029 } 2030 2031 static void 2032 dtlarg_setclid(void *obj) 2033 { 2034 SETCLIENTID4args *args = (SETCLIENTID4args *)obj; 2035 2036 sprintf(get_line(0, 0), "Verifier=%s", 2037 tohex(args->client.verifier, NFS4_VERIFIER_SIZE)); 2038 sprintf(get_line(0, 0), "ID = (%d) %s", 2039 args->client.id.id_len, 2040 tohex(args->client.id.id_val, args->client.id.id_len)); 2041 2042 sprintf(get_line(0, 0), "Callback Program = %u", 2043 args->callback.cb_program); 2044 sprintf(get_line(0, 0), "Callback Net ID = %s", 2045 args->callback.cb_location.r_netid); 2046 sprintf(get_line(0, 0), "Callback Addr = %s", 2047 args->callback.cb_location.r_addr); 2048 sprintf(get_line(0, 0), "Callback Ident = %u", args->callback_ident); 2049 } 2050 2051 static void 2052 sumarg_setclid_cfm(char *buf, size_t buflen, void *obj) 2053 { 2054 SETCLIENTID_CONFIRM4args *args = (SETCLIENTID_CONFIRM4args *)obj; 2055 2056 snprintf(buf, buflen, "%s CFV=%s", sum_clientid(args->clientid), 2057 tohex(args->setclientid_confirm, NFS4_VERIFIER_SIZE)); 2058 } 2059 2060 static void 2061 dtlarg_setclid_cfm(void *obj) 2062 { 2063 SETCLIENTID_CONFIRM4args *args = (SETCLIENTID_CONFIRM4args *)obj; 2064 2065 detail_clientid(args->clientid); 2066 sprintf(get_line(0, 0), "Set Client ID Confirm Verifier = %s", 2067 tohex(args->setclientid_confirm, NFS4_VERIFIER_SIZE)); 2068 } 2069 2070 2071 static void 2072 dtlarg_verify(void *obj) 2073 { 2074 NVERIFY4args *args = (NVERIFY4args *)obj; 2075 2076 detail_fattr4(&args->obj_attributes); 2077 } 2078 2079 static void 2080 sumarg_write(char *buf, size_t buflen, void *obj) 2081 { 2082 WRITE4args *args = (WRITE4args *)obj; 2083 2084 snprintf(buf, buflen, "%s at %llu for %u", 2085 sum_stateid(&args->stateid), args->offset, args->data.data_len); 2086 } 2087 2088 static void 2089 dtlarg_write(void *obj) 2090 { 2091 WRITE4args *args = (WRITE4args *)obj; 2092 2093 sprintf(get_line(0, 0), "Offset = %llu", args->offset); 2094 sprintf(get_line(0, 0), "Count = %u", args->data.data_len); 2095 sprintf(get_line(0, 0), "Stable = %s", stable_how4_name(args->stable)); 2096 detail_stateid(&args->stateid); 2097 } 2098 2099 static char * 2100 sum_fh4(nfs_fh4 *fh) 2101 { 2102 static char buf[20]; 2103 2104 sprintf(buf, "FH=%04X", fh4_hash(fh)); 2105 2106 return (buf); 2107 } 2108 2109 static void 2110 detail_fh4(nfs_fh4 *fh) 2111 { 2112 int i; 2113 uchar_t *cp; 2114 char *bufp; 2115 2116 sprintf(get_line(0, 0), "File handle = [%04X]", fh4_hash(fh)); 2117 bufp = get_line(0, 0); 2118 sprintf(bufp, "(%d) ", fh->nfs_fh4_len); 2119 bufp += strlen(bufp); 2120 /* XXX use tohex()? */ 2121 for (i = 0, cp = (uchar_t *)fh->nfs_fh4_val; 2122 i < fh->nfs_fh4_len; 2123 i++, cp++) { 2124 if (i != 0 && i % 32 == 0) 2125 bufp = get_line(0, 0); 2126 sprintf(bufp, "%02x", *cp); 2127 bufp += strlen(bufp); 2128 } 2129 } 2130 2131 static void 2132 detail_fattr4(fattr4 *attrp) 2133 { 2134 unpkd_attrmap_t provided; 2135 uint_t attrnum; 2136 XDR attrxdr; 2137 jmp_buf old_errbuf; 2138 2139 xdrmem_create(&attrxdr, attrp->attr_vals.attrlist4_val, 2140 attrp->attr_vals.attrlist4_len, XDR_DECODE); 2141 2142 bcopy(xdr_err, old_errbuf, sizeof (old_errbuf)); 2143 if (setjmp(xdr_err)) { 2144 sprintf(get_line(0, 0), "<attr_vals too short>"); 2145 goto done; 2146 } 2147 2148 detail_attr_bitmap("", &attrp->attrmask, &provided); 2149 for (attrnum = 0; attrnum < MAX_ATTRIBUTES; attrnum++) { 2150 if (provided.map[attrnum]) { 2151 attr_info[attrnum].prt_details(&attrxdr); 2152 } 2153 } 2154 2155 done: 2156 bcopy(old_errbuf, xdr_err, sizeof (old_errbuf)); 2157 } 2158 2159 static void 2160 sum_attr_bitmap(char *buf, size_t buflen, bitmap4 *mapp) 2161 { 2162 uint_t num_words; 2163 char *bp; 2164 size_t curlen, remaining; 2165 2166 buf[0] = '\0'; 2167 for (num_words = 0; num_words < mapp->bitmap4_len; num_words++) { 2168 curlen = strlen(buf); 2169 if (curlen + sizeof ("<Too Long>") >= buflen) { 2170 strcpy(buf + buflen - sizeof ("<Too Long>"), 2171 "<Too Long>"); 2172 return; 2173 } 2174 bp = buf + curlen; 2175 remaining = buflen - curlen; 2176 snprintf(bp, remaining, 2177 num_words == 0 ? "%x" : " %x", 2178 mapp->bitmap4_val[num_words]); 2179 } 2180 } 2181 2182 /* 2183 * Print detail information for the given attribute bitmap, and fill in the 2184 * unpacked version of the map if "unpacked" is non-null. Returns the 2185 * number of bytes in the bitmap. "prefix" is an initial string that is 2186 * printed at the front of each line. 2187 */ 2188 2189 static void 2190 detail_attr_bitmap(char *prefix, bitmap4 *bitp, unpkd_attrmap_t *unpacked) 2191 { 2192 uint_t num_words; 2193 uint32_t *wp; 2194 uint_t byte_num; 2195 2196 if (unpacked != NULL) 2197 memset(unpacked, 0, sizeof (unpkd_attrmap_t)); 2198 2199 /* 2200 * Break the bitmap into octets, then print in hex and 2201 * symbolically. 2202 */ 2203 2204 for (num_words = 0, wp = bitp->bitmap4_val; 2205 num_words < bitp->bitmap4_len; 2206 num_words++, wp++) { 2207 for (byte_num = 0; byte_num < 4; byte_num++) { 2208 uchar_t val = (*wp) >> (byte_num * 8); 2209 char *buf = get_line(0, 0); 2210 uint_t attrnum; 2211 int bit; 2212 2213 sprintf(buf, "%s 0x%02x ", prefix, val); 2214 attrnum = num_words * 32 + byte_num * 8; 2215 for (bit = 7; bit >= 0; bit--) { 2216 if (val & (1 << bit)) { 2217 strcat(buf, " "); 2218 strcat(buf, 2219 attr_name(attrnum + bit)); 2220 if (unpacked != NULL) 2221 unpacked->map[attrnum + bit] = 2222 1; 2223 } 2224 } 2225 } 2226 } 2227 } 2228 2229 /* 2230 * Format the summary line results from a COMPOUND4 call. 2231 */ 2232 2233 static void 2234 sum_comp4res(char *line, char *(*sumres_fn)(void)) 2235 { 2236 nfsstat4 status; 2237 static utf8string tag; 2238 2239 status = getxdr_long(); 2240 if (!xdr_utf8string(&xdrm, &tag)) 2241 longjmp(xdr_err, 1); 2242 2243 sprintf(line, "(%.20s) %s %s", utf8localize(&tag), 2244 status_name(status), sumres_fn()); 2245 2246 xdr_free(xdr_utf8string, (char *)&tag); 2247 } 2248 2249 2250 /* 2251 * Return a set of summary strings for the result data that's next in the 2252 * XDR stream, up to SUM_COMPND_MAX characters. If the strings don't fit, 2253 * include a "..." at the end of the string. 2254 */ 2255 2256 static char * 2257 sum_compound4res(void) 2258 { 2259 static char buf[SUM_COMPND_MAX + 2]; /* 1 for null, 1 for overflow */ 2260 int numres; 2261 const size_t buflen = sizeof (buf); 2262 char *bp; 2263 nfs_resop4 one_res; 2264 2265 buf[0] = '\0'; 2266 if (setjmp(xdr_err)) { 2267 bp = buf + strlen(buf); 2268 snprintf(bp, buflen - (bp - buf), 2269 nfs4_fragged_rpc ? nfs4err_fragrpc : nfs4err_xdrfrag); 2270 return (buf); 2271 } 2272 2273 numres = getxdr_long(); 2274 bp = buf; 2275 while (numres-- > 0) { 2276 char *result; 2277 2278 bzero(&one_res, sizeof (one_res)); 2279 2280 if (!xdr_nfs_resop4(&xdrm, &one_res)) { 2281 xdr_free(xdr_nfs_resop4, (char *)&one_res); 2282 longjmp(xdr_err, 1); 2283 } 2284 2285 snprintf(bp, buflen - (bp - buf), "%s ", 2286 opcode_name(one_res.resop)); 2287 bp += strlen(bp); 2288 2289 result = sum_result(&one_res); 2290 if (strlen(result) > 0) { 2291 snprintf(bp, buflen - (bp - buf), "%s ", result); 2292 bp += strlen(bp); 2293 } 2294 2295 /* nfs4_skip_bytes set by xdr_nfs4_argop4() */ 2296 if (nfs4_skip_bytes != 0) 2297 nfs4_xdr_skip(nfs4_skip_bytes); 2298 2299 xdr_free(xdr_nfs_resop4, (char *)&one_res); 2300 /* add "..." if past the "end" of the buffer */ 2301 if (bp - buf > SUM_COMPND_MAX) { 2302 strcpy(buf + SUM_COMPND_MAX - strlen("..."), 2303 "..."); 2304 break; 2305 } 2306 } 2307 2308 return (buf); 2309 } 2310 2311 2312 /* 2313 * Return a set of summary strings for the result data that's next in the 2314 * XDR stream, up to SUM_COMPND_MAX characters. If the strings don't fit, 2315 * include a "..." at the end of the string. 2316 */ 2317 2318 static char * 2319 sum_cb_compound4res(void) 2320 { 2321 static char buf[SUM_COMPND_MAX + 2]; /* 1 for null, 1 for overflow */ 2322 int numres; 2323 const size_t buflen = sizeof (buf); 2324 char *bp; 2325 nfs_cb_resop4 one_res; 2326 2327 buf[0] = '\0'; 2328 if (setjmp(xdr_err)) { 2329 bp = buf + strlen(buf); 2330 snprintf(bp, buflen - (bp - buf), "<XDR Error or Fragmented" 2331 " RPC>"); 2332 return (buf); 2333 } 2334 2335 numres = getxdr_long(); 2336 bp = buf; 2337 while (numres-- > 0) { 2338 bzero(&one_res, sizeof (one_res)); 2339 if (!xdr_nfs_cb_resop4(&xdrm, &one_res)) { 2340 xdr_free(xdr_nfs_cb_resop4, (char *)&one_res); 2341 longjmp(xdr_err, 1); 2342 } 2343 snprintf(bp, buflen - (bp - buf), "%s %s ", 2344 cb_opcode_name(one_res.resop), 2345 sum_cb_result(&one_res)); 2346 bp += strlen(bp); 2347 2348 xdr_free(xdr_nfs_cb_resop4, (char *)&one_res); 2349 2350 /* add "..." if past the "end" of the buffer */ 2351 if (bp - buf > SUM_COMPND_MAX) { 2352 strcpy(buf + SUM_COMPND_MAX - strlen("..."), 2353 "..."); 2354 break; 2355 } 2356 } 2357 2358 return (buf); 2359 } 2360 2361 2362 /* 2363 * Return the summarized results for the given resultdata. 2364 */ 2365 2366 static char * 2367 sum_result(nfs_resop4 *resp) 2368 { 2369 static char buf[1024]; 2370 void (*fmtproc)(char *, size_t, void *); 2371 2372 buf[0] = '\0'; 2373 if (resp->resop < num_opcodes) 2374 fmtproc = opcode_info[resp->resop].sumres; 2375 else if (resp->resop == OP_ILLEGAL) 2376 fmtproc = sum_nfsstat4; 2377 else 2378 fmtproc = NULL; 2379 2380 if (fmtproc != NULL) 2381 fmtproc(buf, sizeof (buf), &resp->nfs_resop4_u); 2382 2383 return (buf); 2384 } 2385 2386 /* 2387 * Return the summarized results for the given resultdata. 2388 */ 2389 2390 static char * 2391 sum_cb_result(nfs_cb_resop4 *resp) 2392 { 2393 static char buf[1024]; 2394 void (*fmtproc)(char *, size_t, void *); 2395 2396 buf[0] = '\0'; 2397 if (resp->resop < cb_num_opcodes) 2398 fmtproc = cb_opcode_info[resp->resop].sumres; 2399 else if (resp->resop == OP_CB_ILLEGAL) 2400 fmtproc = sum_nfsstat4; 2401 else 2402 fmtproc = NULL; 2403 2404 if (fmtproc != NULL) 2405 fmtproc(buf, sizeof (buf), &resp->nfs_cb_resop4_u); 2406 2407 return (buf); 2408 } 2409 2410 2411 static void 2412 dtl_change_info(char *msg, change_info4 *infop) 2413 { 2414 sprintf(get_line(0, 0), "%s:", msg); 2415 sprintf(get_line(0, 0), " Atomic = %s", 2416 infop->atomic ? "TRUE" : "FALSE"); 2417 detail_fattr4_change(" Before", infop->before); 2418 detail_fattr4_change(" After", infop->after); 2419 } 2420 2421 static void 2422 detail_fattr4_change(char *msg, fattr4_change chg) 2423 { 2424 sprintf(get_line(0, 0), "%s: 0x%llx", msg, chg); 2425 /* XXX print as time_t, too? */ 2426 } 2427 2428 static void 2429 sum_nfsstat4(char *buf, size_t buflen, void *obj) 2430 { 2431 nfsstat4 status = *(nfsstat4 *)obj; 2432 2433 strncpy(buf, status_name(status), buflen); 2434 } 2435 2436 static void 2437 dtl_nfsstat4(void *obj) 2438 { 2439 nfsstat4 status = *(nfsstat4 *)obj; 2440 2441 sprintf(get_line(0, 0), "Status = %d (%s)", status, 2442 status_name(status)); 2443 } 2444 2445 static void 2446 sumres_access(char *buf, size_t buflen, void *obj) 2447 { 2448 ACCESS4res *res = (ACCESS4res *)obj; 2449 char *bp = buf; 2450 int len, blen = buflen; 2451 2452 strcpy(bp, status_name(res->status)); 2453 if (res->status == NFS4_OK) { 2454 bp += (len = strlen(bp)); 2455 blen -= len; 2456 2457 snprintf(bp, blen, " Supp="); 2458 bp += (len = strlen(bp)); 2459 blen -= len; 2460 2461 sum_access4(bp, blen, res->ACCESS4res_u.resok4.supported); 2462 bp += (len = strlen(bp)); 2463 blen -= len; 2464 2465 snprintf(bp, blen, " Allow="); 2466 bp += (len = strlen(bp)); 2467 blen -= len; 2468 2469 sum_access4(bp, blen, res->ACCESS4res_u.resok4.access); 2470 } 2471 } 2472 2473 static void 2474 dtlres_access(void *obj) 2475 { 2476 ACCESS4res *res = (ACCESS4res *)obj; 2477 2478 dtl_nfsstat4(obj); 2479 if (res->status == NFS4_OK) { 2480 detail_access4("Supported Attributes", 2481 res->ACCESS4res_u.resok4.supported); 2482 detail_access4("Allowed Attributes", 2483 res->ACCESS4res_u.resok4.access); 2484 } 2485 } 2486 2487 static void 2488 sumres_close(char *buf, size_t buflen, void *obj) 2489 { 2490 CLOSE4res *res = (CLOSE4res *)obj; 2491 2492 if (res->status == NFS4_OK) 2493 snprintf(buf, buflen, "%s", 2494 sum_open_stateid(&res->CLOSE4res_u.open_stateid)); 2495 } 2496 2497 static void 2498 dtlres_close(void *obj) 2499 { 2500 CLOSE4res *res = (CLOSE4res *)obj; 2501 2502 dtl_nfsstat4(obj); 2503 if (res->status == NFS4_OK) { 2504 detail_open_stateid(&res->CLOSE4res_u.open_stateid); 2505 } 2506 } 2507 2508 static void 2509 sumres_commit(char *buf, size_t buflen, void *obj) 2510 { 2511 COMMIT4res *res = (COMMIT4res *)obj; 2512 2513 if (res->status == NFS4_OK) 2514 snprintf(buf, buflen, "Verf=%s", 2515 tohex(res->COMMIT4res_u.resok4.writeverf, 2516 NFS4_VERIFIER_SIZE)); 2517 } 2518 2519 static void 2520 dtlres_commit(void *obj) 2521 { 2522 COMMIT4res *res = (COMMIT4res *)obj; 2523 2524 dtl_nfsstat4(obj); 2525 if (res->status == NFS4_OK) { 2526 sprintf(get_line(0, 0), "Verifier = %s", 2527 tohex(res->COMMIT4res_u.resok4.writeverf, 2528 NFS4_VERIFIER_SIZE)); 2529 } 2530 } 2531 2532 static void 2533 dtlres_create(void *obj) 2534 { 2535 CREATE4res *res = (CREATE4res *)obj; 2536 2537 dtl_nfsstat4(obj); 2538 if (res->status == NFS4_OK) { 2539 dtl_change_info("Change Information", 2540 &res->CREATE4res_u.resok4.cinfo); 2541 detail_attr_bitmap("", &res->CREATE4res_u.resok4.attrset, 2542 NULL); 2543 } 2544 } 2545 2546 static void 2547 sumres_getattr(char *buf, size_t buflen, void *obj) 2548 { 2549 GETATTR4res *res = (GETATTR4res *)obj; 2550 2551 strncpy(buf, status_name(res->status), buflen); 2552 } 2553 2554 static void 2555 dtlres_getattr(void *obj) 2556 { 2557 GETATTR4res *res = (GETATTR4res *)obj; 2558 2559 dtl_nfsstat4(obj); 2560 if (res->status == NFS4_OK) { 2561 detail_fattr4(&res->GETATTR4res_u.resok4.obj_attributes); 2562 } 2563 } 2564 2565 static void 2566 sumres_cb_getattr(char *buf, size_t buflen, void *obj) 2567 { 2568 CB_GETATTR4res *res = (CB_GETATTR4res *)obj; 2569 2570 strncpy(buf, status_name(res->status), buflen); 2571 } 2572 2573 static void 2574 dtlres_cb_getattr(void *obj) 2575 { 2576 CB_GETATTR4res *res = (CB_GETATTR4res *)obj; 2577 2578 dtl_nfsstat4(obj); 2579 if (res->status == NFS4_OK) { 2580 detail_fattr4(&res->CB_GETATTR4res_u.resok4.obj_attributes); 2581 } 2582 } 2583 2584 2585 static void 2586 sumres_getfh(char *buf, size_t buflen, void *obj) 2587 { 2588 char *bp; 2589 GETFH4res *res = (GETFH4res *)obj; 2590 2591 strncpy(buf, status_name(res->status), buflen); 2592 if (res->status == NFS4_OK) { 2593 bp = buf + strlen(buf); 2594 snprintf(bp, buflen - (bp - buf), " %s", 2595 sum_fh4(&res->GETFH4res_u.resok4.object)); 2596 } 2597 } 2598 2599 static void 2600 dtlres_getfh(void *obj) 2601 { 2602 GETFH4res *res = (GETFH4res *)obj; 2603 2604 dtl_nfsstat4(obj); 2605 if (res->status == NFS4_OK) { 2606 detail_fh4(&res->GETFH4res_u.resok4.object); 2607 } 2608 } 2609 2610 static void 2611 dtlres_link(void *obj) 2612 { 2613 LINK4res *res = (LINK4res *)obj; 2614 2615 dtl_nfsstat4(obj); 2616 if (res->status == NFS4_OK) { 2617 dtl_change_info("Change Information", 2618 &res->LINK4res_u.resok4.cinfo); 2619 } 2620 } 2621 2622 static void 2623 sumres_lock(char *buf, size_t buflen, void *obj) 2624 { 2625 char *bp; 2626 LOCK4res *res = (LOCK4res *)obj; 2627 2628 strncpy(buf, status_name(res->status), buflen); 2629 if (res->status == NFS4_OK) { 2630 bp = buf + strlen(buf); 2631 snprintf(bp, buflen - (bp - buf), " %s", 2632 sum_lock_stateid(&res->LOCK4res_u.resok4.lock_stateid)); 2633 } 2634 if (res->status == NFS4ERR_DENIED) { 2635 bp = buf + strlen(buf); 2636 snprintf(bp, buflen - (bp - buf), " %s", 2637 sum_lock_denied(&res->LOCK4res_u.denied)); 2638 } 2639 } 2640 2641 static void 2642 dtlres_lock(void *obj) 2643 { 2644 LOCK4res *res = (LOCK4res *)obj; 2645 2646 dtl_nfsstat4(obj); 2647 if (res->status == NFS4_OK) { 2648 detail_lock_stateid(&res->LOCK4res_u.resok4.lock_stateid); 2649 } 2650 if (res->status == NFS4ERR_DENIED) { 2651 detail_lock_denied(&res->LOCK4res_u.denied); 2652 } 2653 } 2654 2655 static void 2656 sumres_lockt(char *buf, size_t buflen, void *obj) 2657 { 2658 char *bp; 2659 LOCKT4res *res = (LOCKT4res *)obj; 2660 2661 strcpy(buf, status_name(res->status)); 2662 if (res->status == NFS4ERR_DENIED) { 2663 bp = buf + strlen(buf); 2664 snprintf(bp, buflen - (bp - buf), " %s", 2665 sum_lock_denied(&res->LOCKT4res_u.denied)); 2666 } 2667 } 2668 2669 static void 2670 dtlres_lockt(void *obj) 2671 { 2672 LOCKT4res *res = (LOCKT4res *)obj; 2673 2674 dtl_nfsstat4(obj); 2675 if (res->status == NFS4ERR_DENIED) { 2676 detail_lock_denied(&res->LOCKT4res_u.denied); 2677 } 2678 } 2679 2680 static void 2681 sumres_locku(char *buf, size_t buflen, void *obj) 2682 { 2683 char *bp; 2684 LOCKU4res *res = (LOCKU4res *)obj; 2685 2686 strncpy(buf, status_name(res->status), buflen); 2687 bp = buf + strlen(buf); 2688 if (res->status == NFS4_OK) 2689 snprintf(bp, buflen - (bp - buf), " %s", 2690 sum_lock_stateid(&res->LOCKU4res_u.lock_stateid)); 2691 } 2692 2693 static void 2694 dtlres_locku(void *obj) 2695 { 2696 LOCKU4res *res = (LOCKU4res *)obj; 2697 2698 dtl_nfsstat4(obj); 2699 if (res->status == NFS4_OK) 2700 detail_lock_stateid(&res->LOCKU4res_u.lock_stateid); 2701 } 2702 2703 static void 2704 sumres_open(char *buf, size_t buflen, void *obj) 2705 { 2706 char *bp = buf; 2707 OPEN4res *res = (OPEN4res *)obj; 2708 uint_t rflags; 2709 int len, blen = buflen; 2710 2711 strncpy(bp, status_name(res->status), blen); 2712 2713 if (res->status == NFS4_OK) { 2714 bp += (len = strlen(bp)); 2715 blen -= len; 2716 2717 snprintf(bp, blen, " %s", 2718 sum_stateid(&res->OPEN4res_u.resok4.stateid)); 2719 bp += (len = strlen(bp)); 2720 blen -= len; 2721 2722 if ((rflags = res->OPEN4res_u.resok4.rflags) != 0) { 2723 snprintf(bp, blen, "%s", sum_open_rflags(rflags)); 2724 bp += (len = strlen(bp)); 2725 blen -= len; 2726 } 2727 2728 sum_delegation(bp, blen, &res->OPEN4res_u.resok4.delegation); 2729 } 2730 } 2731 2732 static void 2733 dtlres_open(void *obj) 2734 { 2735 OPEN4res *res = (OPEN4res *)obj; 2736 2737 dtl_nfsstat4(obj); 2738 if (res->status == NFS4_OK) { 2739 detail_stateid(&res->OPEN4res_u.resok4.stateid); 2740 dtl_change_info("Change Information", 2741 &res->OPEN4res_u.resok4.cinfo); 2742 sprintf(get_line(0, 0), "Flags = 0x%x (%s)", 2743 res->OPEN4res_u.resok4.rflags, 2744 detail_open_rflags(res->OPEN4res_u.resok4.rflags)); 2745 detail_attr_bitmap("", &res->OPEN4res_u.resok4.attrset, 2746 NULL); 2747 detail_delegation(&res->OPEN4res_u.resok4.delegation); 2748 } 2749 } 2750 2751 static void 2752 sumres_open_confirm(char *buf, size_t buflen, void *obj) 2753 { 2754 char *bp; 2755 OPEN_CONFIRM4res *res = (OPEN_CONFIRM4res *)obj; 2756 2757 strncpy(buf, status_name(res->status), buflen); 2758 if (res->status == NFS4_OK) { 2759 bp = buf + strlen(buf); 2760 snprintf(bp, buflen - (bp - buf), " %s", 2761 sum_open_stateid(&res->OPEN_CONFIRM4res_u.resok4. 2762 open_stateid)); 2763 } 2764 } 2765 2766 static void 2767 dtlres_open_confirm(void *obj) 2768 { 2769 OPEN_CONFIRM4res *res = (OPEN_CONFIRM4res *)obj; 2770 2771 dtl_nfsstat4(obj); 2772 if (res->status == NFS4_OK) { 2773 detail_open_stateid(&res->OPEN_CONFIRM4res_u.resok4. 2774 open_stateid); 2775 } 2776 } 2777 2778 static void 2779 sumres_open_downgrd(char *buf, size_t buflen, void *obj) 2780 { 2781 char *bp; 2782 OPEN_DOWNGRADE4res *res = (OPEN_DOWNGRADE4res *)obj; 2783 2784 strncpy(buf, status_name(res->status), buflen); 2785 if (res->status == NFS4_OK) { 2786 bp = buf + strlen(buf); 2787 snprintf(bp, buflen - (bp - buf), " %s", 2788 sum_open_stateid(&res->OPEN_DOWNGRADE4res_u.resok4. 2789 open_stateid)); 2790 } 2791 } 2792 2793 static void 2794 dtlres_open_downgrd(void *obj) 2795 { 2796 OPEN_DOWNGRADE4res *res = (OPEN_DOWNGRADE4res *)obj; 2797 2798 dtl_nfsstat4(obj); 2799 if (res->status == NFS4_OK) { 2800 detail_open_stateid(&res->OPEN_DOWNGRADE4res_u.resok4. 2801 open_stateid); 2802 } 2803 } 2804 2805 static void 2806 sumres_read(char *buf, size_t buflen, void *obj) 2807 { 2808 char *bp; 2809 READ4res *res = (READ4res *)obj; 2810 2811 strncpy(buf, status_name(res->status), buflen); 2812 if (res->status == NFS4_OK) { 2813 bp = buf + strlen(buf); 2814 snprintf(bp, buflen - (bp - buf), " (%u bytes) %s", 2815 res->READ4res_u.resok4.data.data_len, 2816 res->READ4res_u.resok4.eof ? "EOF" : ""); 2817 } 2818 } 2819 2820 static void 2821 dtlres_read(void *obj) 2822 { 2823 READ4res *res = (READ4res *)obj; 2824 2825 dtl_nfsstat4(obj); 2826 if (res->status == NFS4_OK) { 2827 sprintf(get_line(0, 0), "Count = %u bytes read", 2828 res->READ4res_u.resok4.data.data_len); 2829 sprintf(get_line(0, 0), "End of file = %s", 2830 res->READ4res_u.resok4.eof ? "TRUE" : "FALSE"); 2831 } 2832 } 2833 2834 static void 2835 sumres_readdir(char *buf, size_t buflen, void *obj) 2836 { 2837 char *bp; 2838 READDIR4res *res = (READDIR4res *)obj; 2839 int num_entries = 0; 2840 entry4 *ep; 2841 2842 strncpy(buf, status_name(res->status), buflen); 2843 if (res->status == NFS4_OK) { 2844 for (ep = res->READDIR4res_u.resok4.reply.entries; 2845 ep != NULL; 2846 ep = ep->nextentry) 2847 num_entries++; 2848 bp = buf + strlen(buf); 2849 snprintf(bp, buflen - (bp - buf), " %d entries (%s)", 2850 num_entries, 2851 res->READDIR4res_u.resok4.reply.eof 2852 ? "No more" : "More"); 2853 } 2854 } 2855 2856 static void 2857 dtlres_readdir(void *obj) 2858 { 2859 READDIR4res *res = (READDIR4res *)obj; 2860 int num_entries = 0; 2861 entry4 *ep; 2862 2863 dtl_nfsstat4(obj); 2864 if (res->status == NFS4_OK) { 2865 for (ep = res->READDIR4res_u.resok4.reply.entries; 2866 ep != NULL; 2867 ep = ep->nextentry) { 2868 num_entries++; 2869 sprintf(get_line(0, 0), 2870 "------------------ entry #%d", 2871 num_entries); 2872 sprintf(get_line(0, 0), "Cookie = %llu", 2873 ep->cookie); 2874 sprintf(get_line(0, 0), "Name = %s", 2875 component_name(&ep->name)); 2876 detail_fattr4(&ep->attrs); 2877 } 2878 if (num_entries == 0) 2879 sprintf(get_line(0, 0), "(No entries)"); 2880 sprintf(get_line(0, 0), "EOF = %s", 2881 res->READDIR4res_u.resok4.reply.eof ? "TRUE" : "FALSE"); 2882 sprintf(get_line(0, 0), "Verifer = %s", 2883 tohex(res->READDIR4res_u.resok4.cookieverf, 2884 NFS4_VERIFIER_SIZE)); 2885 } 2886 } 2887 2888 static void 2889 sumres_readlnk(char *buf, size_t buflen, void *obj) 2890 { 2891 char *bp; 2892 READLINK4res *res = (READLINK4res *)obj; 2893 2894 strncpy(buf, status_name(res->status), buflen); 2895 if (res->status == NFS4_OK) { 2896 bp = buf + strlen(buf); 2897 snprintf(bp, buflen - (bp - buf), " %s", 2898 linktext_name(&res->READLINK4res_u.resok4.link)); 2899 } 2900 } 2901 2902 static void 2903 dtlres_readlnk(void *obj) 2904 { 2905 READLINK4res *res = (READLINK4res *)obj; 2906 2907 dtl_nfsstat4(obj); 2908 if (res->status == NFS4_OK) { 2909 sprintf(get_line(0, 0), "Link = %s", 2910 linktext_name(&res->READLINK4res_u.resok4.link)); 2911 } 2912 } 2913 2914 static void 2915 dtlres_remove(void *obj) 2916 { 2917 REMOVE4res *res = (REMOVE4res *)obj; 2918 2919 dtl_nfsstat4(obj); 2920 if (res->status == NFS4_OK) { 2921 dtl_change_info("Change Information", 2922 &res->REMOVE4res_u.resok4.cinfo); 2923 } 2924 } 2925 2926 static void 2927 dtlres_rename(void *obj) 2928 { 2929 RENAME4res *res = (RENAME4res *)obj; 2930 2931 dtl_nfsstat4(obj); 2932 if (res->status == NFS4_OK) { 2933 dtl_change_info("Source Change Information", 2934 &res->RENAME4res_u.resok4.source_cinfo); 2935 dtl_change_info("Target Change Information", 2936 &res->RENAME4res_u.resok4.target_cinfo); 2937 } 2938 } 2939 2940 static void 2941 sumres_secinfo(char *buf, size_t buflen, void *obj) 2942 { 2943 char *bp; 2944 SECINFO4res *res = (SECINFO4res *)obj; 2945 2946 strncpy(buf, status_name(res->status), buflen); 2947 bp = buf + strlen(buf); 2948 if (res->status == NFS4_OK) { 2949 uint_t numinfo = res->SECINFO4res_u.resok4.SECINFO4resok_len; 2950 secinfo4 *infop; 2951 2952 for (infop = res->SECINFO4res_u.resok4.SECINFO4resok_val; 2953 numinfo != 0; 2954 infop++, numinfo--) { 2955 snprintf(bp, buflen - (bp - buf), " %s", 2956 flavor_name(infop->flavor)); 2957 bp += strlen(bp); 2958 } 2959 } 2960 } 2961 2962 static void 2963 dtlres_secinfo(void *obj) 2964 { 2965 SECINFO4res *res = (SECINFO4res *)obj; 2966 2967 dtl_nfsstat4(obj); 2968 if (res->status == NFS4_OK) { 2969 uint_t numinfo = 2970 res->SECINFO4res_u.resok4.SECINFO4resok_len; 2971 secinfo4 *infop; 2972 2973 for (infop = res->SECINFO4res_u.resok4.SECINFO4resok_val; 2974 numinfo != 0; 2975 infop++, numinfo--) { 2976 detail_secinfo4(infop); 2977 } 2978 } 2979 } 2980 2981 static void 2982 sumres_setattr(char *buf, size_t buflen, void *obj) 2983 { 2984 SETATTR4res *res = (SETATTR4res *)obj; 2985 size_t len; 2986 2987 (void) snprintf(buf, buflen, "%s ", status_name(res->status)); 2988 len = strlen(buf); 2989 sum_attr_bitmap(buf + len, buflen - len, &res->attrsset); 2990 } 2991 2992 static void 2993 dtlres_setattr(void *obj) 2994 { 2995 SETATTR4res *res = (SETATTR4res *)obj; 2996 2997 dtl_nfsstat4(obj); 2998 detail_attr_bitmap("", &res->attrsset, NULL); 2999 } 3000 3001 static void 3002 sumres_setclid(char *buf, size_t buflen, void *obj) 3003 { 3004 char *bp; 3005 SETCLIENTID4res *res = (SETCLIENTID4res *)obj; 3006 3007 strncpy(buf, status_name(res->status), buflen); 3008 switch (res->status) { 3009 case NFS_OK: 3010 bp = buf + strlen(buf); 3011 snprintf(bp, buflen - (bp - buf), " %s CFV=%s", 3012 sum_clientid(res->SETCLIENTID4res_u.resok4.clientid), 3013 tohex(res->SETCLIENTID4res_u.resok4.setclientid_confirm, 3014 NFS4_VERIFIER_SIZE)); 3015 break; 3016 case NFS4ERR_CLID_INUSE: 3017 bp = buf + strlen(buf); 3018 snprintf(bp, buflen - (bp - buf), " ID=%s Addr=%s", 3019 res->SETCLIENTID4res_u.client_using.r_netid, 3020 res->SETCLIENTID4res_u.client_using.r_addr); 3021 break; 3022 } 3023 } 3024 3025 static void 3026 dtlres_setclid(void *obj) 3027 { 3028 SETCLIENTID4res *res = (SETCLIENTID4res *)obj; 3029 3030 dtl_nfsstat4(obj); 3031 switch (res->status) { 3032 case NFS_OK: 3033 detail_clientid(res->SETCLIENTID4res_u.resok4.clientid); 3034 sprintf(get_line(0, 0), "Set Client ID Confirm Verifier = %s", 3035 tohex(res->SETCLIENTID4res_u.resok4.setclientid_confirm, 3036 NFS4_VERIFIER_SIZE)); 3037 break; 3038 case NFS4ERR_CLID_INUSE: 3039 sprintf(get_line(0, 0), "Used by Net ID = %s", 3040 res->SETCLIENTID4res_u.client_using.r_netid); 3041 sprintf(get_line(0, 0), "Used by Addr = %s", 3042 res->SETCLIENTID4res_u.client_using.r_addr); 3043 break; 3044 } 3045 } 3046 3047 static void 3048 sumres_write(char *buf, size_t buflen, void *obj) 3049 { 3050 char *bp; 3051 WRITE4res *res = (WRITE4res *)obj; 3052 3053 strncpy(buf, status_name(res->status), buflen); 3054 if (res->status == NFS4_OK) { 3055 bp = buf + strlen(buf); 3056 snprintf(bp, buflen - (bp - buf), " %u (%s)", 3057 res->WRITE4res_u.resok4.count, 3058 stable_how4_name(res->WRITE4res_u.resok4.committed)); 3059 } 3060 } 3061 3062 static void 3063 dtlres_write(void *obj) 3064 { 3065 WRITE4res *res = (WRITE4res *)obj; 3066 3067 dtl_nfsstat4(obj); 3068 if (res->status == NFS4_OK) { 3069 sprintf(get_line(0, 0), "Count = %u bytes written", 3070 res->WRITE4res_u.resok4.count); 3071 sprintf(get_line(0, 0), "Stable = %s", 3072 stable_how4_name(res->WRITE4res_u.resok4.committed)); 3073 sprintf(get_line(0, 0), "Verifier = %s", 3074 tohex(res->WRITE4res_u.resok4.writeverf, 3075 NFS4_VERIFIER_SIZE)); 3076 } 3077 } 3078 3079 /* 3080 * Print details about the nfs_resop4 that is next in the XDR stream. 3081 */ 3082 3083 static void 3084 detail_nfs_resop4(void) 3085 { 3086 int numres; 3087 nfs_resop4 one_res; 3088 void (*fmtproc)(void *); 3089 3090 numres = getxdr_long(); 3091 (void) sprintf(get_line(0, 0), "Number of results = %d", 3092 numres); 3093 3094 while (numres-- > 0) { 3095 bzero(&one_res, sizeof (one_res)); 3096 3097 if (!xdr_nfs_resop4(&xdrm, &one_res)) { 3098 xdr_free(xdr_nfs_resop4, (char *)&one_res); 3099 longjmp(xdr_err, 1); 3100 } 3101 3102 get_line(0, 0); /* blank line to separate ops */ 3103 sprintf(get_line(0, 0), "Op = %d (%s)", 3104 one_res.resop, opcode_name(one_res.resop)); 3105 if (one_res.resop < num_opcodes) 3106 fmtproc = opcode_info[one_res.resop].dtlres; 3107 else if (one_res.resop == OP_ILLEGAL) 3108 fmtproc = dtl_nfsstat4; 3109 else 3110 fmtproc = NULL; 3111 3112 if (fmtproc != NULL) 3113 fmtproc(&one_res.nfs_resop4_u); 3114 3115 /* nfs4_skip_bytes set by xdr_nfs_resop4()() */ 3116 if (nfs4_skip_bytes) 3117 nfs4_xdr_skip(nfs4_skip_bytes); 3118 3119 xdr_free(xdr_nfs_resop4, (char *)&one_res); 3120 } 3121 } 3122 3123 3124 /* 3125 * Print details about the nfs_cb_resop4 that is next in the XDR stream. 3126 */ 3127 3128 static void 3129 detail_cb_resop4(void) 3130 { 3131 int numres; 3132 nfs_cb_resop4 one_res; 3133 void (*fmtproc)(void *); 3134 3135 numres = getxdr_long(); 3136 (void) sprintf(get_line(0, 0), "Number of results = %d", 3137 numres); 3138 3139 while (numres-- > 0) { 3140 bzero(&one_res, sizeof (one_res)); 3141 if (!xdr_nfs_cb_resop4(&xdrm, &one_res)) 3142 longjmp(xdr_err, 1); 3143 3144 get_line(0, 0); /* blank line to separate ops */ 3145 sprintf(get_line(0, 0), "Op = %d (%s)", 3146 one_res.resop, cb_opcode_name(one_res.resop)); 3147 if (one_res.resop < cb_num_opcodes) 3148 fmtproc = cb_opcode_info[one_res.resop].dtlres; 3149 else if (one_res.resop == OP_CB_ILLEGAL) 3150 fmtproc = dtl_nfsstat4; 3151 else 3152 fmtproc = NULL; 3153 3154 if (fmtproc != NULL) 3155 fmtproc(&one_res.nfs_cb_resop4_u); 3156 3157 xdr_free(xdr_nfs_cb_resop4, (char *)&one_res); 3158 } 3159 } 3160 3161 3162 /* 3163 * Return the name of a lock type. 3164 */ 3165 static char * 3166 lock_type_name(enum nfs_lock_type4 type) 3167 { 3168 char *result; 3169 3170 switch (type) { 3171 case READ_LT: 3172 result = "READ"; 3173 break; 3174 case WRITE_LT: 3175 result = "WRITE"; 3176 break; 3177 case READW_LT: 3178 result = "READW"; 3179 break; 3180 case WRITEW_LT: 3181 result = "WRITEW"; 3182 break; 3183 default: 3184 result = "?"; 3185 break; 3186 } 3187 3188 return (result); 3189 } 3190 3191 /* 3192 * Return the name of an opcode. 3193 */ 3194 3195 static char * 3196 opcode_name(uint_t opnum) 3197 { 3198 static char buf[20]; 3199 3200 if (opnum < num_opcodes) 3201 return (opcode_info[opnum].name); 3202 3203 if (opnum == OP_ILLEGAL) 3204 return ("ILLEGAL"); 3205 3206 sprintf(buf, "op %d", opnum); 3207 return (buf); 3208 } 3209 3210 /* 3211 * Return the name of an opcode. 3212 */ 3213 static char * 3214 cb_opcode_name(uint_t opnum) 3215 { 3216 static char buf[20]; 3217 3218 if (opnum < cb_num_opcodes) 3219 return (cb_opcode_info[opnum].name); 3220 3221 if (opnum == OP_CB_ILLEGAL) 3222 return ("CB_ILLEGAL"); 3223 3224 sprintf(buf, "op %d", opnum); 3225 return (buf); 3226 } 3227 3228 3229 /* 3230 * Fill in a summary string for the given access bitmask. 3231 */ 3232 3233 static void 3234 sum_access4(char *buf, size_t buflen, uint32_t bits) 3235 { 3236 buf[0] = '\0'; 3237 3238 if (bits & ACCESS4_READ) 3239 (void) strncat(buf, "rd,", buflen); 3240 if (bits & ACCESS4_LOOKUP) 3241 (void) strncat(buf, "lk,", buflen); 3242 if (bits & ACCESS4_MODIFY) 3243 (void) strncat(buf, "mo,", buflen); 3244 if (bits & ACCESS4_EXTEND) 3245 (void) strncat(buf, "ext,", buflen); 3246 if (bits & ACCESS4_DELETE) 3247 (void) strncat(buf, "dl,", buflen); 3248 if (bits & ACCESS4_EXECUTE) 3249 (void) strncat(buf, "exc,", buflen); 3250 if (buf[0] != '\0') 3251 buf[strlen(buf) - 1] = '\0'; 3252 } 3253 3254 /* 3255 * Print detail information about the given access bitmask. 3256 */ 3257 3258 static void 3259 detail_access4(char *descrip, uint32_t bits) 3260 { 3261 sprintf(get_line(0, 0), "%s = 0x%08x", descrip, bits); 3262 3263 (void) sprintf(get_line(0, 0), " %s", 3264 getflag(bits, ACCESS4_READ, "Read", "(no read)")); 3265 (void) sprintf(get_line(0, 0), " %s", 3266 getflag(bits, ACCESS4_LOOKUP, "Lookup", "(no lookup)")); 3267 (void) sprintf(get_line(0, 0), " %s", 3268 getflag(bits, ACCESS4_MODIFY, "Modify", "(no modify)")); 3269 (void) sprintf(get_line(0, 0), " %s", 3270 getflag(bits, ACCESS4_EXTEND, "Extend", "(no extend)")); 3271 (void) sprintf(get_line(0, 0), " %s", 3272 getflag(bits, ACCESS4_DELETE, "Delete", "(no delete)")); 3273 (void) sprintf(get_line(0, 0), " %s", 3274 getflag(bits, ACCESS4_EXECUTE, "Execute", "(no execute)")); 3275 } 3276 3277 3278 /* 3279 * Fill in a summary string for the given open_claim4. 3280 */ 3281 static void 3282 sum_name(char *buf, size_t buflen, open_claim4 *claim) 3283 { 3284 char *bp = buf; 3285 3286 switch (claim->claim) { 3287 case CLAIM_NULL: 3288 snprintf(bp, buflen, "%s ", 3289 component_name(&claim->open_claim4_u.file)); 3290 break; 3291 case CLAIM_PREVIOUS: 3292 break; 3293 case CLAIM_DELEGATE_CUR: 3294 snprintf(bp, buflen, "%s ", 3295 component_name(&claim->open_claim4_u. 3296 delegate_cur_info.file)); 3297 break; 3298 case CLAIM_DELEGATE_PREV: 3299 snprintf(bp, buflen, "%s ", 3300 component_name(&claim->open_claim4_u. 3301 file_delegate_prev)); 3302 break; 3303 } 3304 } 3305 3306 /* 3307 * Fill in a summary string for the given open_claim4. 3308 */ 3309 static void 3310 sum_claim(char *buf, size_t buflen, open_claim4 *claim) 3311 { 3312 char *bp = buf; 3313 3314 switch (claim->claim) { 3315 case CLAIM_NULL: 3316 snprintf(bp, buflen, " CT=N"); 3317 break; 3318 case CLAIM_PREVIOUS: 3319 snprintf(bp, buflen, " CT=P DT=%s", 3320 get_deleg_typestr(claim->open_claim4_u.delegate_type)); 3321 break; 3322 case CLAIM_DELEGATE_CUR: 3323 snprintf(bp, buflen, " CT=DC %s", 3324 sum_deleg_stateid(&claim->open_claim4_u. 3325 delegate_cur_info.delegate_stateid)); 3326 break; 3327 case CLAIM_DELEGATE_PREV: 3328 snprintf(bp, buflen, " CT=DP"); 3329 break; 3330 default: 3331 snprintf(bp, buflen, " CT=?"); 3332 break; 3333 } 3334 } 3335 3336 static char * 3337 get_deleg_typestr(open_delegation_type4 dt) 3338 { 3339 char *str = ""; 3340 3341 switch (dt) { 3342 case OPEN_DELEGATE_NONE: 3343 str = "N"; 3344 break; 3345 case OPEN_DELEGATE_READ: 3346 str = "R"; 3347 break; 3348 case OPEN_DELEGATE_WRITE: 3349 str = "W"; 3350 break; 3351 default: 3352 str = "?"; 3353 } 3354 3355 return (str); 3356 } 3357 3358 /* 3359 * Print detail information for the given open_claim4. 3360 */ 3361 3362 static void 3363 detail_claim(open_claim4 *claim) 3364 { 3365 sprintf(get_line(0, 0), "Claim Type = %d (%s)", 3366 claim->claim, claim_name(claim->claim)); 3367 3368 switch (claim->claim) { 3369 case CLAIM_NULL: 3370 detail_compname4(&claim->open_claim4_u.file); 3371 break; 3372 case CLAIM_PREVIOUS: 3373 sprintf(get_line(0, 0), "Delegate Type = %s (val = %d)", 3374 get_deleg_typestr(claim->open_claim4_u.delegate_type), 3375 claim->open_claim4_u.delegate_type); 3376 break; 3377 case CLAIM_DELEGATE_CUR: 3378 detail_compname4(&claim->open_claim4_u.delegate_cur_info.file); 3379 detail_deleg_stateid(&claim->open_claim4_u.delegate_cur_info. 3380 delegate_stateid); 3381 break; 3382 case CLAIM_DELEGATE_PREV: 3383 detail_compname4(&claim->open_claim4_u.file_delegate_prev); 3384 break; 3385 } 3386 } 3387 3388 /* 3389 * Return a summary string for the given clientid4. 3390 */ 3391 static char * 3392 sum_clientid(clientid4 client) 3393 { 3394 static char buf[50]; 3395 3396 snprintf(buf, sizeof (buf), "CL=%llx", client); 3397 3398 return (buf); 3399 } 3400 3401 /* 3402 * Print a detail string for the given clientid4. 3403 */ 3404 static void 3405 detail_clientid(clientid4 client) 3406 { 3407 sprintf(get_line(0, 0), "Client ID = %llx", client); 3408 } 3409 3410 /* 3411 * Write a summary string for the given delegation into buf. 3412 */ 3413 3414 static void 3415 sum_delegation(char *buf, size_t buflen, open_delegation4 *delp) 3416 { 3417 switch (delp->delegation_type) { 3418 case OPEN_DELEGATE_NONE: 3419 snprintf(buf, buflen, " DT=N"); 3420 break; 3421 case OPEN_DELEGATE_READ: 3422 snprintf(buf, buflen, " DT=R %s", 3423 sum_deleg_stateid(&delp->open_delegation4_u.write. 3424 stateid)); 3425 break; 3426 case OPEN_DELEGATE_WRITE: 3427 snprintf(buf, buflen, " DT=W %s %s", 3428 sum_deleg_stateid(&delp->open_delegation4_u.write. 3429 stateid), 3430 sum_space_limit(&delp->open_delegation4_u.write. 3431 space_limit)); 3432 break; 3433 default: 3434 snprintf(buf, buflen, " DT=?"); 3435 break; 3436 } 3437 } 3438 3439 static void 3440 detail_delegation(open_delegation4 *delp) 3441 { 3442 sprintf(get_line(0, 0), "Delegation Type = %d (%s)", 3443 delp->delegation_type, 3444 delegation_type_name(delp->delegation_type)); 3445 3446 switch (delp->delegation_type) { 3447 case OPEN_DELEGATE_NONE: 3448 /* no-op */ 3449 break; 3450 case OPEN_DELEGATE_READ: 3451 detail_deleg_stateid(&delp->open_delegation4_u.read.stateid); 3452 sprintf(get_line(0, 0), "Recall = %s", 3453 delp->open_delegation4_u.read.recall ? 3454 "TRUE" : "FALSE"); 3455 sprintf(get_line(0, 0), "[nfsacl4]"); 3456 break; 3457 case OPEN_DELEGATE_WRITE: 3458 detail_deleg_stateid(&delp->open_delegation4_u.write.stateid); 3459 sprintf(get_line(0, 0), "Recall = %s", 3460 delp->open_delegation4_u.write.recall ? 3461 "TRUE" : "FALSE"); 3462 detail_space_limit(&delp->open_delegation4_u.write. 3463 space_limit); 3464 sprintf(get_line(0, 0), "[nfsacl4]"); 3465 break; 3466 } 3467 } 3468 3469 3470 static void 3471 detail_open_owner(open_owner4 *owner) 3472 { 3473 sprintf(get_line(0, 0), "Open Owner hash = [%04X] ", 3474 owner_hash(&owner->owner)); 3475 sprintf(get_line(0, 0), " len = %u val = %s ", 3476 owner->owner.owner_len, 3477 tohex(owner->owner.owner_val, owner->owner.owner_len)); 3478 detail_clientid(owner->clientid); 3479 } 3480 3481 static void 3482 detail_lock_owner(lock_owner4 *owner) 3483 { 3484 sprintf(get_line(0, 0), "Lock Owner hash = [%04X] ", 3485 owner_hash(&owner->owner)); 3486 sprintf(get_line(0, 0), " len = %u val = %s ", 3487 owner->owner.owner_len, 3488 tohex(owner->owner.owner_val, owner->owner.owner_len)); 3489 detail_clientid(owner->clientid); 3490 } 3491 3492 static void 3493 sum_openflag(char *bufp, int buflen, openflag4 *flagp) 3494 { 3495 if (flagp->opentype == OPEN4_CREATE) { 3496 switch (flagp->openflag4_u.how.mode) { 3497 case UNCHECKED4: 3498 snprintf(bufp, buflen, "OT=CR(U)"); 3499 break; 3500 case GUARDED4: 3501 snprintf(bufp, buflen, "OT=CR(G)"); 3502 break; 3503 case EXCLUSIVE4: 3504 snprintf(bufp, buflen, "OT=CR(E)"); 3505 break; 3506 default: 3507 snprintf(bufp, buflen, "OT=CR(?:%d)", 3508 flagp->openflag4_u.how.mode); 3509 break; 3510 } 3511 } else 3512 snprintf(bufp, buflen, "OT=NC"); 3513 } 3514 3515 static void 3516 detail_openflag(openflag4 *flagp) 3517 { 3518 sprintf(get_line(0, 0), "Open Type = %s", 3519 flagp->opentype == OPEN4_CREATE ? "CREATE" : "NOCREATE"); 3520 if (flagp->opentype == OPEN4_CREATE) 3521 detail_createhow4(&flagp->openflag4_u.how); 3522 } 3523 3524 /* 3525 * Fill in buf with the given path. 3526 */ 3527 static void 3528 sum_pathname4(char *buf, size_t buflen, pathname4 *pathp) 3529 { 3530 char *bp = buf; 3531 uint_t component; 3532 3533 for (component = 0; component < pathp->pathname4_len; 3534 component++) { 3535 snprintf(bp, buflen - (bp - buf), 3536 component == 0 ? "%s" : "/%s", 3537 component_name(&pathp->pathname4_val[component])); 3538 bp += strlen(bp); 3539 } 3540 } 3541 3542 static void 3543 sum_compname4(char *buf, size_t buflen, component4 *comp) 3544 { 3545 snprintf(buf, buflen, "%s", component_name(comp)); 3546 } 3547 3548 static void 3549 detail_compname4(component4 *comp) 3550 { 3551 sprintf(get_line(0, 0), "%s", component_name(comp)); 3552 } 3553 3554 static void 3555 detail_pathname4(pathname4 *pathp, char *what) 3556 { 3557 char *bp = get_line(0, 0); 3558 uint_t component; 3559 3560 sprintf(bp, what); 3561 bp += strlen(bp); 3562 3563 for (component = 0; component < pathp->pathname4_len; component++) { 3564 sprintf(bp, component == 0 ? "%s" : "/%s", 3565 component_name(&pathp->pathname4_val[component])); 3566 bp += strlen(bp); 3567 } 3568 } 3569 3570 /* 3571 * Print detail information about the rpcsec_gss_info that is XDR-encoded 3572 * at mem. 3573 */ 3574 3575 static void 3576 detail_rpcsec_gss(rpcsec_gss_info *info) 3577 { 3578 sprintf(get_line(0, 0), "OID = %s", 3579 tohex(info->oid.sec_oid4_val, info->oid.sec_oid4_len)); 3580 sprintf(get_line(0, 0), "QOP = %u", info->qop); 3581 sprintf(get_line(0, 0), "Service = %d (%s)", 3582 info->service, gss_svc_name(info->service)); 3583 } 3584 3585 /* 3586 * Print detail information about the given secinfo4. 3587 */ 3588 3589 static void 3590 detail_secinfo4(secinfo4 *infop) 3591 { 3592 sprintf(get_line(0, 0), "Flavor = %d (%s)", 3593 infop->flavor, flavor_name(infop->flavor)); 3594 switch (infop->flavor) { 3595 case RPCSEC_GSS: 3596 detail_rpcsec_gss(&infop->secinfo4_u.flavor_info); 3597 break; 3598 } 3599 } 3600 3601 3602 /* 3603 * Return a summary string corresponding to the given nfs_space_limit4. 3604 */ 3605 3606 static char * 3607 sum_space_limit(nfs_space_limit4 *limitp) 3608 { 3609 static char buf[64]; 3610 int buflen = sizeof (buf); 3611 3612 buf[0] = '\0'; 3613 switch (limitp->limitby) { 3614 case NFS_LIMIT_SIZE: 3615 snprintf(buf, buflen, "LB=SZ(%llu)", 3616 limitp->nfs_space_limit4_u.filesize); 3617 break; 3618 case NFS_LIMIT_BLOCKS: 3619 snprintf(buf, buflen, "LB=BL(%u*%u)", 3620 limitp->nfs_space_limit4_u.mod_blocks.num_blocks, 3621 limitp->nfs_space_limit4_u.mod_blocks.bytes_per_block); 3622 break; 3623 default: 3624 snprintf(buf, buflen, "LB=?(%d)", limitp->limitby); 3625 break; 3626 } 3627 3628 return (buf); 3629 } 3630 3631 /* 3632 * Print detail information about the given nfs_space_limit4. 3633 */ 3634 3635 static void 3636 detail_space_limit(nfs_space_limit4 *limitp) 3637 { 3638 sprintf(get_line(0, 0), "LimitBy = %d (%s)", 3639 limitp->limitby, 3640 limitby_name(limitp->limitby)); 3641 3642 switch (limitp->limitby) { 3643 case NFS_LIMIT_SIZE: 3644 sprintf(get_line(0, 0), "Bytes = %llu", 3645 limitp->nfs_space_limit4_u.filesize); 3646 break; 3647 case NFS_LIMIT_BLOCKS: 3648 sprintf(get_line(0, 0), "Blocks = %u", 3649 limitp->nfs_space_limit4_u.mod_blocks.num_blocks); 3650 sprintf(get_line(0, 0), "Bytes Per Block = %u", 3651 limitp->nfs_space_limit4_u.mod_blocks.bytes_per_block); 3652 break; 3653 } 3654 } 3655 3656 3657 /* 3658 * Return the short name of a file type. 3659 */ 3660 3661 static char * 3662 sum_type_name(nfs_ftype4 type) 3663 { 3664 static char buf[20]; 3665 3666 if (type < num_ftypes) 3667 return (ftype_names[type].short_name); 3668 else { 3669 sprintf(buf, "type %d", type); 3670 return (buf); 3671 } 3672 } 3673 3674 3675 /* 3676 * Return string with long/short flag names 3677 */ 3678 3679 static char * 3680 get_flags(uint_t flag, ftype_names_t *names, uint_t num_flags, int shortname, 3681 char *prefix) 3682 { 3683 static char buf[200]; 3684 char *bp = buf, *str; 3685 int i, len, blen = sizeof (buf); 3686 ftype_names_t *fn = NULL; 3687 3688 *bp = '\0'; 3689 3690 if (prefix) { 3691 snprintf(bp, blen, "%s", prefix); 3692 bp += (len = sizeof (bp)); 3693 blen -= len; 3694 } 3695 3696 for (i = 0; i < 32; i++) 3697 if (flag & (1 << i)) { 3698 fn = names + (i < num_flags ? i : num_flags); 3699 str = (shortname ? fn->short_name : fn->long_name); 3700 3701 snprintf(bp, blen, "%s,", str); 3702 bp += (len = strlen(bp)); 3703 blen -= len; 3704 } 3705 3706 if (fn) 3707 *(bp - 1) = '\0'; 3708 else 3709 *buf = '\0'; 3710 3711 return (buf); 3712 } 3713 3714 3715 /* 3716 * Return the long name of a file type. 3717 */ 3718 3719 static char * 3720 detail_type_name(nfs_ftype4 type) 3721 { 3722 static char buf[20]; 3723 3724 if (type < num_ftypes) 3725 return (ftype_names[type].long_name); 3726 else { 3727 sprintf(buf, "type %d", type); 3728 return (buf); 3729 } 3730 } 3731 3732 /* 3733 * Return the name of an attribute. 3734 */ 3735 3736 static char * 3737 attr_name(uint_t attrnum) 3738 { 3739 static char buf[20]; 3740 3741 if (attrnum < MAX_ATTRIBUTES) 3742 return (attr_info[attrnum].name); 3743 else { 3744 sprintf(buf, "attr #%d", attrnum); 3745 return (buf); 3746 } 3747 } 3748 3749 /* 3750 * Return the name of the given open_claim_type4. 3751 */ 3752 3753 static char * 3754 claim_name(enum open_claim_type4 claim_type) 3755 { 3756 char *result; 3757 3758 switch (claim_type) { 3759 case CLAIM_NULL: 3760 result = "NULL"; 3761 break; 3762 case CLAIM_PREVIOUS: 3763 result = "PREVIOUS"; 3764 break; 3765 case CLAIM_DELEGATE_CUR: 3766 result = "DELEGATE CURRENT"; 3767 break; 3768 case CLAIM_DELEGATE_PREV: 3769 result = "DELEGATE PREVIOUS"; 3770 break; 3771 default: 3772 result = "?"; 3773 break; 3774 } 3775 3776 return (result); 3777 } 3778 3779 /* 3780 * Return a string naming the given delegation. 3781 */ 3782 3783 static char * 3784 delegation_type_name(enum open_delegation_type4 type) 3785 { 3786 char *result; 3787 3788 switch (type) { 3789 case OPEN_DELEGATE_NONE: 3790 result = "NONE"; 3791 break; 3792 case OPEN_DELEGATE_READ: 3793 result = "READ"; 3794 break; 3795 case OPEN_DELEGATE_WRITE: 3796 result = "WRITE"; 3797 break; 3798 default: 3799 result = "?"; 3800 break; 3801 } 3802 3803 return (result); 3804 } 3805 3806 /* 3807 * Return the name of the given authentication flavor. 3808 */ 3809 3810 static char * 3811 flavor_name(uint_t flavor) 3812 { 3813 char *result; 3814 static char buf[50]; 3815 3816 switch (flavor) { 3817 case AUTH_SYS: 3818 result = "AUTH_SYS"; 3819 break; 3820 case AUTH_NONE: 3821 result = "AUTH_NONE"; 3822 break; 3823 case AUTH_DH: 3824 result = "AUTH_DH"; 3825 break; 3826 case RPCSEC_GSS: 3827 result = "RPCSEC_GSS"; 3828 break; 3829 default: 3830 sprintf(buf, "[flavor %d]", flavor); 3831 result = buf; 3832 break; 3833 } 3834 3835 return (result); 3836 } 3837 3838 /* 3839 * Return the name of the given rpc_gss_svc_t. 3840 */ 3841 3842 static char * 3843 gss_svc_name(rpc_gss_svc_t svc) 3844 { 3845 char *result; 3846 static char buf[50]; 3847 3848 switch (svc) { 3849 case RPC_GSS_SVC_NONE: 3850 result = "NONE"; 3851 break; 3852 case RPC_GSS_SVC_INTEGRITY: 3853 result = "INTEGRITY"; 3854 break; 3855 case RPC_GSS_SVC_PRIVACY: 3856 result = "PRIVACY"; 3857 break; 3858 default: 3859 sprintf(buf, "Service %d", svc); 3860 result = buf; 3861 break; 3862 } 3863 3864 return (result); 3865 } 3866 3867 /* 3868 * Return a string name for the given limit_by4. 3869 */ 3870 3871 static char * 3872 limitby_name(enum limit_by4 limitby) 3873 { 3874 char *result; 3875 3876 switch (limitby) { 3877 case NFS_LIMIT_SIZE: 3878 result = "SIZE"; 3879 break; 3880 case NFS_LIMIT_BLOCKS: 3881 result = "BLOCKS"; 3882 break; 3883 default: 3884 result = "?"; 3885 break; 3886 } 3887 3888 return (result); 3889 } 3890 3891 static char * 3892 status_name(int status) 3893 { 3894 char *p; 3895 3896 switch (status) { 3897 case NFS4_OK: p = "NFS4_OK"; break; 3898 case NFS4ERR_PERM: p = "NFS4ERR_PERM"; break; 3899 case NFS4ERR_NOENT: p = "NFS4ERR_NOENT"; break; 3900 case NFS4ERR_IO: p = "NFS4ERR_IO"; break; 3901 case NFS4ERR_NXIO: p = "NFS4ERR_NXIO"; break; 3902 case NFS4ERR_ACCESS: p = "NFS4ERR_ACCESS"; break; 3903 case NFS4ERR_EXIST: p = "NFS4ERR_EXIST"; break; 3904 case NFS4ERR_XDEV: p = "NFS4ERR_XDEV"; break; 3905 case NFS4ERR_NOTDIR: p = "NFS4ERR_NOTDIR"; break; 3906 case NFS4ERR_ISDIR: p = "NFS4ERR_ISDIR"; break; 3907 case NFS4ERR_INVAL: p = "NFS4ERR_INVAL"; break; 3908 case NFS4ERR_FBIG: p = "NFS4ERR_FBIG"; break; 3909 case NFS4ERR_NOSPC: p = "NFS4ERR_NOSPC"; break; 3910 case NFS4ERR_ROFS: p = "NFS4ERR_ROFS"; break; 3911 case NFS4ERR_MLINK: p = "NFS4ERR_MLINK"; break; 3912 case NFS4ERR_NAMETOOLONG:p = "NFS4ERR_NAMETOOLONG"; break; 3913 case NFS4ERR_NOTEMPTY: p = "NFS4ERR_NOTEMPTY"; break; 3914 case NFS4ERR_DQUOT: p = "NFS4ERR_DQUOT"; break; 3915 case NFS4ERR_STALE: p = "NFS4ERR_STALE"; break; 3916 case NFS4ERR_BADHANDLE: p = "NFS4ERR_BADHANDLE"; break; 3917 case NFS4ERR_BAD_COOKIE:p = "NFS4ERR_BAD_COOKIE"; break; 3918 case NFS4ERR_NOTSUPP: p = "NFS4ERR_NOTSUPP"; break; 3919 case NFS4ERR_TOOSMALL: p = "NFS4ERR_TOOSMALL"; break; 3920 case NFS4ERR_SERVERFAULT:p = "NFS4ERR_SERVERFAULT"; break; 3921 case NFS4ERR_BADTYPE: p = "NFS4ERR_BADTYPE"; break; 3922 case NFS4ERR_DELAY: p = "NFS4ERR_DELAY"; break; 3923 case NFS4ERR_SAME: p = "NFS4ERR_SAME"; break; 3924 case NFS4ERR_DENIED: p = "NFS4ERR_DENIED"; break; 3925 case NFS4ERR_EXPIRED: p = "NFS4ERR_EXPIRED"; break; 3926 case NFS4ERR_LOCKED: p = "NFS4ERR_LOCKED"; break; 3927 case NFS4ERR_GRACE: p = "NFS4ERR_GRACE"; break; 3928 case NFS4ERR_FHEXPIRED: p = "NFS4ERR_FHEXPIRED"; break; 3929 case NFS4ERR_SHARE_DENIED: p = "NFS4ERR_SHARE_DENIED"; break; 3930 case NFS4ERR_WRONGSEC: p = "NFS4ERR_WRONGSEC"; break; 3931 case NFS4ERR_CLID_INUSE: p = "NFS4ERR_CLID_INUSE"; break; 3932 case NFS4ERR_RESOURCE: p = "NFS4ERR_RESOURCE"; break; 3933 case NFS4ERR_MOVED: p = "NFS4ERR_MOVED"; break; 3934 case NFS4ERR_NOFILEHANDLE: p = "NFS4ERR_NOFILEHANDLE"; break; 3935 case NFS4ERR_MINOR_VERS_MISMATCH: p = "NFS4ERR_MINOR_VERS_MISMATCH"; 3936 break; 3937 case NFS4ERR_STALE_CLIENTID: p = "NFS4ERR_STALE_CLIENTID"; break; 3938 case NFS4ERR_STALE_STATEID: p = "NFS4ERR_STALE_STATEID"; break; 3939 case NFS4ERR_OLD_STATEID: p = "NFS4ERR_OLD_STATEID"; break; 3940 case NFS4ERR_BAD_STATEID: p = "NFS4ERR_BAD_STATEID"; break; 3941 case NFS4ERR_BAD_SEQID: p = "NFS4ERR_BAD_SEQID"; break; 3942 case NFS4ERR_NOT_SAME: p = "NFS4ERR_NOT_SAME"; break; 3943 case NFS4ERR_LOCK_RANGE: p = "NFS4ERR_LOCK_RANGE"; break; 3944 case NFS4ERR_SYMLINK: p = "NFS4ERR_SYMLINK"; break; 3945 case NFS4ERR_RESTOREFH: p = "NFS4ERR_RESTOREFH"; break; 3946 case NFS4ERR_LEASE_MOVED: p = "NFS4ERR_LEASE_MOVED"; break; 3947 case NFS4ERR_ATTRNOTSUPP: p = "NFS4ERR_ATTRNOTSUPP"; break; 3948 case NFS4ERR_NO_GRACE: p = "NFS4ERR_NO_GRACE"; break; 3949 case NFS4ERR_RECLAIM_BAD: p = "NFS4ERR_RECLAIM_BAD"; break; 3950 case NFS4ERR_RECLAIM_CONFLICT: p = "NFS4ERR_RECLAIM_CONFLICT"; break; 3951 case NFS4ERR_BADXDR: p = "NFS4ERR_BADXDR"; break; 3952 case NFS4ERR_LOCKS_HELD: p = "NFS4ERR_LOCKS_HELD"; break; 3953 case NFS4ERR_OPENMODE: p = "NFS4ERR_OPENMODE"; break; 3954 case NFS4ERR_BADOWNER: p = "NFS4ERR_BADOWNER"; break; 3955 case NFS4ERR_BADCHAR: p = "NFS4ERR_BADCHAR"; break; 3956 case NFS4ERR_BADNAME: p = "NFS4ERR_BADNAME"; break; 3957 case NFS4ERR_BAD_RANGE: p = "NFS4ERR_BAD_RANGE"; break; 3958 case NFS4ERR_LOCK_NOTSUPP: p = "NFS4ERR_LOCK_NOTSUPP"; break; 3959 case NFS4ERR_OP_ILLEGAL: p = "NFS4ERR_OP_ILLEGAL"; break; 3960 case NFS4ERR_DEADLOCK: p = "NFS4ERR_DEADLOCK"; break; 3961 case NFS4ERR_FILE_OPEN: p = "NFS4ERR_FILE_OPEN"; break; 3962 case NFS4ERR_ADMIN_REVOKED: p = "NFS4ERR_ADMIN_REVOKED"; break; 3963 case NFS4ERR_CB_PATH_DOWN: p = "NFS4ERR_CB_PATH_DOWN"; break; 3964 default: p = "(unknown error)"; break; 3965 } 3966 3967 return (p); 3968 } 3969 3970 char * 3971 nfsstat4_to_name(int status) 3972 { 3973 return (status_name(status)); 3974 } 3975 3976 /* 3977 * Attribute print functions. See attr_info_t. 3978 */ 3979 3980 static void 3981 prt_supported_attrs(XDR *xdr) 3982 { 3983 static bitmap4 val; 3984 3985 if (!xdr_bitmap4(xdr, &val)) 3986 longjmp(xdr_err, 1); 3987 sprintf(get_line(0, 0), "Supported Attributes:"); 3988 detail_attr_bitmap("\t", &val, NULL); 3989 xdr_free(xdr_bitmap4, (char *)&val); 3990 } 3991 3992 static void 3993 prt_type(XDR *xdr) 3994 { 3995 nfs_ftype4 val; 3996 3997 if (!xdr_nfs_ftype4(xdr, &val)) 3998 longjmp(xdr_err, 1); 3999 sprintf(get_line(0, 0), "Type = %s", sum_type_name(val)); 4000 } 4001 4002 static void 4003 prt_fh_expire_type(XDR *xdr) 4004 { 4005 fattr4_fh_expire_type val; 4006 char *buf; 4007 bool_t first = TRUE; 4008 4009 if (!xdr_fattr4_fh_expire_type(xdr, &val)) 4010 longjmp(xdr_err, 1); 4011 buf = get_line(0, 0); 4012 4013 sprintf(buf, "Filehandle expire type = "); 4014 if ((val & (FH4_NOEXPIRE_WITH_OPEN | FH4_VOLATILE_ANY | 4015 FH4_VOL_MIGRATION | FH4_VOL_RENAME)) == 0) { 4016 strcat(buf, "Persistent"); 4017 return; 4018 } 4019 if (val & FH4_NOEXPIRE_WITH_OPEN) { 4020 strcat(buf, "No Expire With OPEN"); 4021 first = FALSE; 4022 } 4023 if (val & FH4_VOLATILE_ANY) { 4024 if (first) 4025 first = FALSE; 4026 else 4027 strcat(buf, ", "); 4028 strcat(buf, "Volatile at any time"); 4029 } 4030 if (val & FH4_VOL_MIGRATION) { 4031 if (first) 4032 first = FALSE; 4033 else 4034 strcat(buf, ", "); 4035 strcat(buf, "Volatile at Migration"); 4036 } 4037 if (val & FH4_VOL_RENAME) { 4038 if (first) 4039 first = FALSE; 4040 else 4041 strcat(buf, ", "); 4042 strcat(buf, "Volatile at Rename"); 4043 } 4044 } 4045 4046 static void 4047 prt_change(XDR *xdr) 4048 { 4049 changeid4 val; 4050 4051 if (!xdr_changeid4(xdr, &val)) 4052 longjmp(xdr_err, 1); 4053 sprintf(get_line(0, 0), "Change ID = 0x%llx", val); 4054 /* XXX print as time_t, too? */ 4055 } 4056 4057 static void 4058 prt_size(XDR *xdr) 4059 { 4060 uint64_t val; 4061 4062 if (!xdr_uint64_t(xdr, &val)) 4063 longjmp(xdr_err, 1); 4064 sprintf(get_line(0, 0), "Size = %llu", val); 4065 } 4066 4067 static void 4068 prt_link_support(XDR *xdr) 4069 { 4070 bool_t val; 4071 4072 if (!xdr_bool(xdr, &val)) 4073 longjmp(xdr_err, 1); 4074 sprintf(get_line(0, 0), "Link Support = %s", 4075 val ? "TRUE" : "FALSE"); 4076 } 4077 4078 static void 4079 prt_symlink_support(XDR *xdr) 4080 { 4081 bool_t val; 4082 4083 if (!xdr_bool(xdr, &val)) 4084 longjmp(xdr_err, 1); 4085 sprintf(get_line(0, 0), "Symlink Support = %s", 4086 val ? "TRUE" : "FALSE"); 4087 } 4088 4089 static void 4090 prt_named_attr(XDR *xdr) 4091 { 4092 bool_t val; 4093 4094 if (!xdr_bool(xdr, &val)) 4095 longjmp(xdr_err, 1); 4096 sprintf(get_line(0, 0), "Has Named Attributes = %s", 4097 val ? "TRUE" : "FALSE"); 4098 } 4099 4100 static void 4101 prt_fsid(XDR *xdr) 4102 { 4103 fsid4 val; 4104 4105 if (!xdr_fsid4(xdr, &val)) 4106 longjmp(xdr_err, 1); 4107 sprintf(get_line(0, 0), "FS ID: Major = %llx, Minor = %llx", 4108 val.major, val.minor); 4109 } 4110 4111 static void 4112 prt_unique_handles(XDR *xdr) 4113 { 4114 bool_t val; 4115 4116 if (!xdr_bool(xdr, &val)) 4117 longjmp(xdr_err, 1); 4118 sprintf(get_line(0, 0), "Unique Handles = %s", 4119 val ? "TRUE" : "FALSE"); 4120 } 4121 4122 static void 4123 prt_lease_time(XDR *xdr) 4124 { 4125 uint32_t val; 4126 4127 if (!xdr_uint32_t(xdr, &val)) 4128 longjmp(xdr_err, 1); 4129 sprintf(get_line(0, 0), "Lease Time = %u", val); 4130 } 4131 4132 static void 4133 prt_rdattr_error(XDR *xdr) 4134 { 4135 nfsstat4 val; 4136 4137 if (!xdr_nfsstat4(xdr, &val)) 4138 longjmp(xdr_err, 1); 4139 sprintf(get_line(0, 0), "Rdattr Error = %u (%s)", 4140 val, status_name(val)); 4141 } 4142 4143 static void 4144 prt_acl(XDR *xdr) 4145 { 4146 static fattr4_acl val; 4147 char buffy[NFS4_OPAQUE_LIMIT]; 4148 int i, len; 4149 4150 if (!xdr_fattr4_acl(xdr, &val)) 4151 longjmp(xdr_err, 1); 4152 sprintf(get_line(0, 0), "ACL of %d entries", val.fattr4_acl_len); 4153 for (i = 0; i < val.fattr4_acl_len; i++) { 4154 sprintf(get_line(0, 0), "nfsace4[%d]", i); 4155 4156 sprintf(get_line(0, 0), " type = %x", 4157 val.fattr4_acl_val[i].type); 4158 detail_acetype4(val.fattr4_acl_val[i].type); 4159 4160 sprintf(get_line(0, 0), " flags = %x", 4161 val.fattr4_acl_val[i].flag); 4162 detail_aceflag4(val.fattr4_acl_val[i].flag); 4163 4164 sprintf(get_line(0, 0), " mask = %x", 4165 val.fattr4_acl_val[i].access_mask); 4166 detail_acemask4(val.fattr4_acl_val[i].access_mask); 4167 4168 len = val.fattr4_acl_val[i].who.utf8string_len; 4169 if (len >= NFS4_OPAQUE_LIMIT) 4170 len = NFS4_OPAQUE_LIMIT - 1; 4171 (void) strncpy(buffy, val.fattr4_acl_val[i].who.utf8string_val, 4172 len); 4173 buffy[len] = '\0'; 4174 sprintf(get_line(0, 0), " who = %s", buffy); 4175 } 4176 xdr_free(xdr_fattr4_acl, (char *)&val); 4177 } 4178 4179 static void 4180 detail_acetype4(acetype4 type) 4181 { 4182 if (type >= ACETYPE4_NAMES_MAX) { 4183 sprintf(get_line(0, 0), " unknown type"); 4184 } else { 4185 sprintf(get_line(0, 0), " %s", acetype4_names[type]); 4186 } 4187 } 4188 4189 static void 4190 detail_uint32_bitmap(uint32_t mask, char *mask_names[], int names_max) 4191 { 4192 char buffy[BUFSIZ], *name; 4193 char *indent = " "; 4194 char *spacer = " "; 4195 int pending = 0; 4196 int bit; 4197 int len, namelen, spacelen; 4198 4199 strcpy(buffy, indent); 4200 len = strlen(buffy); 4201 spacelen = strlen(spacer); 4202 4203 for (bit = 0; bit < names_max; bit++) { 4204 if (mask & (1 << bit)) { 4205 name = mask_names[bit]; 4206 namelen = strlen(name); 4207 /* 80 - 6 for "NFS: " = 74 */ 4208 if ((len + spacelen + namelen) >= 74) { 4209 sprintf(get_line(0, 0), "%s", buffy); 4210 strcpy(buffy, indent); 4211 len = strlen(buffy); 4212 pending = 0; 4213 } 4214 (void) strlcat(buffy, spacer, sizeof (buffy)); 4215 (void) strlcat(buffy, name, sizeof (buffy)); 4216 pending = 1; 4217 len += spacelen + namelen; 4218 } 4219 } 4220 if (pending) 4221 sprintf(get_line(0, 0), "%s", buffy); 4222 } 4223 4224 static void 4225 detail_aceflag4(aceflag4 flag) 4226 { 4227 detail_uint32_bitmap(flag, aceflag4_names, ACEFLAG4_NAMES_MAX); 4228 } 4229 4230 static void 4231 detail_acemask4(acemask4 mask) 4232 { 4233 detail_uint32_bitmap(mask, acemask4_names, ACEMASK4_NAMES_MAX); 4234 } 4235 4236 static void 4237 prt_aclsupport(XDR *xdr) 4238 { 4239 fattr4_aclsupport val; 4240 4241 if (!xdr_fattr4_aclsupport(xdr, &val)) 4242 longjmp(xdr_err, 1); 4243 if (val & ACL4_SUPPORT_ALLOW_ACL) 4244 sprintf(get_line(0, 0), "ALLOW ACL Supported"); 4245 if (val & ACL4_SUPPORT_DENY_ACL) 4246 sprintf(get_line(0, 0), "DENY ACL Supported"); 4247 if (val & ACL4_SUPPORT_AUDIT_ACL) 4248 sprintf(get_line(0, 0), "AUDIT ACL Supported"); 4249 if (val & ACL4_SUPPORT_ALARM_ACL) 4250 sprintf(get_line(0, 0), "ALARM ACL Supported"); 4251 } 4252 4253 static void 4254 prt_archive(XDR *xdr) 4255 { 4256 bool_t val; 4257 4258 if (!xdr_bool(xdr, &val)) 4259 longjmp(xdr_err, 1); 4260 sprintf(get_line(0, 0), "Archived = %s", 4261 val ? "TRUE" : "FALSE"); 4262 } 4263 4264 static void 4265 prt_cansettime(XDR *xdr) 4266 { 4267 bool_t val; 4268 4269 if (!xdr_bool(xdr, &val)) 4270 longjmp(xdr_err, 1); 4271 sprintf(get_line(0, 0), "Server Can Set Time = %s", 4272 val ? "TRUE" : "FALSE"); 4273 } 4274 4275 static void 4276 prt_case_insensitive(XDR *xdr) 4277 { 4278 bool_t val; 4279 4280 if (!xdr_bool(xdr, &val)) 4281 longjmp(xdr_err, 1); 4282 sprintf(get_line(0, 0), "Case Insensitive Lookups = %s", 4283 val ? "TRUE" : "FALSE"); 4284 } 4285 4286 static void 4287 prt_case_preserving(XDR *xdr) 4288 { 4289 bool_t val; 4290 4291 if (!xdr_bool(xdr, &val)) 4292 longjmp(xdr_err, 1); 4293 sprintf(get_line(0, 0), "Case Preserving = %s", 4294 val ? "TRUE" : "FALSE"); 4295 } 4296 4297 static void 4298 prt_chown_restricted(XDR *xdr) 4299 { 4300 bool_t val; 4301 4302 if (!xdr_bool(xdr, &val)) 4303 longjmp(xdr_err, 1); 4304 sprintf(get_line(0, 0), "Chown Is Restricted = %s", 4305 val ? "TRUE" : "FALSE"); 4306 } 4307 4308 static void 4309 prt_filehandle(XDR *xdr) 4310 { 4311 static nfs_fh4 val; 4312 4313 if (!xdr_nfs_fh4(xdr, &val)) 4314 longjmp(xdr_err, 1); 4315 detail_fh4(&val); 4316 xdr_free(xdr_nfs_fh4, (char *)&val); 4317 } 4318 4319 static void 4320 prt_fileid(XDR *xdr) 4321 { 4322 uint64_t val; 4323 4324 if (!xdr_uint64_t(xdr, &val)) 4325 longjmp(xdr_err, 1); 4326 sprintf(get_line(0, 0), "File ID = %llu", val); 4327 } 4328 4329 static void 4330 prt_mounted_on_fileid(XDR *xdr) 4331 { 4332 uint64_t val; 4333 4334 if (!xdr_uint64_t(xdr, &val)) 4335 longjmp(xdr_err, 1); 4336 sprintf(get_line(0, 0), "Mounted On File ID = %llu", val); 4337 } 4338 4339 static void 4340 prt_files_avail(XDR *xdr) 4341 { 4342 uint64_t val; 4343 4344 if (!xdr_uint64_t(xdr, &val)) 4345 longjmp(xdr_err, 1); 4346 sprintf(get_line(0, 0), "Files Available = %llu", val); 4347 } 4348 4349 static void 4350 prt_files_free(XDR *xdr) 4351 { 4352 uint64_t val; 4353 4354 if (!xdr_uint64_t(xdr, &val)) 4355 longjmp(xdr_err, 1); 4356 sprintf(get_line(0, 0), "Files Free = %llu", val); 4357 } 4358 4359 static void 4360 prt_files_total(XDR *xdr) 4361 { 4362 uint64_t val; 4363 4364 if (!xdr_uint64_t(xdr, &val)) 4365 longjmp(xdr_err, 1); 4366 sprintf(get_line(0, 0), "Files Total = %llu", val); 4367 } 4368 4369 static void 4370 prt_fs_location(fs_location4 *fsl) 4371 { 4372 int i; 4373 4374 for (i = 0; i < fsl->server.server_len; i++) 4375 sprintf(get_line(0, 0), "server: %s", 4376 utf8localize(&fsl->server.server_val[i])); 4377 4378 detail_pathname4(&fsl->rootpath, "rootpath: "); 4379 } 4380 4381 static void 4382 prt_fs_locations(XDR *xdr) 4383 { 4384 static fs_locations4 val; 4385 int i; 4386 4387 if (!xdr_fs_locations4(xdr, &val)) 4388 longjmp(xdr_err, 1); 4389 sprintf(get_line(0, 0), "[fs_locations]"); 4390 detail_pathname4(&val.fs_root, "fs_root: "); 4391 for (i = 0; i < val.locations.locations_len; i++) 4392 prt_fs_location(&val.locations.locations_val[i]); 4393 xdr_free(xdr_fs_locations4, (char *)&val); 4394 } 4395 4396 static void 4397 prt_hidden(XDR *xdr) 4398 { 4399 bool_t val; 4400 4401 if (!xdr_bool(xdr, &val)) 4402 longjmp(xdr_err, 1); 4403 sprintf(get_line(0, 0), "Hidden = %s", 4404 val ? "TRUE" : "FALSE"); 4405 } 4406 4407 static void 4408 prt_homogeneous(XDR *xdr) 4409 { 4410 bool_t val; 4411 4412 if (!xdr_bool(xdr, &val)) 4413 longjmp(xdr_err, 1); 4414 sprintf(get_line(0, 0), "FS Is Homogeneous = %s", 4415 val ? "TRUE" : "FALSE"); 4416 } 4417 4418 static void 4419 prt_maxfilesize(XDR *xdr) 4420 { 4421 uint64_t val; 4422 4423 if (!xdr_uint64_t(xdr, &val)) 4424 longjmp(xdr_err, 1); 4425 sprintf(get_line(0, 0), "Maximum File Size = %llu", val); 4426 } 4427 4428 static void 4429 prt_maxlink(XDR *xdr) 4430 { 4431 uint32_t val; 4432 4433 if (!xdr_uint32_t(xdr, &val)) 4434 longjmp(xdr_err, 1); 4435 sprintf(get_line(0, 0), "Maximum Number of Links = %u", val); 4436 } 4437 4438 static void 4439 prt_maxname(XDR *xdr) 4440 { 4441 uint32_t val; 4442 4443 if (!xdr_uint32_t(xdr, &val)) 4444 longjmp(xdr_err, 1); 4445 sprintf(get_line(0, 0), "Maximum File Name Length = %u", val); 4446 } 4447 4448 static void 4449 prt_maxread(XDR *xdr) 4450 { 4451 uint64_t val; 4452 4453 if (!xdr_uint64_t(xdr, &val)) 4454 longjmp(xdr_err, 1); 4455 sprintf(get_line(0, 0), "Maximum Read Size = %llu", val); 4456 } 4457 4458 static void 4459 prt_maxwrite(XDR *xdr) 4460 { 4461 uint64_t val; 4462 4463 if (!xdr_uint64_t(xdr, &val)) 4464 longjmp(xdr_err, 1); 4465 4466 sprintf(get_line(0, 0), "Maximum Write Size = %llu", val); 4467 } 4468 4469 static void 4470 prt_mimetype(XDR *xdr) 4471 { 4472 static utf8string val; 4473 4474 if (!xdr_utf8string(xdr, &val)) 4475 longjmp(xdr_err, 1); 4476 sprintf(get_line(0, 0), "MIME Type = %s", utf8localize(&val)); 4477 xdr_free(xdr_utf8string, (char *)&val); 4478 } 4479 4480 static void 4481 prt_mode(XDR *xdr) 4482 { 4483 mode4 val; 4484 4485 if (!xdr_mode4(xdr, &val)) 4486 longjmp(xdr_err, 1); 4487 sprintf(get_line(0, 0), "Mode = 0%03o", val); 4488 } 4489 4490 static void 4491 prt_no_trunc(XDR *xdr) 4492 { 4493 bool_t val; 4494 4495 if (!xdr_bool(xdr, &val)) 4496 longjmp(xdr_err, 1); 4497 sprintf(get_line(0, 0), "Long Names Are Error (no_trunc) = %s", 4498 val ? "TRUE" : "FALSE"); 4499 } 4500 4501 static void 4502 prt_numlinks(XDR *xdr) 4503 { 4504 uint32_t val; 4505 4506 if (!xdr_uint32_t(xdr, &val)) 4507 longjmp(xdr_err, 1); 4508 sprintf(get_line(0, 0), "Number of Links = %u", val); 4509 } 4510 4511 static void 4512 prt_owner(XDR *xdr) 4513 { 4514 static utf8string val; 4515 4516 if (!xdr_utf8string(xdr, &val)) 4517 longjmp(xdr_err, 1); 4518 sprintf(get_line(0, 0), "Owner = %s", utf8localize(&val)); 4519 xdr_free(xdr_utf8string, (char *)&val); 4520 } 4521 4522 static void 4523 prt_owner_group(XDR *xdr) 4524 { 4525 static utf8string val; 4526 4527 if (!xdr_utf8string(xdr, &val)) 4528 longjmp(xdr_err, 1); 4529 sprintf(get_line(0, 0), "Group = %s", utf8localize(&val)); 4530 xdr_free(xdr_utf8string, (char *)&val); 4531 } 4532 4533 static void 4534 prt_quota_avail_hard(XDR *xdr) 4535 { 4536 uint64_t val; 4537 4538 if (!xdr_uint64_t(xdr, &val)) 4539 longjmp(xdr_err, 1); 4540 sprintf(get_line(0, 0), "Quota Hard Limit = %llu", val); 4541 } 4542 4543 static void 4544 prt_quota_avail_soft(XDR *xdr) 4545 { 4546 uint64_t val; 4547 4548 if (!xdr_uint64_t(xdr, &val)) 4549 longjmp(xdr_err, 1); 4550 sprintf(get_line(0, 0), "Quota Soft Limit = %llu", val); 4551 } 4552 4553 static void 4554 prt_quota_used(XDR *xdr) 4555 { 4556 uint64_t val; 4557 4558 if (!xdr_uint64_t(xdr, &val)) 4559 longjmp(xdr_err, 1); 4560 sprintf(get_line(0, 0), "Quota Used = %llu", val); 4561 } 4562 4563 static void 4564 prt_rawdev(XDR *xdr) 4565 { 4566 specdata4 val; 4567 4568 if (!xdr_specdata4(xdr, &val)) 4569 longjmp(xdr_err, 1); 4570 sprintf(get_line(0, 0), "Raw Device ID = %u, %u", 4571 val.specdata1, val.specdata2); 4572 } 4573 4574 static void 4575 prt_space_avail(XDR *xdr) 4576 { 4577 uint64_t val; 4578 4579 if (!xdr_uint64_t(xdr, &val)) 4580 longjmp(xdr_err, 1); 4581 sprintf(get_line(0, 0), "Space Available = %llu", val); 4582 } 4583 4584 static void 4585 prt_space_free(XDR *xdr) 4586 { 4587 uint64_t val; 4588 4589 if (!xdr_uint64_t(xdr, &val)) 4590 longjmp(xdr_err, 1); 4591 sprintf(get_line(0, 0), "Space Free = %llu", val); 4592 } 4593 4594 static void 4595 prt_space_total(XDR *xdr) 4596 { 4597 uint64_t val; 4598 4599 if (!xdr_uint64_t(xdr, &val)) 4600 longjmp(xdr_err, 1); 4601 sprintf(get_line(0, 0), "Total Disk Space = %llu", val); 4602 } 4603 4604 static void 4605 prt_space_used(XDR *xdr) 4606 { 4607 uint64_t val; 4608 4609 if (!xdr_uint64_t(xdr, &val)) 4610 longjmp(xdr_err, 1); 4611 sprintf(get_line(0, 0), "Space Used (this object) = %llu", val); 4612 } 4613 4614 static void 4615 prt_system(XDR *xdr) 4616 { 4617 bool_t val; 4618 4619 if (!xdr_bool(xdr, &val)) 4620 longjmp(xdr_err, 1); 4621 sprintf(get_line(0, 0), "System File = %s", 4622 val ? "TRUE" : "FALSE"); 4623 } 4624 4625 static void 4626 prt_time_access(XDR *xdr) 4627 { 4628 nfstime4 val; 4629 4630 if (!xdr_nfstime4(xdr, &val)) 4631 longjmp(xdr_err, 1); 4632 sprintf(get_line(0, 0), "Last Access Time = %s", 4633 format_time(val.seconds, val.nseconds)); 4634 } 4635 4636 static void 4637 prt_time_access_set(XDR *xdr) 4638 { 4639 settime4 val; 4640 4641 if (!xdr_settime4(xdr, &val)) 4642 longjmp(xdr_err, 1); 4643 if (val.set_it == SET_TO_CLIENT_TIME4) { 4644 sprintf(get_line(0, 0), "Access Time = %s (set to client time)", 4645 format_time(val.settime4_u.time.seconds, 4646 val.settime4_u.time.nseconds)); 4647 } else if (val.set_it == SET_TO_SERVER_TIME4) { 4648 sprintf(get_line(0, 0), "Access Time (set to server time)"); 4649 } else 4650 longjmp(xdr_err, 1); 4651 } 4652 4653 static void 4654 prt_time_backup(XDR *xdr) 4655 { 4656 nfstime4 val; 4657 4658 if (!xdr_nfstime4(xdr, &val)) 4659 longjmp(xdr_err, 1); 4660 sprintf(get_line(0, 0), "Last Backup Time = %s", 4661 format_time(val.seconds, val.nseconds)); 4662 } 4663 4664 static void 4665 prt_time_create(XDR *xdr) 4666 { 4667 nfstime4 val; 4668 4669 if (!xdr_nfstime4(xdr, &val)) 4670 longjmp(xdr_err, 1); 4671 sprintf(get_line(0, 0), "Creation Time = %s", 4672 format_time(val.seconds, val.nseconds)); 4673 } 4674 4675 static void 4676 prt_time_delta(XDR *xdr) 4677 { 4678 nfstime4 val; 4679 4680 if (!xdr_nfstime4(xdr, &val)) 4681 longjmp(xdr_err, 1); 4682 sprintf(get_line(0, 0), "Server Time Granularity = %lld.%09d sec", 4683 val.seconds, val.nseconds); 4684 } 4685 4686 static void 4687 prt_time_metadata(XDR *xdr) 4688 { 4689 nfstime4 val; 4690 4691 if (!xdr_nfstime4(xdr, &val)) 4692 longjmp(xdr_err, 1); 4693 sprintf(get_line(0, 0), "Last Metadata Change Time = %s", 4694 format_time(val.seconds, val.nseconds)); 4695 } 4696 4697 static void 4698 prt_time_modify(XDR *xdr) 4699 { 4700 nfstime4 val; 4701 4702 if (!xdr_nfstime4(xdr, &val)) 4703 longjmp(xdr_err, 1); 4704 sprintf(get_line(0, 0), "Last Modification Time = %s", 4705 format_time(val.seconds, val.nseconds)); 4706 } 4707 4708 static void 4709 prt_time_modify_set(XDR *xdr) 4710 { 4711 settime4 val; 4712 4713 if (!xdr_settime4(xdr, &val)) 4714 longjmp(xdr_err, 1); 4715 if (val.set_it == SET_TO_CLIENT_TIME4) { 4716 sprintf(get_line(0, 0), 4717 "Modification Time = %s (set to client time)", 4718 format_time(val.settime4_u.time.seconds, 4719 val.settime4_u.time.nseconds)); 4720 } else if (val.set_it == SET_TO_SERVER_TIME4) { 4721 sprintf(get_line(0, 0), 4722 "Modification Time (set to server time)"); 4723 } else 4724 longjmp(xdr_err, 1); 4725 } 4726 4727 /* 4728 * Display the UTF8 string that is next in the XDR stream. 4729 */ 4730 4731 static void 4732 showxdr_utf8string(char *fmt) 4733 { 4734 static utf8string string; 4735 4736 if (!xdr_utf8string(&xdrm, &string)) 4737 longjmp(xdr_err, 1); 4738 sprintf(get_line(0, 0), fmt, utf8localize(&string)); 4739 xdr_free(xdr_utf8string, (char *)&string); 4740 } 4741 4742 /* 4743 * utf8string is defined in nfs4_prot.x as an opaque array, which means 4744 * when it is decoded into a string, the string might not have a trailing 4745 * null. Also, the string will still be encoded in UTF-8, rather than 4746 * whatever character encoding is associated with the current locale. This 4747 * routine converts a utf8string into a (null-terminated) C string. One day 4748 * it will convert into the current character encoding, too. To avoid 4749 * dealing with storage management issues, it allocates storage for each 4750 * new string, then this storage is "freed" when the packet has been 4751 * processed. 4752 */ 4753 4754 #define MAX_UTF8_STRINGS 512 4755 4756 static char *utf_buf[MAX_UTF8_STRINGS]; 4757 static size_t utf_buflen[MAX_UTF8_STRINGS]; 4758 static uint_t cur_utf_buf = 0; 4759 4760 static char * 4761 utf8localize(utf8string *utf8str) 4762 { 4763 size_t newsize, oldsize, len; 4764 char *result, *cp; 4765 4766 len = utf8str->utf8string_len; 4767 if (len == 0) 4768 return (""); 4769 if (cur_utf_buf >= MAX_UTF8_STRINGS) 4770 return ("[Too Many UTF-8 Strings]"); 4771 4772 newsize = oldsize = utf_buflen[cur_utf_buf]; 4773 4774 4775 if (oldsize < len + 1) { 4776 /* truncate opaques at NFS4_OPAQUE_LIMIT */ 4777 if (len > NFS4_OPAQUE_LIMIT) 4778 len = NFS4_OPAQUE_LIMIT; 4779 newsize = len + 1; 4780 } 4781 if (newsize != oldsize) { 4782 utf_buf[cur_utf_buf] = realloc(utf_buf[cur_utf_buf], 4783 newsize); 4784 if (utf_buf[cur_utf_buf] == NULL) { 4785 pr_err("out of memory\n"); 4786 utf_buflen[cur_utf_buf] = 0; 4787 return (""); 4788 } 4789 utf_buflen[cur_utf_buf] = newsize; 4790 } 4791 4792 result = utf_buf[cur_utf_buf]; 4793 strncpy(result, utf8str->utf8string_val, len); 4794 result[len] = '\0'; 4795 for (cp = result; cp < result + len; cp++) { 4796 if (!isprint(*cp)) { 4797 *cp = '.'; 4798 } 4799 } 4800 4801 cur_utf_buf++; 4802 4803 return (result); 4804 } 4805 4806 static void 4807 utf8free() 4808 { 4809 cur_utf_buf = 0; 4810 } 4811 4812 4813 /* 4814 * adler16(): adler32 hash code shamelessly copied and mutiliated from 4815 * usr/src/uts/common/io/ppp/spppcomp/zlib.[ch] 4816 * 4817 * The alg was originally created to provide a running 4818 * checksum, but we don't need that -- we just want to 4819 * chksum data described by buf,len; therefore, the first 4820 * parameter was removed (held the running checksum), 4821 * and s1/s2 are always set to their required initial 4822 * values (1 and 0). I also ripped out code which only 4823 * applied to large data sets (bufs larger than 5k). All 4824 * I wanted was their core checksum alg (which is supposed 4825 * to do really well). The v2/v3 hash alg didn't work well 4826 * at all for v4 stuff -- it produced too many collisions. 4827 * 4828 * The copyright info from uts/common/io/ppp/spppcomp/zlib.[ch] 4829 * is included below. 4830 */ 4831 4832 /* -----zlib.c copyright info below */ 4833 /* 4834 * Copyright 2000 Sun Microsystems, Inc. 4835 * All rights reserved. 4836 * 4837 * Updated from zlib-1.0.4 to zlib-1.1.3 by James Carlson. 4838 * 4839 * This file is derived from various .h and .c files from the zlib-1.0.4 4840 * distribution by Jean-loup Gailly and Mark Adler, with some additions 4841 * by Paul Mackerras to aid in implementing Deflate compression and 4842 * decompression for PPP packets. See zlib.h for conditions of 4843 * distribution and use. 4844 * 4845 * Changes that have been made include: 4846 * - added Z_PACKET_FLUSH (see zlib.h for details) 4847 * - added inflateIncomp and deflateOutputPending 4848 * - allow strm->next_out to be NULL, meaning discard the output 4849 * 4850 * $Id: zlib.c,v 1.11 1998/09/13 23:37:12 paulus Exp $ 4851 */ 4852 /* +++ adler32.c */ 4853 /* 4854 * adler32.c -- compute the Adler-32 checksum of a data stream 4855 * Copyright (C) 1995-1998 Mark Adler 4856 * For conditions of distribution and use, see copyright notice in zlib.h 4857 */ 4858 /* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */ 4859 /* -----zlib.c copyright info above */ 4860 4861 /* -----zlib.h copyright info below */ 4862 /* 4863 * Copyright 2000 Sun Microsystems, Inc. 4864 * All rights reserved. 4865 * 4866 * Permission to use, copy, modify, and distribute this software and 4867 * its documentation is hereby granted, provided that the above 4868 * copyright notice appears in all copies. 4869 * 4870 * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF 4871 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 4872 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 4873 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE 4874 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, 4875 * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES 4876 * 4877 * This file has been altered from its original by Sun Microsystems to 4878 * fit local coding style. 4879 */ 4880 /* -----zlib.h copyright info above */ 4881 4882 #define DO1(buf, i) {s1 += buf[i]; s2 += s1; } 4883 #define DO2(buf, i) DO1(buf, i); DO1(buf, i+1); 4884 #define DO4(buf, i) DO2(buf, i); DO2(buf, i+2); 4885 #define DO8(buf, i) DO4(buf, i); DO4(buf, i+4); 4886 #define DO16(buf) DO8(buf, 0); DO8(buf, 8); 4887 4888 static uint32_t 4889 adler16(void *p, int len) 4890 { 4891 uint32_t s1 = 1; 4892 uint32_t s2 = 0; 4893 uchar_t *buf = p; 4894 4895 while (len >= 16) { 4896 DO16(buf); 4897 buf += 16; 4898 len -= 16; 4899 } 4900 4901 while (len > 0) { 4902 s1 += *buf++; 4903 s2 += s1; 4904 len--; 4905 } 4906 4907 return ((uint32_t)(s2 ^ s1) & 0xFFFFU); 4908 } 4909