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