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