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 2985 strncpy(buf, status_name(res->status), buflen); 2986 sum_attr_bitmap(buf, buflen, &res->attrsset); 2987 } 2988 2989 static void 2990 dtlres_setattr(void *obj) 2991 { 2992 SETATTR4res *res = (SETATTR4res *)obj; 2993 2994 dtl_nfsstat4(obj); 2995 detail_attr_bitmap("", &res->attrsset, NULL); 2996 } 2997 2998 static void 2999 sumres_setclid(char *buf, size_t buflen, void *obj) 3000 { 3001 char *bp; 3002 SETCLIENTID4res *res = (SETCLIENTID4res *)obj; 3003 3004 strncpy(buf, status_name(res->status), buflen); 3005 switch (res->status) { 3006 case NFS_OK: 3007 bp = buf + strlen(buf); 3008 snprintf(bp, buflen - (bp - buf), " %s CFV=%s", 3009 sum_clientid(res->SETCLIENTID4res_u.resok4.clientid), 3010 tohex(res->SETCLIENTID4res_u.resok4.setclientid_confirm, 3011 NFS4_VERIFIER_SIZE)); 3012 break; 3013 case NFS4ERR_CLID_INUSE: 3014 bp = buf + strlen(buf); 3015 snprintf(bp, buflen - (bp - buf), " ID=%s Addr=%s", 3016 res->SETCLIENTID4res_u.client_using.r_netid, 3017 res->SETCLIENTID4res_u.client_using.r_addr); 3018 break; 3019 } 3020 } 3021 3022 static void 3023 dtlres_setclid(void *obj) 3024 { 3025 SETCLIENTID4res *res = (SETCLIENTID4res *)obj; 3026 3027 dtl_nfsstat4(obj); 3028 switch (res->status) { 3029 case NFS_OK: 3030 detail_clientid(res->SETCLIENTID4res_u.resok4.clientid); 3031 sprintf(get_line(0, 0), "Set Client ID Confirm Verifier = %s", 3032 tohex(res->SETCLIENTID4res_u.resok4.setclientid_confirm, 3033 NFS4_VERIFIER_SIZE)); 3034 break; 3035 case NFS4ERR_CLID_INUSE: 3036 sprintf(get_line(0, 0), "Used by Net ID = %s", 3037 res->SETCLIENTID4res_u.client_using.r_netid); 3038 sprintf(get_line(0, 0), "Used by Addr = %s", 3039 res->SETCLIENTID4res_u.client_using.r_addr); 3040 break; 3041 } 3042 } 3043 3044 static void 3045 sumres_write(char *buf, size_t buflen, void *obj) 3046 { 3047 char *bp; 3048 WRITE4res *res = (WRITE4res *)obj; 3049 3050 strncpy(buf, status_name(res->status), buflen); 3051 if (res->status == NFS4_OK) { 3052 bp = buf + strlen(buf); 3053 snprintf(bp, buflen - (bp - buf), " %u (%s)", 3054 res->WRITE4res_u.resok4.count, 3055 stable_how4_name(res->WRITE4res_u.resok4.committed)); 3056 } 3057 } 3058 3059 static void 3060 dtlres_write(void *obj) 3061 { 3062 WRITE4res *res = (WRITE4res *)obj; 3063 3064 dtl_nfsstat4(obj); 3065 if (res->status == NFS4_OK) { 3066 sprintf(get_line(0, 0), "Count = %u bytes written", 3067 res->WRITE4res_u.resok4.count); 3068 sprintf(get_line(0, 0), "Stable = %s", 3069 stable_how4_name(res->WRITE4res_u.resok4.committed)); 3070 sprintf(get_line(0, 0), "Verifier = %s", 3071 tohex(res->WRITE4res_u.resok4.writeverf, 3072 NFS4_VERIFIER_SIZE)); 3073 } 3074 } 3075 3076 /* 3077 * Print details about the nfs_resop4 that is next in the XDR stream. 3078 */ 3079 3080 static void 3081 detail_nfs_resop4(void) 3082 { 3083 int numres; 3084 nfs_resop4 one_res; 3085 void (*fmtproc)(void *); 3086 3087 numres = getxdr_long(); 3088 (void) sprintf(get_line(0, 0), "Number of results = %d", 3089 numres); 3090 3091 while (numres-- > 0) { 3092 bzero(&one_res, sizeof (one_res)); 3093 3094 if (!xdr_nfs_resop4(&xdrm, &one_res)) { 3095 xdr_free(xdr_nfs_resop4, (char *)&one_res); 3096 longjmp(xdr_err, 1); 3097 } 3098 3099 get_line(0, 0); /* blank line to separate ops */ 3100 sprintf(get_line(0, 0), "Op = %d (%s)", 3101 one_res.resop, opcode_name(one_res.resop)); 3102 if (one_res.resop < num_opcodes) 3103 fmtproc = opcode_info[one_res.resop].dtlres; 3104 else if (one_res.resop == OP_ILLEGAL) 3105 fmtproc = dtl_nfsstat4; 3106 else 3107 fmtproc = NULL; 3108 3109 if (fmtproc != NULL) 3110 fmtproc(&one_res.nfs_resop4_u); 3111 3112 /* nfs4_skip_bytes set by xdr_nfs_resop4()() */ 3113 if (nfs4_skip_bytes) 3114 nfs4_xdr_skip(nfs4_skip_bytes); 3115 3116 xdr_free(xdr_nfs_resop4, (char *)&one_res); 3117 } 3118 } 3119 3120 3121 /* 3122 * Print details about the nfs_cb_resop4 that is next in the XDR stream. 3123 */ 3124 3125 static void 3126 detail_cb_resop4(void) 3127 { 3128 int numres; 3129 nfs_cb_resop4 one_res; 3130 void (*fmtproc)(void *); 3131 3132 numres = getxdr_long(); 3133 (void) sprintf(get_line(0, 0), "Number of results = %d", 3134 numres); 3135 3136 while (numres-- > 0) { 3137 bzero(&one_res, sizeof (one_res)); 3138 if (!xdr_nfs_cb_resop4(&xdrm, &one_res)) 3139 longjmp(xdr_err, 1); 3140 3141 get_line(0, 0); /* blank line to separate ops */ 3142 sprintf(get_line(0, 0), "Op = %d (%s)", 3143 one_res.resop, cb_opcode_name(one_res.resop)); 3144 if (one_res.resop < cb_num_opcodes) 3145 fmtproc = cb_opcode_info[one_res.resop].dtlres; 3146 else if (one_res.resop == OP_CB_ILLEGAL) 3147 fmtproc = dtl_nfsstat4; 3148 else 3149 fmtproc = NULL; 3150 3151 if (fmtproc != NULL) 3152 fmtproc(&one_res.nfs_cb_resop4_u); 3153 3154 xdr_free(xdr_nfs_cb_resop4, (char *)&one_res); 3155 } 3156 } 3157 3158 3159 /* 3160 * Return the name of a lock type. 3161 */ 3162 static char * 3163 lock_type_name(enum nfs_lock_type4 type) 3164 { 3165 char *result; 3166 3167 switch (type) { 3168 case READ_LT: 3169 result = "READ"; 3170 break; 3171 case WRITE_LT: 3172 result = "WRITE"; 3173 break; 3174 case READW_LT: 3175 result = "READW"; 3176 break; 3177 case WRITEW_LT: 3178 result = "WRITEW"; 3179 break; 3180 default: 3181 result = "?"; 3182 break; 3183 } 3184 3185 return (result); 3186 } 3187 3188 /* 3189 * Return the name of an opcode. 3190 */ 3191 3192 static char * 3193 opcode_name(uint_t opnum) 3194 { 3195 static char buf[20]; 3196 3197 if (opnum < num_opcodes) 3198 return (opcode_info[opnum].name); 3199 3200 if (opnum == OP_ILLEGAL) 3201 return ("ILLEGAL"); 3202 3203 sprintf(buf, "op %d", opnum); 3204 return (buf); 3205 } 3206 3207 /* 3208 * Return the name of an opcode. 3209 */ 3210 static char * 3211 cb_opcode_name(uint_t opnum) 3212 { 3213 static char buf[20]; 3214 3215 if (opnum < cb_num_opcodes) 3216 return (cb_opcode_info[opnum].name); 3217 3218 if (opnum == OP_CB_ILLEGAL) 3219 return ("CB_ILLEGAL"); 3220 3221 sprintf(buf, "op %d", opnum); 3222 return (buf); 3223 } 3224 3225 3226 /* 3227 * Fill in a summary string for the given access bitmask. 3228 */ 3229 3230 static void 3231 sum_access4(char *buf, size_t buflen, uint32_t bits) 3232 { 3233 buf[0] = '\0'; 3234 3235 if (bits & ACCESS4_READ) 3236 (void) strncat(buf, "rd,", buflen); 3237 if (bits & ACCESS4_LOOKUP) 3238 (void) strncat(buf, "lk,", buflen); 3239 if (bits & ACCESS4_MODIFY) 3240 (void) strncat(buf, "mo,", buflen); 3241 if (bits & ACCESS4_EXTEND) 3242 (void) strncat(buf, "ext,", buflen); 3243 if (bits & ACCESS4_DELETE) 3244 (void) strncat(buf, "dl,", buflen); 3245 if (bits & ACCESS4_EXECUTE) 3246 (void) strncat(buf, "exc,", buflen); 3247 if (buf[0] != '\0') 3248 buf[strlen(buf) - 1] = '\0'; 3249 } 3250 3251 /* 3252 * Print detail information about the given access bitmask. 3253 */ 3254 3255 static void 3256 detail_access4(char *descrip, uint32_t bits) 3257 { 3258 sprintf(get_line(0, 0), "%s = 0x%08x", descrip, bits); 3259 3260 (void) sprintf(get_line(0, 0), " %s", 3261 getflag(bits, ACCESS4_READ, "Read", "(no read)")); 3262 (void) sprintf(get_line(0, 0), " %s", 3263 getflag(bits, ACCESS4_LOOKUP, "Lookup", "(no lookup)")); 3264 (void) sprintf(get_line(0, 0), " %s", 3265 getflag(bits, ACCESS4_MODIFY, "Modify", "(no modify)")); 3266 (void) sprintf(get_line(0, 0), " %s", 3267 getflag(bits, ACCESS4_EXTEND, "Extend", "(no extend)")); 3268 (void) sprintf(get_line(0, 0), " %s", 3269 getflag(bits, ACCESS4_DELETE, "Delete", "(no delete)")); 3270 (void) sprintf(get_line(0, 0), " %s", 3271 getflag(bits, ACCESS4_EXECUTE, "Execute", "(no execute)")); 3272 } 3273 3274 3275 /* 3276 * Fill in a summary string for the given open_claim4. 3277 */ 3278 static void 3279 sum_name(char *buf, size_t buflen, open_claim4 *claim) 3280 { 3281 char *bp = buf; 3282 3283 switch (claim->claim) { 3284 case CLAIM_NULL: 3285 snprintf(bp, buflen, "%s ", 3286 component_name(&claim->open_claim4_u.file)); 3287 break; 3288 case CLAIM_PREVIOUS: 3289 break; 3290 case CLAIM_DELEGATE_CUR: 3291 snprintf(bp, buflen, "%s ", 3292 component_name(&claim->open_claim4_u. 3293 delegate_cur_info.file)); 3294 break; 3295 case CLAIM_DELEGATE_PREV: 3296 snprintf(bp, buflen, "%s ", 3297 component_name(&claim->open_claim4_u. 3298 file_delegate_prev)); 3299 break; 3300 } 3301 } 3302 3303 /* 3304 * Fill in a summary string for the given open_claim4. 3305 */ 3306 static void 3307 sum_claim(char *buf, size_t buflen, open_claim4 *claim) 3308 { 3309 char *bp = buf; 3310 3311 switch (claim->claim) { 3312 case CLAIM_NULL: 3313 snprintf(bp, buflen, " CT=N"); 3314 break; 3315 case CLAIM_PREVIOUS: 3316 snprintf(bp, buflen, " CT=P DT=%s", 3317 get_deleg_typestr(claim->open_claim4_u.delegate_type)); 3318 break; 3319 case CLAIM_DELEGATE_CUR: 3320 snprintf(bp, buflen, " CT=DC %s", 3321 sum_deleg_stateid(&claim->open_claim4_u. 3322 delegate_cur_info.delegate_stateid)); 3323 break; 3324 case CLAIM_DELEGATE_PREV: 3325 snprintf(bp, buflen, " CT=DP"); 3326 break; 3327 default: 3328 snprintf(bp, buflen, " CT=?"); 3329 break; 3330 } 3331 } 3332 3333 static char * 3334 get_deleg_typestr(open_delegation_type4 dt) 3335 { 3336 char *str = ""; 3337 3338 switch (dt) { 3339 case OPEN_DELEGATE_NONE: 3340 str = "N"; 3341 break; 3342 case OPEN_DELEGATE_READ: 3343 str = "R"; 3344 break; 3345 case OPEN_DELEGATE_WRITE: 3346 str = "W"; 3347 break; 3348 default: 3349 str = "?"; 3350 } 3351 3352 return (str); 3353 } 3354 3355 /* 3356 * Print detail information for the given open_claim4. 3357 */ 3358 3359 static void 3360 detail_claim(open_claim4 *claim) 3361 { 3362 sprintf(get_line(0, 0), "Claim Type = %d (%s)", 3363 claim->claim, claim_name(claim->claim)); 3364 3365 switch (claim->claim) { 3366 case CLAIM_NULL: 3367 detail_compname4(&claim->open_claim4_u.file); 3368 break; 3369 case CLAIM_PREVIOUS: 3370 sprintf(get_line(0, 0), "Delegate Type = %s (val = %d)", 3371 get_deleg_typestr(claim->open_claim4_u.delegate_type), 3372 claim->open_claim4_u.delegate_type); 3373 break; 3374 case CLAIM_DELEGATE_CUR: 3375 detail_compname4(&claim->open_claim4_u.delegate_cur_info.file); 3376 detail_deleg_stateid(&claim->open_claim4_u.delegate_cur_info. 3377 delegate_stateid); 3378 break; 3379 case CLAIM_DELEGATE_PREV: 3380 detail_compname4(&claim->open_claim4_u.file_delegate_prev); 3381 break; 3382 } 3383 } 3384 3385 /* 3386 * Return a summary string for the given clientid4. 3387 */ 3388 static char * 3389 sum_clientid(clientid4 client) 3390 { 3391 static char buf[50]; 3392 3393 snprintf(buf, sizeof (buf), "CL=%llx", client); 3394 3395 return (buf); 3396 } 3397 3398 /* 3399 * Print a detail string for the given clientid4. 3400 */ 3401 static void 3402 detail_clientid(clientid4 client) 3403 { 3404 sprintf(get_line(0, 0), "Client ID = %llx", client); 3405 } 3406 3407 /* 3408 * Write a summary string for the given delegation into buf. 3409 */ 3410 3411 static void 3412 sum_delegation(char *buf, size_t buflen, open_delegation4 *delp) 3413 { 3414 switch (delp->delegation_type) { 3415 case OPEN_DELEGATE_NONE: 3416 snprintf(buf, buflen, " DT=N"); 3417 break; 3418 case OPEN_DELEGATE_READ: 3419 snprintf(buf, buflen, " DT=R %s", 3420 sum_deleg_stateid(&delp->open_delegation4_u.write. 3421 stateid)); 3422 break; 3423 case OPEN_DELEGATE_WRITE: 3424 snprintf(buf, buflen, " DT=W %s %s", 3425 sum_deleg_stateid(&delp->open_delegation4_u.write. 3426 stateid), 3427 sum_space_limit(&delp->open_delegation4_u.write. 3428 space_limit)); 3429 break; 3430 default: 3431 snprintf(buf, buflen, " DT=?"); 3432 break; 3433 } 3434 } 3435 3436 static void 3437 detail_delegation(open_delegation4 *delp) 3438 { 3439 sprintf(get_line(0, 0), "Delegation Type = %d (%s)", 3440 delp->delegation_type, 3441 delegation_type_name(delp->delegation_type)); 3442 3443 switch (delp->delegation_type) { 3444 case OPEN_DELEGATE_NONE: 3445 /* no-op */ 3446 break; 3447 case OPEN_DELEGATE_READ: 3448 detail_deleg_stateid(&delp->open_delegation4_u.read.stateid); 3449 sprintf(get_line(0, 0), "Recall = %s", 3450 delp->open_delegation4_u.read.recall ? 3451 "TRUE" : "FALSE"); 3452 sprintf(get_line(0, 0), "[nfsacl4]"); 3453 break; 3454 case OPEN_DELEGATE_WRITE: 3455 detail_deleg_stateid(&delp->open_delegation4_u.write.stateid); 3456 sprintf(get_line(0, 0), "Recall = %s", 3457 delp->open_delegation4_u.write.recall ? 3458 "TRUE" : "FALSE"); 3459 detail_space_limit(&delp->open_delegation4_u.write. 3460 space_limit); 3461 sprintf(get_line(0, 0), "[nfsacl4]"); 3462 break; 3463 } 3464 } 3465 3466 3467 static void 3468 detail_open_owner(open_owner4 *owner) 3469 { 3470 sprintf(get_line(0, 0), "Open Owner hash = [%04X] ", 3471 owner_hash(&owner->owner)); 3472 sprintf(get_line(0, 0), " len = %u val = %s ", 3473 owner->owner.owner_len, 3474 tohex(owner->owner.owner_val, owner->owner.owner_len)); 3475 detail_clientid(owner->clientid); 3476 } 3477 3478 static void 3479 detail_lock_owner(lock_owner4 *owner) 3480 { 3481 sprintf(get_line(0, 0), "Lock Owner hash = [%04X] ", 3482 owner_hash(&owner->owner)); 3483 sprintf(get_line(0, 0), " len = %u val = %s ", 3484 owner->owner.owner_len, 3485 tohex(owner->owner.owner_val, owner->owner.owner_len)); 3486 detail_clientid(owner->clientid); 3487 } 3488 3489 static void 3490 sum_openflag(char *bufp, int buflen, openflag4 *flagp) 3491 { 3492 if (flagp->opentype == OPEN4_CREATE) { 3493 switch (flagp->openflag4_u.how.mode) { 3494 case UNCHECKED4: 3495 snprintf(bufp, buflen, "OT=CR(U)"); 3496 break; 3497 case GUARDED4: 3498 snprintf(bufp, buflen, "OT=CR(G)"); 3499 break; 3500 case EXCLUSIVE4: 3501 snprintf(bufp, buflen, "OT=CR(E)"); 3502 break; 3503 default: 3504 snprintf(bufp, buflen, "OT=CR(?:%d)", 3505 flagp->openflag4_u.how.mode); 3506 break; 3507 } 3508 } else 3509 snprintf(bufp, buflen, "OT=NC"); 3510 } 3511 3512 static void 3513 detail_openflag(openflag4 *flagp) 3514 { 3515 sprintf(get_line(0, 0), "Open Type = %s", 3516 flagp->opentype == OPEN4_CREATE ? "CREATE" : "NOCREATE"); 3517 if (flagp->opentype == OPEN4_CREATE) 3518 detail_createhow4(&flagp->openflag4_u.how); 3519 } 3520 3521 /* 3522 * Fill in buf with the given path. 3523 */ 3524 static void 3525 sum_pathname4(char *buf, size_t buflen, pathname4 *pathp) 3526 { 3527 char *bp = buf; 3528 uint_t component; 3529 3530 for (component = 0; component < pathp->pathname4_len; 3531 component++) { 3532 snprintf(bp, buflen - (bp - buf), 3533 component == 0 ? "%s" : "/%s", 3534 component_name(&pathp->pathname4_val[component])); 3535 bp += strlen(bp); 3536 } 3537 } 3538 3539 static void 3540 sum_compname4(char *buf, size_t buflen, component4 *comp) 3541 { 3542 snprintf(buf, buflen, "%s", component_name(comp)); 3543 } 3544 3545 static void 3546 detail_compname4(component4 *comp) 3547 { 3548 sprintf(get_line(0, 0), "%s", component_name(comp)); 3549 } 3550 3551 static void 3552 detail_pathname4(pathname4 *pathp, char *what) 3553 { 3554 char *bp = get_line(0, 0); 3555 uint_t component; 3556 3557 sprintf(bp, what); 3558 bp += strlen(bp); 3559 3560 for (component = 0; component < pathp->pathname4_len; component++) { 3561 sprintf(bp, component == 0 ? "%s" : "/%s", 3562 component_name(&pathp->pathname4_val[component])); 3563 bp += strlen(bp); 3564 } 3565 } 3566 3567 /* 3568 * Print detail information about the rpcsec_gss_info that is XDR-encoded 3569 * at mem. 3570 */ 3571 3572 static void 3573 detail_rpcsec_gss(rpcsec_gss_info *info) 3574 { 3575 sprintf(get_line(0, 0), "OID = %s", 3576 tohex(info->oid.sec_oid4_val, info->oid.sec_oid4_len)); 3577 sprintf(get_line(0, 0), "QOP = %u", info->qop); 3578 sprintf(get_line(0, 0), "Service = %d (%s)", 3579 info->service, gss_svc_name(info->service)); 3580 } 3581 3582 /* 3583 * Print detail information about the given secinfo4. 3584 */ 3585 3586 static void 3587 detail_secinfo4(secinfo4 *infop) 3588 { 3589 sprintf(get_line(0, 0), "Flavor = %d (%s)", 3590 infop->flavor, flavor_name(infop->flavor)); 3591 switch (infop->flavor) { 3592 case RPCSEC_GSS: 3593 detail_rpcsec_gss(&infop->secinfo4_u.flavor_info); 3594 break; 3595 } 3596 } 3597 3598 3599 /* 3600 * Return a summary string corresponding to the given nfs_space_limit4. 3601 */ 3602 3603 static char * 3604 sum_space_limit(nfs_space_limit4 *limitp) 3605 { 3606 static char buf[64]; 3607 int buflen = sizeof (buf); 3608 3609 buf[0] = '\0'; 3610 switch (limitp->limitby) { 3611 case NFS_LIMIT_SIZE: 3612 snprintf(buf, buflen, "LB=SZ(%llu)", 3613 limitp->nfs_space_limit4_u.filesize); 3614 break; 3615 case NFS_LIMIT_BLOCKS: 3616 snprintf(buf, buflen, "LB=BL(%u*%u)", 3617 limitp->nfs_space_limit4_u.mod_blocks.num_blocks, 3618 limitp->nfs_space_limit4_u.mod_blocks.bytes_per_block); 3619 break; 3620 default: 3621 snprintf(buf, buflen, "LB=?(%d)", limitp->limitby); 3622 break; 3623 } 3624 3625 return (buf); 3626 } 3627 3628 /* 3629 * Print detail information about the given nfs_space_limit4. 3630 */ 3631 3632 static void 3633 detail_space_limit(nfs_space_limit4 *limitp) 3634 { 3635 sprintf(get_line(0, 0), "LimitBy = %d (%s)", 3636 limitp->limitby, 3637 limitby_name(limitp->limitby)); 3638 3639 switch (limitp->limitby) { 3640 case NFS_LIMIT_SIZE: 3641 sprintf(get_line(0, 0), "Bytes = %llu", 3642 limitp->nfs_space_limit4_u.filesize); 3643 break; 3644 case NFS_LIMIT_BLOCKS: 3645 sprintf(get_line(0, 0), "Blocks = %u", 3646 limitp->nfs_space_limit4_u.mod_blocks.num_blocks); 3647 sprintf(get_line(0, 0), "Bytes Per Block = %u", 3648 limitp->nfs_space_limit4_u.mod_blocks.bytes_per_block); 3649 break; 3650 } 3651 } 3652 3653 3654 /* 3655 * Return the short name of a file type. 3656 */ 3657 3658 static char * 3659 sum_type_name(nfs_ftype4 type) 3660 { 3661 static char buf[20]; 3662 3663 if (type < num_ftypes) 3664 return (ftype_names[type].short_name); 3665 else { 3666 sprintf(buf, "type %d", type); 3667 return (buf); 3668 } 3669 } 3670 3671 3672 /* 3673 * Return string with long/short flag names 3674 */ 3675 3676 static char * 3677 get_flags(uint_t flag, ftype_names_t *names, uint_t num_flags, int shortname, 3678 char *prefix) 3679 { 3680 static char buf[200]; 3681 char *bp = buf, *str; 3682 int i, len, blen = sizeof (buf); 3683 ftype_names_t *fn = NULL; 3684 3685 *bp = '\0'; 3686 3687 if (prefix) { 3688 snprintf(bp, blen, "%s", prefix); 3689 bp += (len = sizeof (bp)); 3690 blen -= len; 3691 } 3692 3693 for (i = 0; i < 32; i++) 3694 if (flag & (1 << i)) { 3695 fn = names + (i < num_flags ? i : num_flags); 3696 str = (shortname ? fn->short_name : fn->long_name); 3697 3698 snprintf(bp, blen, "%s,", str); 3699 bp += (len = strlen(bp)); 3700 blen -= len; 3701 } 3702 3703 if (fn) 3704 *(bp - 1) = '\0'; 3705 else 3706 *buf = '\0'; 3707 3708 return (buf); 3709 } 3710 3711 3712 /* 3713 * Return the long name of a file type. 3714 */ 3715 3716 static char * 3717 detail_type_name(nfs_ftype4 type) 3718 { 3719 static char buf[20]; 3720 3721 if (type < num_ftypes) 3722 return (ftype_names[type].long_name); 3723 else { 3724 sprintf(buf, "type %d", type); 3725 return (buf); 3726 } 3727 } 3728 3729 /* 3730 * Return the name of an attribute. 3731 */ 3732 3733 static char * 3734 attr_name(uint_t attrnum) 3735 { 3736 static char buf[20]; 3737 3738 if (attrnum < MAX_ATTRIBUTES) 3739 return (attr_info[attrnum].name); 3740 else { 3741 sprintf(buf, "attr #%d", attrnum); 3742 return (buf); 3743 } 3744 } 3745 3746 /* 3747 * Return the name of the given open_claim_type4. 3748 */ 3749 3750 static char * 3751 claim_name(enum open_claim_type4 claim_type) 3752 { 3753 char *result; 3754 3755 switch (claim_type) { 3756 case CLAIM_NULL: 3757 result = "NULL"; 3758 break; 3759 case CLAIM_PREVIOUS: 3760 result = "PREVIOUS"; 3761 break; 3762 case CLAIM_DELEGATE_CUR: 3763 result = "DELEGATE CURRENT"; 3764 break; 3765 case CLAIM_DELEGATE_PREV: 3766 result = "DELEGATE PREVIOUS"; 3767 break; 3768 default: 3769 result = "?"; 3770 break; 3771 } 3772 3773 return (result); 3774 } 3775 3776 /* 3777 * Return a string naming the given delegation. 3778 */ 3779 3780 static char * 3781 delegation_type_name(enum open_delegation_type4 type) 3782 { 3783 char *result; 3784 3785 switch (type) { 3786 case OPEN_DELEGATE_NONE: 3787 result = "NONE"; 3788 break; 3789 case OPEN_DELEGATE_READ: 3790 result = "READ"; 3791 break; 3792 case OPEN_DELEGATE_WRITE: 3793 result = "WRITE"; 3794 break; 3795 default: 3796 result = "?"; 3797 break; 3798 } 3799 3800 return (result); 3801 } 3802 3803 /* 3804 * Return the name of the given authentication flavor. 3805 */ 3806 3807 static char * 3808 flavor_name(uint_t flavor) 3809 { 3810 char *result; 3811 static char buf[50]; 3812 3813 switch (flavor) { 3814 case AUTH_SYS: 3815 result = "AUTH_SYS"; 3816 break; 3817 case AUTH_NONE: 3818 result = "AUTH_NONE"; 3819 break; 3820 case AUTH_DH: 3821 result = "AUTH_DH"; 3822 break; 3823 case RPCSEC_GSS: 3824 result = "RPCSEC_GSS"; 3825 break; 3826 default: 3827 sprintf(buf, "[flavor %d]", flavor); 3828 result = buf; 3829 break; 3830 } 3831 3832 return (result); 3833 } 3834 3835 /* 3836 * Return the name of the given rpc_gss_svc_t. 3837 */ 3838 3839 static char * 3840 gss_svc_name(rpc_gss_svc_t svc) 3841 { 3842 char *result; 3843 static char buf[50]; 3844 3845 switch (svc) { 3846 case RPC_GSS_SVC_NONE: 3847 result = "NONE"; 3848 break; 3849 case RPC_GSS_SVC_INTEGRITY: 3850 result = "INTEGRITY"; 3851 break; 3852 case RPC_GSS_SVC_PRIVACY: 3853 result = "PRIVACY"; 3854 break; 3855 default: 3856 sprintf(buf, "Service %d", svc); 3857 result = buf; 3858 break; 3859 } 3860 3861 return (result); 3862 } 3863 3864 /* 3865 * Return a string name for the given limit_by4. 3866 */ 3867 3868 static char * 3869 limitby_name(enum limit_by4 limitby) 3870 { 3871 char *result; 3872 3873 switch (limitby) { 3874 case NFS_LIMIT_SIZE: 3875 result = "SIZE"; 3876 break; 3877 case NFS_LIMIT_BLOCKS: 3878 result = "BLOCKS"; 3879 break; 3880 default: 3881 result = "?"; 3882 break; 3883 } 3884 3885 return (result); 3886 } 3887 3888 static char * 3889 status_name(int status) 3890 { 3891 char *p; 3892 3893 switch (status) { 3894 case NFS4_OK: p = "NFS4_OK"; break; 3895 case NFS4ERR_PERM: p = "NFS4ERR_PERM"; break; 3896 case NFS4ERR_NOENT: p = "NFS4ERR_NOENT"; break; 3897 case NFS4ERR_IO: p = "NFS4ERR_IO"; break; 3898 case NFS4ERR_NXIO: p = "NFS4ERR_NXIO"; break; 3899 case NFS4ERR_ACCESS: p = "NFS4ERR_ACCESS"; break; 3900 case NFS4ERR_EXIST: p = "NFS4ERR_EXIST"; break; 3901 case NFS4ERR_XDEV: p = "NFS4ERR_XDEV"; break; 3902 case NFS4ERR_NOTDIR: p = "NFS4ERR_NOTDIR"; break; 3903 case NFS4ERR_ISDIR: p = "NFS4ERR_ISDIR"; break; 3904 case NFS4ERR_INVAL: p = "NFS4ERR_INVAL"; break; 3905 case NFS4ERR_FBIG: p = "NFS4ERR_FBIG"; break; 3906 case NFS4ERR_NOSPC: p = "NFS4ERR_NOSPC"; break; 3907 case NFS4ERR_ROFS: p = "NFS4ERR_ROFS"; break; 3908 case NFS4ERR_MLINK: p = "NFS4ERR_MLINK"; break; 3909 case NFS4ERR_NAMETOOLONG:p = "NFS4ERR_NAMETOOLONG"; break; 3910 case NFS4ERR_NOTEMPTY: p = "NFS4ERR_NOTEMPTY"; break; 3911 case NFS4ERR_DQUOT: p = "NFS4ERR_DQUOT"; break; 3912 case NFS4ERR_STALE: p = "NFS4ERR_STALE"; break; 3913 case NFS4ERR_BADHANDLE: p = "NFS4ERR_BADHANDLE"; break; 3914 case NFS4ERR_BAD_COOKIE:p = "NFS4ERR_BAD_COOKIE"; break; 3915 case NFS4ERR_NOTSUPP: p = "NFS4ERR_NOTSUPP"; break; 3916 case NFS4ERR_TOOSMALL: p = "NFS4ERR_TOOSMALL"; break; 3917 case NFS4ERR_SERVERFAULT:p = "NFS4ERR_SERVERFAULT"; break; 3918 case NFS4ERR_BADTYPE: p = "NFS4ERR_BADTYPE"; break; 3919 case NFS4ERR_DELAY: p = "NFS4ERR_DELAY"; break; 3920 case NFS4ERR_SAME: p = "NFS4ERR_SAME"; break; 3921 case NFS4ERR_DENIED: p = "NFS4ERR_DENIED"; break; 3922 case NFS4ERR_EXPIRED: p = "NFS4ERR_EXPIRED"; break; 3923 case NFS4ERR_LOCKED: p = "NFS4ERR_LOCKED"; break; 3924 case NFS4ERR_GRACE: p = "NFS4ERR_GRACE"; break; 3925 case NFS4ERR_FHEXPIRED: p = "NFS4ERR_FHEXPIRED"; break; 3926 case NFS4ERR_SHARE_DENIED: p = "NFS4ERR_SHARE_DENIED"; break; 3927 case NFS4ERR_WRONGSEC: p = "NFS4ERR_WRONGSEC"; break; 3928 case NFS4ERR_CLID_INUSE: p = "NFS4ERR_CLID_INUSE"; break; 3929 case NFS4ERR_RESOURCE: p = "NFS4ERR_RESOURCE"; break; 3930 case NFS4ERR_MOVED: p = "NFS4ERR_MOVED"; break; 3931 case NFS4ERR_NOFILEHANDLE: p = "NFS4ERR_NOFILEHANDLE"; break; 3932 case NFS4ERR_MINOR_VERS_MISMATCH: p = "NFS4ERR_MINOR_VERS_MISMATCH"; 3933 break; 3934 case NFS4ERR_STALE_CLIENTID: p = "NFS4ERR_STALE_CLIENTID"; break; 3935 case NFS4ERR_STALE_STATEID: p = "NFS4ERR_STALE_STATEID"; break; 3936 case NFS4ERR_OLD_STATEID: p = "NFS4ERR_OLD_STATEID"; break; 3937 case NFS4ERR_BAD_STATEID: p = "NFS4ERR_BAD_STATEID"; break; 3938 case NFS4ERR_BAD_SEQID: p = "NFS4ERR_BAD_SEQID"; break; 3939 case NFS4ERR_NOT_SAME: p = "NFS4ERR_NOT_SAME"; break; 3940 case NFS4ERR_LOCK_RANGE: p = "NFS4ERR_LOCK_RANGE"; break; 3941 case NFS4ERR_SYMLINK: p = "NFS4ERR_SYMLINK"; break; 3942 case NFS4ERR_RESTOREFH: p = "NFS4ERR_RESTOREFH"; break; 3943 case NFS4ERR_LEASE_MOVED: p = "NFS4ERR_LEASE_MOVED"; break; 3944 case NFS4ERR_ATTRNOTSUPP: p = "NFS4ERR_ATTRNOTSUPP"; break; 3945 case NFS4ERR_NO_GRACE: p = "NFS4ERR_NO_GRACE"; break; 3946 case NFS4ERR_RECLAIM_BAD: p = "NFS4ERR_RECLAIM_BAD"; break; 3947 case NFS4ERR_RECLAIM_CONFLICT: p = "NFS4ERR_RECLAIM_CONFLICT"; break; 3948 case NFS4ERR_BADXDR: p = "NFS4ERR_BADXDR"; break; 3949 case NFS4ERR_LOCKS_HELD: p = "NFS4ERR_LOCKS_HELD"; break; 3950 case NFS4ERR_OPENMODE: p = "NFS4ERR_OPENMODE"; break; 3951 case NFS4ERR_BADOWNER: p = "NFS4ERR_BADOWNER"; break; 3952 case NFS4ERR_BADCHAR: p = "NFS4ERR_BADCHAR"; break; 3953 case NFS4ERR_BADNAME: p = "NFS4ERR_BADNAME"; break; 3954 case NFS4ERR_BAD_RANGE: p = "NFS4ERR_BAD_RANGE"; break; 3955 case NFS4ERR_LOCK_NOTSUPP: p = "NFS4ERR_LOCK_NOTSUPP"; break; 3956 case NFS4ERR_OP_ILLEGAL: p = "NFS4ERR_OP_ILLEGAL"; break; 3957 case NFS4ERR_DEADLOCK: p = "NFS4ERR_DEADLOCK"; break; 3958 case NFS4ERR_FILE_OPEN: p = "NFS4ERR_FILE_OPEN"; break; 3959 case NFS4ERR_ADMIN_REVOKED: p = "NFS4ERR_ADMIN_REVOKED"; break; 3960 case NFS4ERR_CB_PATH_DOWN: p = "NFS4ERR_CB_PATH_DOWN"; break; 3961 default: p = "(unknown error)"; break; 3962 } 3963 3964 return (p); 3965 } 3966 3967 char * 3968 nfsstat4_to_name(int status) 3969 { 3970 return (status_name(status)); 3971 } 3972 3973 /* 3974 * Attribute print functions. See attr_info_t. 3975 */ 3976 3977 static void 3978 prt_supported_attrs(XDR *xdr) 3979 { 3980 static bitmap4 val; 3981 3982 if (!xdr_bitmap4(xdr, &val)) 3983 longjmp(xdr_err, 1); 3984 sprintf(get_line(0, 0), "Supported Attributes:"); 3985 detail_attr_bitmap("\t", &val, NULL); 3986 xdr_free(xdr_bitmap4, (char *)&val); 3987 } 3988 3989 static void 3990 prt_type(XDR *xdr) 3991 { 3992 nfs_ftype4 val; 3993 3994 if (!xdr_nfs_ftype4(xdr, &val)) 3995 longjmp(xdr_err, 1); 3996 sprintf(get_line(0, 0), "Type = %s", sum_type_name(val)); 3997 } 3998 3999 static void 4000 prt_fh_expire_type(XDR *xdr) 4001 { 4002 fattr4_fh_expire_type val; 4003 char *buf; 4004 bool_t first = TRUE; 4005 4006 if (!xdr_fattr4_fh_expire_type(xdr, &val)) 4007 longjmp(xdr_err, 1); 4008 buf = get_line(0, 0); 4009 4010 sprintf(buf, "Filehandle expire type = "); 4011 if ((val & (FH4_NOEXPIRE_WITH_OPEN | FH4_VOLATILE_ANY | 4012 FH4_VOL_MIGRATION | FH4_VOL_RENAME)) == 0) { 4013 strcat(buf, "Persistent"); 4014 return; 4015 } 4016 if (val & FH4_NOEXPIRE_WITH_OPEN) { 4017 strcat(buf, "No Expire With OPEN"); 4018 first = FALSE; 4019 } 4020 if (val & FH4_VOLATILE_ANY) { 4021 if (first) 4022 first = FALSE; 4023 else 4024 strcat(buf, ", "); 4025 strcat(buf, "Volatile at any time"); 4026 } 4027 if (val & FH4_VOL_MIGRATION) { 4028 if (first) 4029 first = FALSE; 4030 else 4031 strcat(buf, ", "); 4032 strcat(buf, "Volatile at Migration"); 4033 } 4034 if (val & FH4_VOL_RENAME) { 4035 if (first) 4036 first = FALSE; 4037 else 4038 strcat(buf, ", "); 4039 strcat(buf, "Volatile at Rename"); 4040 } 4041 } 4042 4043 static void 4044 prt_change(XDR *xdr) 4045 { 4046 changeid4 val; 4047 4048 if (!xdr_changeid4(xdr, &val)) 4049 longjmp(xdr_err, 1); 4050 sprintf(get_line(0, 0), "Change ID = 0x%llx", val); 4051 /* XXX print as time_t, too? */ 4052 } 4053 4054 static void 4055 prt_size(XDR *xdr) 4056 { 4057 uint64_t val; 4058 4059 if (!xdr_uint64_t(xdr, &val)) 4060 longjmp(xdr_err, 1); 4061 sprintf(get_line(0, 0), "Size = %llu", val); 4062 } 4063 4064 static void 4065 prt_link_support(XDR *xdr) 4066 { 4067 bool_t val; 4068 4069 if (!xdr_bool(xdr, &val)) 4070 longjmp(xdr_err, 1); 4071 sprintf(get_line(0, 0), "Link Support = %s", 4072 val ? "TRUE" : "FALSE"); 4073 } 4074 4075 static void 4076 prt_symlink_support(XDR *xdr) 4077 { 4078 bool_t val; 4079 4080 if (!xdr_bool(xdr, &val)) 4081 longjmp(xdr_err, 1); 4082 sprintf(get_line(0, 0), "Symlink Support = %s", 4083 val ? "TRUE" : "FALSE"); 4084 } 4085 4086 static void 4087 prt_named_attr(XDR *xdr) 4088 { 4089 bool_t val; 4090 4091 if (!xdr_bool(xdr, &val)) 4092 longjmp(xdr_err, 1); 4093 sprintf(get_line(0, 0), "Has Named Attributes = %s", 4094 val ? "TRUE" : "FALSE"); 4095 } 4096 4097 static void 4098 prt_fsid(XDR *xdr) 4099 { 4100 fsid4 val; 4101 4102 if (!xdr_fsid4(xdr, &val)) 4103 longjmp(xdr_err, 1); 4104 sprintf(get_line(0, 0), "FS ID: Major = %llx, Minor = %llx", 4105 val.major, val.minor); 4106 } 4107 4108 static void 4109 prt_unique_handles(XDR *xdr) 4110 { 4111 bool_t val; 4112 4113 if (!xdr_bool(xdr, &val)) 4114 longjmp(xdr_err, 1); 4115 sprintf(get_line(0, 0), "Unique Handles = %s", 4116 val ? "TRUE" : "FALSE"); 4117 } 4118 4119 static void 4120 prt_lease_time(XDR *xdr) 4121 { 4122 uint32_t val; 4123 4124 if (!xdr_uint32_t(xdr, &val)) 4125 longjmp(xdr_err, 1); 4126 sprintf(get_line(0, 0), "Lease Time = %u", val); 4127 } 4128 4129 static void 4130 prt_rdattr_error(XDR *xdr) 4131 { 4132 nfsstat4 val; 4133 4134 if (!xdr_nfsstat4(xdr, &val)) 4135 longjmp(xdr_err, 1); 4136 sprintf(get_line(0, 0), "Rdattr Error = %u (%s)", 4137 val, status_name(val)); 4138 } 4139 4140 static void 4141 prt_acl(XDR *xdr) 4142 { 4143 static fattr4_acl val; 4144 char buffy[NFS4_OPAQUE_LIMIT]; 4145 int i, len; 4146 4147 if (!xdr_fattr4_acl(xdr, &val)) 4148 longjmp(xdr_err, 1); 4149 sprintf(get_line(0, 0), "ACL of %d entries", val.fattr4_acl_len); 4150 for (i = 0; i < val.fattr4_acl_len; i++) { 4151 sprintf(get_line(0, 0), "nfsace4[%d]", i); 4152 4153 sprintf(get_line(0, 0), " type = %x", 4154 val.fattr4_acl_val[i].type); 4155 detail_acetype4(val.fattr4_acl_val[i].type); 4156 4157 sprintf(get_line(0, 0), " flags = %x", 4158 val.fattr4_acl_val[i].flag); 4159 detail_aceflag4(val.fattr4_acl_val[i].flag); 4160 4161 sprintf(get_line(0, 0), " mask = %x", 4162 val.fattr4_acl_val[i].access_mask); 4163 detail_acemask4(val.fattr4_acl_val[i].access_mask); 4164 4165 len = val.fattr4_acl_val[i].who.utf8string_len; 4166 if (len >= NFS4_OPAQUE_LIMIT) 4167 len = NFS4_OPAQUE_LIMIT - 1; 4168 (void) strncpy(buffy, val.fattr4_acl_val[i].who.utf8string_val, 4169 len); 4170 buffy[len] = '\0'; 4171 sprintf(get_line(0, 0), " who = %s", buffy); 4172 } 4173 xdr_free(xdr_fattr4_acl, (char *)&val); 4174 } 4175 4176 static void 4177 detail_acetype4(acetype4 type) 4178 { 4179 if (type >= ACETYPE4_NAMES_MAX) { 4180 sprintf(get_line(0, 0), " unknown type"); 4181 } else { 4182 sprintf(get_line(0, 0), " %s", acetype4_names[type]); 4183 } 4184 } 4185 4186 static void 4187 detail_uint32_bitmap(uint32_t mask, char *mask_names[], int names_max) 4188 { 4189 char buffy[BUFSIZ], *name; 4190 char *indent = " "; 4191 char *spacer = " "; 4192 int pending = 0; 4193 int bit; 4194 int len, namelen, spacelen; 4195 4196 strcpy(buffy, indent); 4197 len = strlen(buffy); 4198 spacelen = strlen(spacer); 4199 4200 for (bit = 0; bit < names_max; bit++) { 4201 if (mask & (1 << bit)) { 4202 name = mask_names[bit]; 4203 namelen = strlen(name); 4204 /* 80 - 6 for "NFS: " = 74 */ 4205 if ((len + spacelen + namelen) >= 74) { 4206 sprintf(get_line(0, 0), "%s", buffy); 4207 strcpy(buffy, indent); 4208 len = strlen(buffy); 4209 pending = 0; 4210 } 4211 (void) strlcat(buffy, spacer, sizeof (buffy)); 4212 (void) strlcat(buffy, name, sizeof (buffy)); 4213 pending = 1; 4214 len += spacelen + namelen; 4215 } 4216 } 4217 if (pending) 4218 sprintf(get_line(0, 0), "%s", buffy); 4219 } 4220 4221 static void 4222 detail_aceflag4(aceflag4 flag) 4223 { 4224 detail_uint32_bitmap(flag, aceflag4_names, ACEFLAG4_NAMES_MAX); 4225 } 4226 4227 static void 4228 detail_acemask4(acemask4 mask) 4229 { 4230 detail_uint32_bitmap(mask, acemask4_names, ACEMASK4_NAMES_MAX); 4231 } 4232 4233 static void 4234 prt_aclsupport(XDR *xdr) 4235 { 4236 fattr4_aclsupport val; 4237 4238 if (!xdr_fattr4_aclsupport(xdr, &val)) 4239 longjmp(xdr_err, 1); 4240 if (val & ACL4_SUPPORT_ALLOW_ACL) 4241 sprintf(get_line(0, 0), "ALLOW ACL Supported"); 4242 if (val & ACL4_SUPPORT_DENY_ACL) 4243 sprintf(get_line(0, 0), "DENY ACL Supported"); 4244 if (val & ACL4_SUPPORT_AUDIT_ACL) 4245 sprintf(get_line(0, 0), "AUDIT ACL Supported"); 4246 if (val & ACL4_SUPPORT_ALARM_ACL) 4247 sprintf(get_line(0, 0), "ALARM ACL Supported"); 4248 } 4249 4250 static void 4251 prt_archive(XDR *xdr) 4252 { 4253 bool_t val; 4254 4255 if (!xdr_bool(xdr, &val)) 4256 longjmp(xdr_err, 1); 4257 sprintf(get_line(0, 0), "Archived = %s", 4258 val ? "TRUE" : "FALSE"); 4259 } 4260 4261 static void 4262 prt_cansettime(XDR *xdr) 4263 { 4264 bool_t val; 4265 4266 if (!xdr_bool(xdr, &val)) 4267 longjmp(xdr_err, 1); 4268 sprintf(get_line(0, 0), "Server Can Set Time = %s", 4269 val ? "TRUE" : "FALSE"); 4270 } 4271 4272 static void 4273 prt_case_insensitive(XDR *xdr) 4274 { 4275 bool_t val; 4276 4277 if (!xdr_bool(xdr, &val)) 4278 longjmp(xdr_err, 1); 4279 sprintf(get_line(0, 0), "Case Insensitive Lookups = %s", 4280 val ? "TRUE" : "FALSE"); 4281 } 4282 4283 static void 4284 prt_case_preserving(XDR *xdr) 4285 { 4286 bool_t val; 4287 4288 if (!xdr_bool(xdr, &val)) 4289 longjmp(xdr_err, 1); 4290 sprintf(get_line(0, 0), "Case Preserving = %s", 4291 val ? "TRUE" : "FALSE"); 4292 } 4293 4294 static void 4295 prt_chown_restricted(XDR *xdr) 4296 { 4297 bool_t val; 4298 4299 if (!xdr_bool(xdr, &val)) 4300 longjmp(xdr_err, 1); 4301 sprintf(get_line(0, 0), "Chown Is Restricted = %s", 4302 val ? "TRUE" : "FALSE"); 4303 } 4304 4305 static void 4306 prt_filehandle(XDR *xdr) 4307 { 4308 static nfs_fh4 val; 4309 4310 if (!xdr_nfs_fh4(xdr, &val)) 4311 longjmp(xdr_err, 1); 4312 detail_fh4(&val); 4313 xdr_free(xdr_nfs_fh4, (char *)&val); 4314 } 4315 4316 static void 4317 prt_fileid(XDR *xdr) 4318 { 4319 uint64_t val; 4320 4321 if (!xdr_uint64_t(xdr, &val)) 4322 longjmp(xdr_err, 1); 4323 sprintf(get_line(0, 0), "File ID = %llu", val); 4324 } 4325 4326 static void 4327 prt_mounted_on_fileid(XDR *xdr) 4328 { 4329 uint64_t val; 4330 4331 if (!xdr_uint64_t(xdr, &val)) 4332 longjmp(xdr_err, 1); 4333 sprintf(get_line(0, 0), "Mounted On File ID = %llu", val); 4334 } 4335 4336 static void 4337 prt_files_avail(XDR *xdr) 4338 { 4339 uint64_t val; 4340 4341 if (!xdr_uint64_t(xdr, &val)) 4342 longjmp(xdr_err, 1); 4343 sprintf(get_line(0, 0), "Files Available = %llu", val); 4344 } 4345 4346 static void 4347 prt_files_free(XDR *xdr) 4348 { 4349 uint64_t val; 4350 4351 if (!xdr_uint64_t(xdr, &val)) 4352 longjmp(xdr_err, 1); 4353 sprintf(get_line(0, 0), "Files Free = %llu", val); 4354 } 4355 4356 static void 4357 prt_files_total(XDR *xdr) 4358 { 4359 uint64_t val; 4360 4361 if (!xdr_uint64_t(xdr, &val)) 4362 longjmp(xdr_err, 1); 4363 sprintf(get_line(0, 0), "Files Total = %llu", val); 4364 } 4365 4366 static void 4367 prt_fs_location(fs_location4 *fsl) 4368 { 4369 int i; 4370 4371 for (i = 0; i < fsl->server.server_len; i++) 4372 sprintf(get_line(0, 0), "server: %s", 4373 utf8localize(&fsl->server.server_val[i])); 4374 4375 detail_pathname4(&fsl->rootpath, "rootpath: "); 4376 } 4377 4378 static void 4379 prt_fs_locations(XDR *xdr) 4380 { 4381 static fs_locations4 val; 4382 int i; 4383 4384 if (!xdr_fs_locations4(xdr, &val)) 4385 longjmp(xdr_err, 1); 4386 sprintf(get_line(0, 0), "[fs_locations]"); 4387 detail_pathname4(&val.fs_root, "fs_root: "); 4388 for (i = 0; i < val.locations.locations_len; i++) 4389 prt_fs_location(&val.locations.locations_val[i]); 4390 xdr_free(xdr_fs_locations4, (char *)&val); 4391 } 4392 4393 static void 4394 prt_hidden(XDR *xdr) 4395 { 4396 bool_t val; 4397 4398 if (!xdr_bool(xdr, &val)) 4399 longjmp(xdr_err, 1); 4400 sprintf(get_line(0, 0), "Hidden = %s", 4401 val ? "TRUE" : "FALSE"); 4402 } 4403 4404 static void 4405 prt_homogeneous(XDR *xdr) 4406 { 4407 bool_t val; 4408 4409 if (!xdr_bool(xdr, &val)) 4410 longjmp(xdr_err, 1); 4411 sprintf(get_line(0, 0), "FS Is Homogeneous = %s", 4412 val ? "TRUE" : "FALSE"); 4413 } 4414 4415 static void 4416 prt_maxfilesize(XDR *xdr) 4417 { 4418 uint64_t val; 4419 4420 if (!xdr_uint64_t(xdr, &val)) 4421 longjmp(xdr_err, 1); 4422 sprintf(get_line(0, 0), "Maximum File Size = %llu", val); 4423 } 4424 4425 static void 4426 prt_maxlink(XDR *xdr) 4427 { 4428 uint32_t val; 4429 4430 if (!xdr_uint32_t(xdr, &val)) 4431 longjmp(xdr_err, 1); 4432 sprintf(get_line(0, 0), "Maximum Number of Links = %u", val); 4433 } 4434 4435 static void 4436 prt_maxname(XDR *xdr) 4437 { 4438 uint32_t val; 4439 4440 if (!xdr_uint32_t(xdr, &val)) 4441 longjmp(xdr_err, 1); 4442 sprintf(get_line(0, 0), "Maximum File Name Length = %u", val); 4443 } 4444 4445 static void 4446 prt_maxread(XDR *xdr) 4447 { 4448 uint64_t val; 4449 4450 if (!xdr_uint64_t(xdr, &val)) 4451 longjmp(xdr_err, 1); 4452 sprintf(get_line(0, 0), "Maximum Read Size = %llu", val); 4453 } 4454 4455 static void 4456 prt_maxwrite(XDR *xdr) 4457 { 4458 uint64_t val; 4459 4460 if (!xdr_uint64_t(xdr, &val)) 4461 longjmp(xdr_err, 1); 4462 4463 sprintf(get_line(0, 0), "Maximum Write Size = %llu", val); 4464 } 4465 4466 static void 4467 prt_mimetype(XDR *xdr) 4468 { 4469 static utf8string val; 4470 4471 if (!xdr_utf8string(xdr, &val)) 4472 longjmp(xdr_err, 1); 4473 sprintf(get_line(0, 0), "MIME Type = %s", utf8localize(&val)); 4474 xdr_free(xdr_utf8string, (char *)&val); 4475 } 4476 4477 static void 4478 prt_mode(XDR *xdr) 4479 { 4480 mode4 val; 4481 4482 if (!xdr_mode4(xdr, &val)) 4483 longjmp(xdr_err, 1); 4484 sprintf(get_line(0, 0), "Mode = 0%03o", val); 4485 } 4486 4487 static void 4488 prt_no_trunc(XDR *xdr) 4489 { 4490 bool_t val; 4491 4492 if (!xdr_bool(xdr, &val)) 4493 longjmp(xdr_err, 1); 4494 sprintf(get_line(0, 0), "Long Names Are Error (no_trunc) = %s", 4495 val ? "TRUE" : "FALSE"); 4496 } 4497 4498 static void 4499 prt_numlinks(XDR *xdr) 4500 { 4501 uint32_t val; 4502 4503 if (!xdr_uint32_t(xdr, &val)) 4504 longjmp(xdr_err, 1); 4505 sprintf(get_line(0, 0), "Number of Links = %u", val); 4506 } 4507 4508 static void 4509 prt_owner(XDR *xdr) 4510 { 4511 static utf8string val; 4512 4513 if (!xdr_utf8string(xdr, &val)) 4514 longjmp(xdr_err, 1); 4515 sprintf(get_line(0, 0), "Owner = %s", utf8localize(&val)); 4516 xdr_free(xdr_utf8string, (char *)&val); 4517 } 4518 4519 static void 4520 prt_owner_group(XDR *xdr) 4521 { 4522 static utf8string val; 4523 4524 if (!xdr_utf8string(xdr, &val)) 4525 longjmp(xdr_err, 1); 4526 sprintf(get_line(0, 0), "Group = %s", utf8localize(&val)); 4527 xdr_free(xdr_utf8string, (char *)&val); 4528 } 4529 4530 static void 4531 prt_quota_avail_hard(XDR *xdr) 4532 { 4533 uint64_t val; 4534 4535 if (!xdr_uint64_t(xdr, &val)) 4536 longjmp(xdr_err, 1); 4537 sprintf(get_line(0, 0), "Quota Hard Limit = %llu", val); 4538 } 4539 4540 static void 4541 prt_quota_avail_soft(XDR *xdr) 4542 { 4543 uint64_t val; 4544 4545 if (!xdr_uint64_t(xdr, &val)) 4546 longjmp(xdr_err, 1); 4547 sprintf(get_line(0, 0), "Quota Soft Limit = %llu", val); 4548 } 4549 4550 static void 4551 prt_quota_used(XDR *xdr) 4552 { 4553 uint64_t val; 4554 4555 if (!xdr_uint64_t(xdr, &val)) 4556 longjmp(xdr_err, 1); 4557 sprintf(get_line(0, 0), "Quota Used = %llu", val); 4558 } 4559 4560 static void 4561 prt_rawdev(XDR *xdr) 4562 { 4563 specdata4 val; 4564 4565 if (!xdr_specdata4(xdr, &val)) 4566 longjmp(xdr_err, 1); 4567 sprintf(get_line(0, 0), "Raw Device ID = %u, %u", 4568 val.specdata1, val.specdata2); 4569 } 4570 4571 static void 4572 prt_space_avail(XDR *xdr) 4573 { 4574 uint64_t val; 4575 4576 if (!xdr_uint64_t(xdr, &val)) 4577 longjmp(xdr_err, 1); 4578 sprintf(get_line(0, 0), "Space Available = %llu", val); 4579 } 4580 4581 static void 4582 prt_space_free(XDR *xdr) 4583 { 4584 uint64_t val; 4585 4586 if (!xdr_uint64_t(xdr, &val)) 4587 longjmp(xdr_err, 1); 4588 sprintf(get_line(0, 0), "Space Free = %llu", val); 4589 } 4590 4591 static void 4592 prt_space_total(XDR *xdr) 4593 { 4594 uint64_t val; 4595 4596 if (!xdr_uint64_t(xdr, &val)) 4597 longjmp(xdr_err, 1); 4598 sprintf(get_line(0, 0), "Total Disk Space = %llu", val); 4599 } 4600 4601 static void 4602 prt_space_used(XDR *xdr) 4603 { 4604 uint64_t val; 4605 4606 if (!xdr_uint64_t(xdr, &val)) 4607 longjmp(xdr_err, 1); 4608 sprintf(get_line(0, 0), "Space Used (this object) = %llu", val); 4609 } 4610 4611 static void 4612 prt_system(XDR *xdr) 4613 { 4614 bool_t val; 4615 4616 if (!xdr_bool(xdr, &val)) 4617 longjmp(xdr_err, 1); 4618 sprintf(get_line(0, 0), "System File = %s", 4619 val ? "TRUE" : "FALSE"); 4620 } 4621 4622 static void 4623 prt_time_access(XDR *xdr) 4624 { 4625 nfstime4 val; 4626 4627 if (!xdr_nfstime4(xdr, &val)) 4628 longjmp(xdr_err, 1); 4629 sprintf(get_line(0, 0), "Last Access Time = %s", 4630 format_time(val.seconds, val.nseconds)); 4631 } 4632 4633 static void 4634 prt_time_access_set(XDR *xdr) 4635 { 4636 settime4 val; 4637 4638 if (!xdr_settime4(xdr, &val)) 4639 longjmp(xdr_err, 1); 4640 if (val.set_it == SET_TO_CLIENT_TIME4) { 4641 sprintf(get_line(0, 0), "Access Time = %s (set to client time)", 4642 format_time(val.settime4_u.time.seconds, 4643 val.settime4_u.time.nseconds)); 4644 } else if (val.set_it == SET_TO_SERVER_TIME4) { 4645 sprintf(get_line(0, 0), "Access Time (set to server time)"); 4646 } else 4647 longjmp(xdr_err, 1); 4648 } 4649 4650 static void 4651 prt_time_backup(XDR *xdr) 4652 { 4653 nfstime4 val; 4654 4655 if (!xdr_nfstime4(xdr, &val)) 4656 longjmp(xdr_err, 1); 4657 sprintf(get_line(0, 0), "Last Backup Time = %s", 4658 format_time(val.seconds, val.nseconds)); 4659 } 4660 4661 static void 4662 prt_time_create(XDR *xdr) 4663 { 4664 nfstime4 val; 4665 4666 if (!xdr_nfstime4(xdr, &val)) 4667 longjmp(xdr_err, 1); 4668 sprintf(get_line(0, 0), "Creation Time = %s", 4669 format_time(val.seconds, val.nseconds)); 4670 } 4671 4672 static void 4673 prt_time_delta(XDR *xdr) 4674 { 4675 nfstime4 val; 4676 4677 if (!xdr_nfstime4(xdr, &val)) 4678 longjmp(xdr_err, 1); 4679 sprintf(get_line(0, 0), "Server Time Granularity = %lld.%09d sec", 4680 val.seconds, val.nseconds); 4681 } 4682 4683 static void 4684 prt_time_metadata(XDR *xdr) 4685 { 4686 nfstime4 val; 4687 4688 if (!xdr_nfstime4(xdr, &val)) 4689 longjmp(xdr_err, 1); 4690 sprintf(get_line(0, 0), "Last Metadata Change Time = %s", 4691 format_time(val.seconds, val.nseconds)); 4692 } 4693 4694 static void 4695 prt_time_modify(XDR *xdr) 4696 { 4697 nfstime4 val; 4698 4699 if (!xdr_nfstime4(xdr, &val)) 4700 longjmp(xdr_err, 1); 4701 sprintf(get_line(0, 0), "Last Modification Time = %s", 4702 format_time(val.seconds, val.nseconds)); 4703 } 4704 4705 static void 4706 prt_time_modify_set(XDR *xdr) 4707 { 4708 settime4 val; 4709 4710 if (!xdr_settime4(xdr, &val)) 4711 longjmp(xdr_err, 1); 4712 if (val.set_it == SET_TO_CLIENT_TIME4) { 4713 sprintf(get_line(0, 0), 4714 "Modification Time = %s (set to client time)", 4715 format_time(val.settime4_u.time.seconds, 4716 val.settime4_u.time.nseconds)); 4717 } else if (val.set_it == SET_TO_SERVER_TIME4) { 4718 sprintf(get_line(0, 0), 4719 "Modification Time (set to server time)"); 4720 } else 4721 longjmp(xdr_err, 1); 4722 } 4723 4724 /* 4725 * Display the UTF8 string that is next in the XDR stream. 4726 */ 4727 4728 static void 4729 showxdr_utf8string(char *fmt) 4730 { 4731 static utf8string string; 4732 4733 if (!xdr_utf8string(&xdrm, &string)) 4734 longjmp(xdr_err, 1); 4735 sprintf(get_line(0, 0), fmt, utf8localize(&string)); 4736 xdr_free(xdr_utf8string, (char *)&string); 4737 } 4738 4739 /* 4740 * utf8string is defined in nfs4_prot.x as an opaque array, which means 4741 * when it is decoded into a string, the string might not have a trailing 4742 * null. Also, the string will still be encoded in UTF-8, rather than 4743 * whatever character encoding is associated with the current locale. This 4744 * routine converts a utf8string into a (null-terminated) C string. One day 4745 * it will convert into the current character encoding, too. To avoid 4746 * dealing with storage management issues, it allocates storage for each 4747 * new string, then this storage is "freed" when the packet has been 4748 * processed. 4749 */ 4750 4751 #define MAX_UTF8_STRINGS 512 4752 4753 static char *utf_buf[MAX_UTF8_STRINGS]; 4754 static size_t utf_buflen[MAX_UTF8_STRINGS]; 4755 static uint_t cur_utf_buf = 0; 4756 4757 static char * 4758 utf8localize(utf8string *utf8str) 4759 { 4760 size_t newsize, oldsize, len; 4761 char *result, *cp; 4762 4763 len = utf8str->utf8string_len; 4764 if (len == 0) 4765 return (""); 4766 if (cur_utf_buf >= MAX_UTF8_STRINGS) 4767 return ("[Too Many UTF-8 Strings]"); 4768 4769 newsize = oldsize = utf_buflen[cur_utf_buf]; 4770 4771 4772 if (oldsize < len + 1) { 4773 /* truncate opaques at NFS4_OPAQUE_LIMIT */ 4774 if (len > NFS4_OPAQUE_LIMIT) 4775 len = NFS4_OPAQUE_LIMIT; 4776 newsize = len + 1; 4777 } 4778 if (newsize != oldsize) { 4779 utf_buf[cur_utf_buf] = realloc(utf_buf[cur_utf_buf], 4780 newsize); 4781 if (utf_buf[cur_utf_buf] == NULL) { 4782 pr_err("out of memory\n"); 4783 utf_buflen[cur_utf_buf] = 0; 4784 return (""); 4785 } 4786 utf_buflen[cur_utf_buf] = newsize; 4787 } 4788 4789 result = utf_buf[cur_utf_buf]; 4790 strncpy(result, utf8str->utf8string_val, len); 4791 result[len] = '\0'; 4792 for (cp = result; cp < result + len; cp++) { 4793 if (!isprint(*cp)) { 4794 *cp = '.'; 4795 } 4796 } 4797 4798 cur_utf_buf++; 4799 4800 return (result); 4801 } 4802 4803 static void 4804 utf8free() 4805 { 4806 cur_utf_buf = 0; 4807 } 4808 4809 4810 /* 4811 * adler16(): adler32 hash code shamelessly copied and mutiliated from 4812 * usr/src/uts/common/io/ppp/spppcomp/zlib.[ch] 4813 * 4814 * The alg was originally created to provide a running 4815 * checksum, but we don't need that -- we just want to 4816 * chksum data described by buf,len; therefore, the first 4817 * parameter was removed (held the running checksum), 4818 * and s1/s2 are always set to their required initial 4819 * values (1 and 0). I also ripped out code which only 4820 * applied to large data sets (bufs larger than 5k). All 4821 * I wanted was their core checksum alg (which is supposed 4822 * to do really well). The v2/v3 hash alg didn't work well 4823 * at all for v4 stuff -- it produced too many collisions. 4824 * 4825 * The copyright info from uts/common/io/ppp/spppcomp/zlib.[ch] 4826 * is included below. 4827 */ 4828 4829 /* -----zlib.c copyright info below */ 4830 /* 4831 * Copyright 2000 Sun Microsystems, Inc. 4832 * All rights reserved. 4833 * 4834 * Updated from zlib-1.0.4 to zlib-1.1.3 by James Carlson. 4835 * 4836 * This file is derived from various .h and .c files from the zlib-1.0.4 4837 * distribution by Jean-loup Gailly and Mark Adler, with some additions 4838 * by Paul Mackerras to aid in implementing Deflate compression and 4839 * decompression for PPP packets. See zlib.h for conditions of 4840 * distribution and use. 4841 * 4842 * Changes that have been made include: 4843 * - added Z_PACKET_FLUSH (see zlib.h for details) 4844 * - added inflateIncomp and deflateOutputPending 4845 * - allow strm->next_out to be NULL, meaning discard the output 4846 * 4847 * $Id: zlib.c,v 1.11 1998/09/13 23:37:12 paulus Exp $ 4848 */ 4849 /* +++ adler32.c */ 4850 /* 4851 * adler32.c -- compute the Adler-32 checksum of a data stream 4852 * Copyright (C) 1995-1998 Mark Adler 4853 * For conditions of distribution and use, see copyright notice in zlib.h 4854 */ 4855 /* From: adler32.c,v 1.10 1996/05/22 11:52:18 me Exp $ */ 4856 /* -----zlib.c copyright info above */ 4857 4858 /* -----zlib.h copyright info below */ 4859 /* 4860 * Copyright 2000 Sun Microsystems, Inc. 4861 * All rights reserved. 4862 * 4863 * Permission to use, copy, modify, and distribute this software and 4864 * its documentation is hereby granted, provided that the above 4865 * copyright notice appears in all copies. 4866 * 4867 * SUN MAKES NO REPRESENTATION OR WARRANTIES ABOUT THE SUITABILITY OF 4868 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 4869 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 4870 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE 4871 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, 4872 * MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES 4873 * 4874 * This file has been altered from its original by Sun Microsystems to 4875 * fit local coding style. 4876 */ 4877 /* -----zlib.h copyright info above */ 4878 4879 #define DO1(buf, i) {s1 += buf[i]; s2 += s1; } 4880 #define DO2(buf, i) DO1(buf, i); DO1(buf, i+1); 4881 #define DO4(buf, i) DO2(buf, i); DO2(buf, i+2); 4882 #define DO8(buf, i) DO4(buf, i); DO4(buf, i+4); 4883 #define DO16(buf) DO8(buf, 0); DO8(buf, 8); 4884 4885 static uint32_t 4886 adler16(void *p, int len) 4887 { 4888 uint32_t s1 = 1; 4889 uint32_t s2 = 0; 4890 uchar_t *buf = p; 4891 4892 while (len >= 16) { 4893 DO16(buf); 4894 buf += 16; 4895 len -= 16; 4896 } 4897 4898 while (len > 0) { 4899 s1 += *buf++; 4900 s2 += s1; 4901 len--; 4902 } 4903 4904 return ((uint32_t)(s2 ^ s1) & 0xFFFFU); 4905 } 4906