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