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