Home | History | Annotate | Download | only in snoop
      1  0  stevel /*
      2  0  stevel  * CDDL HEADER START
      3  0  stevel  *
      4  0  stevel  * The contents of this file are subject to the terms of the
      5  0  stevel  * Common Development and Distribution License, Version 1.0 only
      6  0  stevel  * (the "License").  You may not use this file except in compliance
      7  0  stevel  * with the License.
      8  0  stevel  *
      9  0  stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  0  stevel  * or http://www.opensolaris.org/os/licensing.
     11  0  stevel  * See the License for the specific language governing permissions
     12  0  stevel  * and limitations under the License.
     13  0  stevel  *
     14  0  stevel  * When distributing Covered Code, include this CDDL HEADER in each
     15  0  stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  0  stevel  * If applicable, add the following below this CDDL HEADER, with the
     17  0  stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     18  0  stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  0  stevel  *
     20  0  stevel  * CDDL HEADER END
     21  0  stevel  */
     22  0  stevel /*
     23  0  stevel  * Copyright (c) 1991, 1999, 2001 by Sun Microsystems, Inc.
     24  0  stevel  * All rights reserved.
     25  0  stevel  */
     26  0  stevel 
     27  0  stevel #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28  0  stevel 
     29  0  stevel #include <ctype.h>
     30  0  stevel #include <sys/types.h>
     31  0  stevel #include <sys/errno.h>
     32  0  stevel #include <setjmp.h>
     33  0  stevel #include <string.h>
     34  0  stevel 
     35  0  stevel #include <netinet/in.h>
     36  0  stevel #include <rpc/types.h>
     37  0  stevel #include <rpc/rpc.h>
     38  0  stevel #include <rpc/xdr.h>
     39  0  stevel #include <rpc/auth.h>
     40  0  stevel #include <rpc/clnt.h>
     41  0  stevel #include <rpc/rpc_msg.h>
     42  0  stevel #include <rpcsvc/nis.h>
     43  0  stevel #include <rpcsvc/nis_callback.h>
     44  0  stevel 
     45  0  stevel #include "snoop.h"
     46  0  stevel #include "nis_clnt.h"
     47  0  stevel 
     48  0  stevel extern char *dlc_header;
     49  0  stevel extern jmp_buf xdr_err;
     50  0  stevel 
     51  0  stevel /*
     52  0  stevel  * Number of spaces for each level of indentation.  Since this value is
     53  0  stevel  *   assumed in most of the strings below, defining it is pretty quixotic.
     54  0  stevel  */
     55  0  stevel #define	INDENT_SPACES	4
     56  0  stevel 
     57  0  stevel /*
     58  0  stevel  * ==== Old (pre Sep '91) format for public keys in NIS+ directories, now
     59  0  stevel  *	removed from the header files.  Should be removed from snoop once
     60  0  stevel  *	we're sure we won't see old-style packets
     61  0  stevel  */
     62  0  stevel #ifndef SZ_PKEY
     63  0  stevel #define	SZ_PKEY 64
     64  0  stevel #endif /* SZ_PKEY */
     65  0  stevel 
     66  0  stevel /*
     67  0  stevel  * ==== New (Aug '91) NIS+ remote procedure, which hasn't made into our
     68  0  stevel  *	header files yet.  When it does, nuke this stuff.
     69  0  stevel  */
     70  0  stevel #ifndef	NIS_UPDKEYS
     71  0  stevel #define	NIS_UPDKEYS	24
     72  0  stevel #endif	/* NIS_UPDKEYS */
     73  0  stevel 
     74  0  stevel /*
     75  0  stevel  * ==== Constants for public keys.  We should use NIS_MAXKEYLEN and the
     76  0  stevel  *	key-type constants from the NIS+ header files, but at present (Aug '91)
     77  0  stevel  *	we're ahead of the header files.
     78  0  stevel  */
     79  0  stevel #define	KEYLEN_FIRST	0
     80  0  stevel #define	KEYLEN_LIMIT	1024
     81  0  stevel #define	KEYTYPE_FIRST	0
     82  0  stevel #define	KEYTYPE_LIMIT	3
     83  0  stevel 
     84  0  stevel 
     85  0  stevel static char *procnames_short[] = {
     86  0  stevel 	"Null",		/*  0 */
     87  0  stevel 	"Lookup",	/*  1 */
     88  0  stevel 	"Add",		/*  2 */
     89  0  stevel 	"Modify",	/*  3 */
     90  0  stevel 	"Remove",	/*  4 */
     91  0  stevel 	"IBlist",	/*  5 */
     92  0  stevel 	"IBadd",	/*  6 */
     93  0  stevel 	"IBmodify",	/*  7 */
     94  0  stevel 	"IBremove",	/*  8 */
     95  0  stevel 	"IBfirst",	/*  9 */
     96  0  stevel 	"IBnext",	/*  10 */
     97  0  stevel 	"** Unused 11",	/*  11 */
     98  0  stevel 	"FindDir",	/*  12 */
     99  0  stevel 	"** Unused 13",	/*  13 */
    100  0  stevel 	"Status",	/*  14 */
    101  0  stevel 	"DumpLog",	/*  15 */
    102  0  stevel 	"Dump",		/*  16 */
    103  0  stevel 	"Callback",	/*  17 */
    104  0  stevel 	"CheckpointTime",	/*  18 */
    105  0  stevel 	"Checkpoint",	/*  19 */
    106  0  stevel 	"Ping",		/*  20 */
    107  0  stevel 	"ServerState",	/*  21 */
    108  0  stevel 	"MakeDir",	/*  22 */
    109  0  stevel 	"RemoveDir",	/*  23 */
    110  0  stevel 	"UpdateKeys",	/*  24 */
    111  0  stevel };
    112  0  stevel 
    113  0  stevel static char *procnames_long[] = {
    114  0  stevel 	"Null procedure",		/*  0 */
    115  0  stevel 	"Lookup",			/*  1 */
    116  0  stevel 	"Add",				/*  2 */
    117  0  stevel 	"Modify",			/*  3 */
    118  0  stevel 	"Remove",			/*  4 */
    119  0  stevel 	"List IBase",			/*  5 */
    120  0  stevel 	"Add to IBase",			/*  6 */
    121  0  stevel 	"Modify IBase",			/*  7 */
    122  0  stevel 	"Remove from IBase",		/*  8 */
    123  0  stevel 	"IBase First Entry",		/*  9 */
    124  0  stevel 	"IBase Next Entry",		/*  10 */
    125  0  stevel 	"** 11 (Unused) **",		/*  11 */
    126  0  stevel 	"Find Directory",		/*  12 */
    127  0  stevel 	"** 13 (Unused) **",		/*  13 */
    128  0  stevel 	"Get/Reset Statistics",		/*  14 */
    129  0  stevel 	"Dump Directory Log",		/*  15 */
    130  0  stevel 	"Dump Directory Contents",	/*  16 */
    131  0  stevel 	"Check Callback Thread",	/*  17 */
    132  0  stevel 	"Get Checkpoint Time",		/*  18 */
    133  0  stevel 	"Establish Checkpoint",		/*  19 */
    134  0  stevel 	"Ping Replicas",		/*  20 */
    135  0  stevel 	"Change Server State",		/*  21 */
    136  0  stevel 	"Make Directory",		/*  22 */
    137  0  stevel 	"Remove Directory",		/*  23 */
    138  0  stevel 	"Update Public Keys",		/*  24 */
    139  0  stevel };
    140  0  stevel 
    141  0  stevel #define	MAXPROC	24
    142  0  stevel 
    143  0  stevel static void detail_bool(void);
    144  0  stevel static void detail_callback(void);
    145  0  stevel static void detail_cback_data(void);
    146  0  stevel static void detail_cookie(void);
    147  0  stevel static void detail_cp_result(void);
    148  0  stevel static void detail_cptime(void);
    149  0  stevel static void detail_dump_args(void);
    150  0  stevel static void detail_ib_request(void);
    151  0  stevel static void detail_fd_args(void);
    152  0  stevel static void detail_fd_result(void);
    153  0  stevel static void detail_log_entry(void);
    154  0  stevel static void detail_log_result(void);
    155  0  stevel static void detail_nis_attrs(int);
    156  0  stevel static void detail_nis_error(void);
    157  0  stevel static void detail_nis_name(void);
    158  0  stevel static void detail_nis_result(void);
    159  0  stevel static void detail_nis_taglist(void);
    160  0  stevel static void detail_ns_request(void);
    161  0  stevel static void detail_ping_args(void);
    162  0  stevel static int is_printable(char *, unsigned int);
    163  0  stevel static void sum_bool(char *);
    164  0  stevel static void sum_callback(char *);
    165  0  stevel static void sum_cback_data(char *);
    166  0  stevel static void sum_cp_result(char *);
    167  0  stevel static void sum_cptime(char *);
    168  0  stevel static void sum_dump_args(char *);
    169  0  stevel static void sum_ib_request(char *);
    170  0  stevel static void sum_fd_args(char *);
    171  0  stevel static void sum_fd_result(char *);
    172  0  stevel static void sum_log_result(char *);
    173  0  stevel static void sum_nis_error(char *);
    174  0  stevel static void sum_nis_name(char *);
    175  0  stevel static void sum_nis_result(char *);
    176  0  stevel static void sum_nis_taglist(char *);
    177  0  stevel static void sum_ns_request(char *);
    178  0  stevel static void sum_ping_args(char *);
    179  0  stevel 
    180  0  stevel void
    181  0  stevel interpret_nisplus(flags, type, xid, vers, proc, data, len)
    182  0  stevel 	int flags, type, xid, vers, proc;
    183  0  stevel 	char *data;
    184  0  stevel 	int len;
    185  0  stevel {
    186  0  stevel 	char *line;
    187  0  stevel 
    188  0  stevel 	if (proc < 0 || proc > MAXPROC)
    189  0  stevel 		return;
    190  0  stevel 
    191  0  stevel 	if (flags & F_SUM) {
    192  0  stevel 		if (setjmp(xdr_err)) {
    193  0  stevel 			return;
    194  0  stevel 		}
    195  0  stevel 
    196  0  stevel 		line = get_sum_line();
    197  0  stevel 
    198  0  stevel 		if (type == CALL) {
    199  0  stevel 			(void) sprintf(line,
    200  0  stevel 				"NIS+ C %s",
    201  0  stevel 				procnames_short[proc]);
    202  0  stevel 			line += strlen(line);
    203  0  stevel 
    204  0  stevel 			switch (proc) {
    205  0  stevel 			case NIS_LOOKUP:
    206  0  stevel 			case NIS_ADD:
    207  0  stevel 			case NIS_MODIFY:
    208  0  stevel 			case NIS_REMOVE:
    209  0  stevel 				sum_ns_request(line);
    210  0  stevel 				break;
    211  0  stevel 			case NIS_IBLIST:
    212  0  stevel 			case NIS_IBADD:
    213  0  stevel 			case NIS_IBMODIFY:
    214  0  stevel 			case NIS_IBREMOVE:
    215  0  stevel 			case NIS_IBFIRST:
    216  0  stevel 			case NIS_IBNEXT:
    217  0  stevel 				sum_ib_request(line);
    218  0  stevel 				break;
    219  0  stevel 			case NIS_FINDDIRECTORY:
    220  0  stevel 				sum_fd_args(line);
    221  0  stevel 				break;
    222  0  stevel 			case NIS_STATUS:
    223  0  stevel 			case NIS_SERVSTATE:
    224  0  stevel 				sum_nis_taglist(line);
    225  0  stevel 				break;
    226  0  stevel 			case NIS_DUMPLOG:
    227  0  stevel 			case NIS_DUMP:
    228  0  stevel 				sum_dump_args(line);
    229  0  stevel 				break;
    230  0  stevel 			case NIS_CALLBACK:
    231  0  stevel 				sum_callback(line);
    232  0  stevel 				break;
    233  0  stevel 			case NIS_PING:
    234  0  stevel 				sum_ping_args(line);
    235  0  stevel 				break;
    236  0  stevel 			case NIS_CPTIME:
    237  0  stevel 			case NIS_CHECKPOINT:
    238  0  stevel 			case NIS_MKDIR:
    239  0  stevel 			case NIS_RMDIR:
    240  0  stevel 			case NIS_UPDKEYS:
    241  0  stevel 				sum_nis_name(line);
    242  0  stevel 				break;
    243  0  stevel 			default:
    244  0  stevel 				/* === mutter about bogus procnums? */
    245  0  stevel 				break;
    246  0  stevel 			}
    247  0  stevel 
    248  0  stevel 			check_retransmit(line, xid);
    249  0  stevel 		} else {
    250  0  stevel 			(void) sprintf(line, "NIS+ R %s ",
    251  0  stevel 				procnames_short[proc]);
    252  0  stevel 			line += strlen(line);
    253  0  stevel 			switch (proc) {
    254  0  stevel 			case NIS_LOOKUP:
    255  0  stevel 			case NIS_ADD:
    256  0  stevel 			case NIS_MODIFY:
    257  0  stevel 			case NIS_REMOVE:
    258  0  stevel 			case NIS_IBLIST:
    259  0  stevel 			case NIS_IBADD:
    260  0  stevel 			case NIS_IBMODIFY:
    261  0  stevel 			case NIS_IBREMOVE:
    262  0  stevel 			case NIS_IBFIRST:
    263  0  stevel 			case NIS_IBNEXT:
    264  0  stevel 				sum_nis_result(line);
    265  0  stevel 				break;
    266  0  stevel 			case NIS_FINDDIRECTORY:
    267  0  stevel 				sum_fd_result(line);
    268  0  stevel 				break;
    269  0  stevel 			case NIS_STATUS:
    270  0  stevel 			case NIS_SERVSTATE:
    271  0  stevel 				sum_nis_taglist(line);
    272  0  stevel 				break;
    273  0  stevel 			case NIS_DUMPLOG:
    274  0  stevel 			case NIS_DUMP:
    275  0  stevel 				sum_log_result(line);
    276  0  stevel 				break;
    277  0  stevel 			case NIS_CALLBACK:
    278  0  stevel 				sum_bool(line);
    279  0  stevel 				break;
    280  0  stevel 			case NIS_CPTIME:
    281  0  stevel 				sum_cptime(line);
    282  0  stevel 				break;
    283  0  stevel 			case NIS_CHECKPOINT:
    284  0  stevel 				sum_cp_result(line);
    285  0  stevel 				break;
    286  0  stevel 			case NIS_PING:
    287  0  stevel 				break;
    288  0  stevel 			case NIS_MKDIR:
    289  0  stevel 			case NIS_RMDIR:
    290  0  stevel 			case NIS_UPDKEYS:
    291  0  stevel 				sum_nis_error(line);
    292  0  stevel 				break;
    293  0  stevel 			default:
    294  0  stevel 				/* === mutter about bogus procnums? */
    295  0  stevel 				break;
    296  0  stevel 			}
    297  0  stevel 		}
    298  0  stevel 	}
    299  0  stevel 
    300  0  stevel 	if (flags & F_DTAIL) {
    301  0  stevel 		show_header("NIS+:  ", "NIS+ Name Service", len);
    302  0  stevel 		show_space();
    303  0  stevel 		if (setjmp(xdr_err)) {
    304  0  stevel 			return;
    305  0  stevel 		}
    306  0  stevel 		(void) sprintf(get_line(0, 0),
    307  0  stevel 			"Proc = %d (%s)",
    308  0  stevel 			proc, procnames_long[proc]);
    309  0  stevel 
    310  0  stevel 		if (type == CALL) {
    311  0  stevel 			switch (proc) {
    312  0  stevel 			case NIS_LOOKUP:
    313  0  stevel 			case NIS_ADD:
    314  0  stevel 			case NIS_MODIFY:
    315  0  stevel 			case NIS_REMOVE:
    316  0  stevel 				detail_ns_request();
    317  0  stevel 				break;
    318  0  stevel 			case NIS_IBLIST:
    319  0  stevel 			case NIS_IBADD:
    320  0  stevel 			case NIS_IBMODIFY:
    321  0  stevel 			case NIS_IBREMOVE:
    322  0  stevel 			case NIS_IBFIRST:
    323  0  stevel 			case NIS_IBNEXT:
    324  0  stevel 				detail_ib_request();
    325  0  stevel 				break;
    326  0  stevel 			case NIS_FINDDIRECTORY:
    327  0  stevel 				detail_fd_args();
    328  0  stevel 				break;
    329  0  stevel 			case NIS_STATUS:
    330  0  stevel 			case NIS_SERVSTATE:
    331  0  stevel 				detail_nis_taglist();
    332  0  stevel 				break;
    333  0  stevel 			case NIS_DUMPLOG:
    334  0  stevel 			case NIS_DUMP:
    335  0  stevel 				detail_dump_args();
    336  0  stevel 				break;
    337  0  stevel 			case NIS_CALLBACK:
    338  0  stevel 				detail_callback();
    339  0  stevel 				break;
    340  0  stevel 			case NIS_PING:
    341  0  stevel 				detail_ping_args();
    342  0  stevel 				break;
    343  0  stevel 			case NIS_CPTIME:
    344  0  stevel 			case NIS_CHECKPOINT:
    345  0  stevel 			case NIS_MKDIR:
    346  0  stevel 			case NIS_RMDIR:
    347  0  stevel 			case NIS_UPDKEYS:
    348  0  stevel 				detail_nis_name();
    349  0  stevel 				break;
    350  0  stevel 			default:
    351  0  stevel 				/* === mutter about bogus procnums? */
    352  0  stevel 				break;
    353  0  stevel 			}
    354  0  stevel 		} else {
    355  0  stevel 			switch (proc) {
    356  0  stevel 			case NIS_LOOKUP:
    357  0  stevel 			case NIS_ADD:
    358  0  stevel 			case NIS_MODIFY:
    359  0  stevel 			case NIS_REMOVE:
    360  0  stevel 			case NIS_IBLIST:
    361  0  stevel 			case NIS_IBADD:
    362  0  stevel 			case NIS_IBMODIFY:
    363  0  stevel 			case NIS_IBREMOVE:
    364  0  stevel 			case NIS_IBFIRST:
    365  0  stevel 			case NIS_IBNEXT:
    366  0  stevel 				detail_nis_result();
    367  0  stevel 				break;
    368  0  stevel 			case NIS_FINDDIRECTORY:
    369  0  stevel 				detail_fd_result();
    370  0  stevel 				break;
    371  0  stevel 			case NIS_STATUS:
    372  0  stevel 			case NIS_SERVSTATE:
    373  0  stevel 				detail_nis_taglist();
    374  0  stevel 				break;
    375  0  stevel 			case NIS_DUMPLOG:
    376  0  stevel 			case NIS_DUMP:
    377  0  stevel 				detail_log_result();
    378  0  stevel 				break;
    379  0  stevel 			case NIS_CALLBACK:
    380  0  stevel 				detail_bool();
    381  0  stevel 				break;
    382  0  stevel 			case NIS_CPTIME:
    383  0  stevel 				detail_cptime();
    384  0  stevel 				break;
    385  0  stevel 			case NIS_CHECKPOINT:
    386  0  stevel 				detail_cp_result();
    387  0  stevel 				break;
    388  0  stevel 			case NIS_PING:
    389  0  stevel 				break;
    390  0  stevel 			case NIS_MKDIR:
    391  0  stevel 			case NIS_RMDIR:
    392  0  stevel 			case NIS_UPDKEYS:
    393  0  stevel 				detail_nis_error();
    394  0  stevel 				break;
    395  0  stevel 			default:
    396  0  stevel 				/* === mutter about bogus procnums? */
    397  0  stevel 				break;
    398  0  stevel 			}
    399  0  stevel 		}
    400  0  stevel 
    401  0  stevel 		show_trailer();
    402  0  stevel 	}
    403  0  stevel }
    404  0  stevel 
    405  0  stevel static char *cbnames_short[] = {
    406  0  stevel 	"Null",		/*  0 */
    407  0  stevel 	"Receive",	/*  1 */
    408  0  stevel 	"Finish",	/*  2 */
    409  0  stevel 	"Error",	/*  3 */
    410  0  stevel };
    411  0  stevel 
    412  0  stevel static char *cbnames_long[] = {
    413  0  stevel 	"Null procedure",		/*  0 */
    414  0  stevel 	"Receive Callback Data",	/*  1 */
    415  0  stevel 	"Finish Callback",		/*  2 */
    416  0  stevel 	"Callback Error",		/*  3 */
    417  0  stevel };
    418  0  stevel 
    419  0  stevel void
    420  0  stevel interpret_nisp_cb(flags, type, xid, vers, proc, data, len)
    421  0  stevel 	int flags, type, xid, vers, proc;
    422  0  stevel 	char *data;
    423  0  stevel 	int len;
    424  0  stevel {
    425  0  stevel 	char *line;
    426  0  stevel 
    427  0  stevel 	if (flags & F_SUM) {
    428  0  stevel 		if (setjmp(xdr_err)) {
    429  0  stevel 			return;
    430  0  stevel 		}
    431  0  stevel 
    432  0  stevel 		line = get_sum_line();
    433  0  stevel 
    434  0  stevel 		if (type == CALL) {
    435  0  stevel 			(void) sprintf(line,
    436  0  stevel 				"NIS+ Callback C %s",
    437  0  stevel 				cbnames_short[proc]);
    438  0  stevel 			line += strlen(line);
    439  0  stevel 
    440  0  stevel 			switch (proc) {
    441  0  stevel 			    case CBPROC_RECEIVE:
    442  0  stevel 				sum_cback_data(line);
    443  0  stevel 				break;
    444  0  stevel 			    case CBPROC_FINISH:
    445  0  stevel 				/* void: nothing to do */
    446  0  stevel 				break;
    447  0  stevel 			    case CBPROC_ERROR:
    448  0  stevel 				sum_nis_error(line);
    449  0  stevel 				break;
    450  0  stevel 			    default:
    451  0  stevel 				/* === mutter about bogus procnums? */
    452  0  stevel 				break;
    453  0  stevel 			}
    454  0  stevel 
    455  0  stevel 			check_retransmit(line, xid);
    456  0  stevel 		} else {
    457  0  stevel 			(void) sprintf(line, "NIS+ Callback R %s ",
    458  0  stevel 				cbnames_short[proc]);
    459  0  stevel 			line += strlen(line);
    460  0  stevel 			switch (proc) {
    461  0  stevel 			    case CBPROC_RECEIVE:
    462  0  stevel 				sum_bool(line);
    463  0  stevel 				break;
    464  0  stevel 			    case CBPROC_FINISH:
    465  0  stevel 			    case CBPROC_ERROR:
    466  0  stevel 				/* void: nothing to do */
    467  0  stevel 				break;
    468  0  stevel 			    default:
    469  0  stevel 				/* === mutter about bogus procnums? */
    470  0  stevel 				break;
    471  0  stevel 			}
    472  0  stevel 		}
    473  0  stevel 	}
    474  0  stevel 
    475  0  stevel 	if (flags & F_DTAIL) {
    476  0  stevel 		show_header("NIS+ CB:  ", "NIS+ Name Service Callback", len);
    477  0  stevel 		show_space();
    478  0  stevel 		if (setjmp(xdr_err)) {
    479  0  stevel 			return;
    480  0  stevel 		}
    481  0  stevel 		(void) sprintf(get_line(0, 0),
    482  0  stevel 			"Proc = %d (%s)",
    483  0  stevel 			proc, cbnames_long[proc]);
    484  0  stevel 
    485  0  stevel 		if (type == CALL) {
    486  0  stevel 			switch (proc) {
    487  0  stevel 			    case CBPROC_RECEIVE:
    488  0  stevel 				detail_cback_data();
    489  0  stevel 				break;
    490  0  stevel 			    case CBPROC_FINISH:
    491  0  stevel 				/* void: nothing to do */
    492  0  stevel 				break;
    493  0  stevel 			    case CBPROC_ERROR:
    494  0  stevel 				detail_nis_error();
    495  0  stevel 				break;
    496  0  stevel 			    default:
    497  0  stevel 				/* === mutter about bogus procnums? */
    498  0  stevel 				break;
    499  0  stevel 			}
    500  0  stevel 		} else {
    501  0  stevel 			switch (proc) {
    502  0  stevel 			    case CBPROC_RECEIVE:
    503  0  stevel 				detail_bool();
    504  0  stevel 				break;
    505  0  stevel 			    case CBPROC_FINISH:
    506  0  stevel 			    case CBPROC_ERROR:
    507  0  stevel 				/* void: nothing to do */
    508  0  stevel 				break;
    509  0  stevel 			    default:
    510  0  stevel 				/* === mutter about bogus procnums? */
    511  0  stevel 				break;
    512  0  stevel 			}
    513  0  stevel 		}
    514  0  stevel 
    515  0  stevel 		show_trailer();
    516  0  stevel 	}
    517  0  stevel }
    518  0  stevel 
    519  0  stevel /*
    520  0  stevel  * stringof_XXX() routines -- return printable representations of various
    521  0  stevel  *	numeric values.  Would be nice if we could get this from the NIS+
    522  0  stevel  *	library instead of reinventing them.
    523  0  stevel  * N.B.  Mucho use of pointer-to-static result types (ugh); don't expect the
    524  0  stevel  *	return value to stay good for long.
    525  0  stevel  */
    526  0  stevel 
    527  0  stevel #ifndef RIGHTS_FORMAT
    528  0  stevel #define	RIGHTS_FORMAT	1
    529  0  stevel #endif	/* RIGHTS_FORMAT */
    530  0  stevel 
    531  0  stevel static struct {
    532  0  stevel 	int shift;
    533  0  stevel 	char *name;
    534  0  stevel } rightsclasses[] = {
    535  0  stevel #if	RIGHTS_FORMAT == 1
    536  0  stevel 	24,	"",
    537  0  stevel 	16,	"",
    538  0  stevel 	8,	"",
    539  0  stevel 	0,	"",
    540  0  stevel #elif	RIGHTS_FORMAT == 2
    541  0  stevel 	16,	"o:",
    542  0  stevel 	8,	"g:",
    543  0  stevel 	0,	"w:",
    544  0  stevel 	24,	"u:",
    545  0  stevel #else	/* RIGHTS_FORMAT == 3 */
    546  0  stevel 	16,	"owner:",
    547  0  stevel 	8,	"group:",
    548  0  stevel 	0,	"world:",
    549  0  stevel 	24,	"unauth:",
    550  0  stevel #endif	/* RIGHTS_FORMAT */
    551  0  stevel };
    552  0  stevel 
    553  0  stevel char *
    554  0  stevel stringof_rights(rights)
    555  0  stevel 	unsigned rights;
    556  0  stevel {
    557  0  stevel 	static char rightsbuf[100];
    558  0  stevel 	char *p;
    559  0  stevel 	int i;
    560  0  stevel 
    561  0  stevel 	sprintf(rightsbuf, "%08x (", rights);
    562  0  stevel 	p = rightsbuf + strlen(rightsbuf);
    563  0  stevel 
    564  0  stevel 	for (i = 0; i < 4; i++) {
    565  0  stevel 		int shift = rightsclasses[i].shift;
    566  0  stevel 		strcpy(p, rightsclasses[i].name);
    567  0  stevel 		p += strlen(p);
    568  0  stevel 		*p++ = (rights >> shift) & NIS_READ_ACC    ? 'r' : '-';
    569  0  stevel 		*p++ = (rights >> shift) & NIS_MODIFY_ACC  ? 'm' : '-';
    570  0  stevel 		*p++ = (rights >> shift) & NIS_CREATE_ACC  ? 'c' : '-';
    571  0  stevel 		*p++ = (rights >> shift) & NIS_DESTROY_ACC ? 'd' : '-';
    572  0  stevel 		*p++ = ' ';
    573  0  stevel 		rights &= ~((NIS_READ_ACC   | NIS_MODIFY_ACC  |
    574  0  stevel 				NIS_CREATE_ACC | NIS_DESTROY_ACC) << shift);
    575  0  stevel 	}
    576  0  stevel 	if (rights == 0) {
    577  0  stevel 		p[-1] = ')';		/* Nuke that last space */
    578  0  stevel 		p[ 0] = 0;
    579  0  stevel 	} else {
    580  0  stevel 		sprintf(p, "+ Unknown bits: %08x **)", rights);
    581  0  stevel 	}
    582  0  stevel 	return (rightsbuf);
    583  0  stevel }
    584  0  stevel 
    585  0  stevel char *
    586  0  stevel stringof_ib_flags(flags)
    587  0  stevel 	unsigned flags;
    588  0  stevel {
    589  0  stevel 	static char flagsbuf[120];
    590  0  stevel 
    591  0  stevel 	if (flags == 0) {
    592  0  stevel 		sprintf(flagsbuf, "%08x", flags);
    593  0  stevel 		return (flagsbuf);
    594  0  stevel 	}
    595  0  stevel 	sprintf(flagsbuf,
    596  0  stevel 		"%08x (%s%s%s%s",
    597  0  stevel 		flags,
    598  0  stevel 		flags & MOD_SAMEOBJ		? "MOD_SAMEOBJ, "	: "",
    599  0  stevel 		flags & REM_MULTIPLE		? "REM_MULTIPLE, "	: "",
    600  0  stevel 		flags & ADD_OVERWRITE		? "ADD_OVERWRITE, "	: "",
    601  0  stevel 		flags & RETURN_RESULT		? "RETURN_RESULT, "	: "");
    602  0  stevel 	flags &= ~(MOD_SAMEOBJ | REM_MULTIPLE | ADD_OVERWRITE | RETURN_RESULT);
    603  0  stevel 	if (flags != 0) {
    604  0  stevel 		sprintf(flagsbuf + strlen(flagsbuf),
    605  0  stevel 			"** Unknown bits %08x **, ", flags);
    606  0  stevel 	}
    607  0  stevel 	/* Replace the trailing ", " with ")" */
    608  0  stevel 	sprintf(flagsbuf + strlen(flagsbuf) - 2, ")");
    609  0  stevel 	return (flagsbuf);
    610  0  stevel }
    611  0  stevel 
    612  0  stevel char *
    613  0  stevel stringof_colflags(flags)
    614  0  stevel 	unsigned flags;
    615  0  stevel {
    616  0  stevel 	static char flagsbuf[120];
    617  0  stevel 
    618  0  stevel 	if (flags == 0) {
    619  0  stevel 		sprintf(flagsbuf, "%08x", flags);
    620  0  stevel 		return (flagsbuf);
    621  0  stevel 	}
    622  0  stevel 	sprintf(flagsbuf,
    623  0  stevel 		"%08x (%s%s%s%s%s",
    624  0  stevel 		flags,
    625  0  stevel 		flags & TA_CASE		? "Case-insensitive, "	: "",
    626  0  stevel 		flags & TA_SEARCHABLE	? "Searchable, "	: "",
    627  0  stevel 		flags & TA_XDR		? "XDR Encoded, "	: "",
    628  0  stevel 		flags & TA_CRYPT	? "Encrypted, "		: "",
    629  0  stevel 		flags & TA_BINARY	? "Binary, " 		: "");
    630  0  stevel 	flags &= ~(TA_CASE | TA_SEARCHABLE | TA_XDR | TA_CRYPT | TA_BINARY);
    631  0  stevel 	if (flags != 0) {
    632  0  stevel 		sprintf(flagsbuf + strlen(flagsbuf),
    633  0  stevel 			"** Unknown bits %08x **, ", flags);
    634  0  stevel 	}
    635  0  stevel 	/* Replace the trailing ", " with ")" */
    636  0  stevel 	sprintf(flagsbuf + strlen(flagsbuf) - 2, ")");
    637  0  stevel 	return (flagsbuf);
    638  0  stevel }
    639  0  stevel 
    640  0  stevel char *
    641  0  stevel stringof_entryflags(flags)
    642  0  stevel 	unsigned flags;
    643  0  stevel {
    644  0  stevel 	static char flagsbuf[100];
    645  0  stevel 
    646  0  stevel 	if (flags == 0) {
    647  0  stevel 		sprintf(flagsbuf, "%08x", flags);
    648  0  stevel 		return (flagsbuf);
    649  0  stevel 	}
    650  0  stevel 	sprintf(flagsbuf,
    651  0  stevel 		"%08x (%s%s%s%s",
    652  0  stevel 		flags,
    653  0  stevel 		flags & EN_MODIFIED	? "Modified, "		: "",
    654  0  stevel 		flags & EN_XDR		? "XDR Encoded, "	: "",
    655  0  stevel 		flags & EN_CRYPT	? "Encrypted, "		: "",
    656  0  stevel 		flags & EN_BINARY	? "Binary, " 		: "");
    657  0  stevel 	flags &= ~(EN_MODIFIED | EN_XDR | EN_CRYPT | EN_BINARY);
    658  0  stevel 	if (flags != 0) {
    659  0  stevel 		sprintf(flagsbuf + strlen(flagsbuf),
    660  0  stevel 			"** Unknown bits %08x **, ", flags);
    661  0  stevel 	}
    662  0  stevel 	/* Replace the trailing ", " with ")" */
    663  0  stevel 	sprintf(flagsbuf + strlen(flagsbuf) - 2, ")");
    664  0  stevel 	return (flagsbuf);
    665  0  stevel }
    666  0  stevel 
    667  0  stevel char *
    668  0  stevel stringof_groupflags(flags)
    669  0  stevel 	unsigned flags;
    670  0  stevel {
    671  0  stevel 	static char flagsbuf[80];
    672  0  stevel 
    673  0  stevel 	if (flags == 0) {
    674  0  stevel 		sprintf(flagsbuf, "%08x", flags);
    675  0  stevel 		return (flagsbuf);
    676  0  stevel 	}
    677  0  stevel 	sprintf(flagsbuf,
    678  0  stevel 		"%08x (%s%s%s",
    679  0  stevel 		flags,
    680  0  stevel 		flags & NEGMEM_GROUPS	? "Negative, "		: "",
    681  0  stevel 		flags & RECURS_GROUPS	? "Recursive, "		: "",
    682  0  stevel 		flags & IMPMEM_GROUPS	? "Implicit, "		: "");
    683  0  stevel 	flags &= ~(NEGMEM_GROUPS | RECURS_GROUPS | IMPMEM_GROUPS);
    684  0  stevel 	if (flags != 0) {
    685  0  stevel 		sprintf(flagsbuf + strlen(flagsbuf),
    686  0  stevel 			"** Unknown bits %08x **, ", flags);
    687  0  stevel 	}
    688  0  stevel 	/* Replace the trailing ", " with ")" */
    689  0  stevel 	sprintf(flagsbuf + strlen(flagsbuf) - 2, ")");
    690  0  stevel 	return (flagsbuf);
    691  0  stevel }
    692  0  stevel 
    693  0  stevel char *
    694  0  stevel stringof_tag(ttype)
    695  0  stevel 	int ttype;
    696  0  stevel {
    697  0  stevel 	switch (ttype) {
    698  0  stevel 	    case TAG_DEBUG:	return ("DEBUG");
    699  0  stevel 	    case TAG_STATS:	return ("STATS");
    700  0  stevel 	    case TAG_GCACHE:	return ("GCACHE");
    701  0  stevel 	    case TAG_DCACHE:	return ("DCACHE");
    702  0  stevel 	    case TAG_OCACHE:	return ("OCACHE");
    703  0  stevel 	    case TAG_SECURE:	return ("SECURE");
    704  0  stevel 
    705  0  stevel #ifdef undef
    706  0  stevel /*
    707  0  stevel  * Old tags, removed September '91 (some of the tag-numbers have been
    708  0  stevel  *   reassigned, just to make things completely confusing).
    709  0  stevel  */
    710  0  stevel 	    case TAG_LOOKUPS:	return ("LOOKUPS";
    711  0  stevel 	    case TAG_S_LOOKUPS:	return ("S_LOOKUPS";
    712  0  stevel 	    case TAG_U_LOOKUPS:	return ("U_LOOKUPS";
    713  0  stevel #endif /* undef */
    714  0  stevel 	    case TAG_OPSTATS:	return ("OPSTATS");
    715  0  stevel 	    case TAG_THREADS:	return ("THREADS");
    716  0  stevel 	    case TAG_UPDATES:	return ("UPDATES");
    717  0  stevel 	    case TAG_VISIBLE:	return ("VISIBLE");
    718  0  stevel 	    case TAG_S_DCACHE:	return ("S_DCACHE");
    719  0  stevel 	    case TAG_S_OCACHE:	return ("S_OCACHE");
    720  0  stevel 	    case TAG_S_GCACHE:	return ("S_GCACHE");
    721  0  stevel 	    case TAG_S_STORAGE:	return ("S_STORAGE");
    722  0  stevel 
    723  0  stevel 	    default:		return ("*Unknown*");
    724  0  stevel 	}
    725  0  stevel }
    726  0  stevel 
    727  0  stevel char *
    728  0  stevel stringof_otype(otype)
    729  0  stevel 	int otype;
    730  0  stevel {
    731  0  stevel 	static char buf[30];
    732  0  stevel 
    733  0  stevel 	switch (otype) {
    734  0  stevel 	    case NIS_BOGUS_OBJ:	return ("BOGUS (uninitialized?)");
    735  0  stevel 	    case NIS_NO_OBJ:	return ("NULL");
    736  0  stevel 	    case NIS_DIRECTORY_OBJ:	return ("DIRECTORY");
    737  0  stevel 	    case NIS_GROUP_OBJ:	return ("GROUP");
    738  0  stevel 	    case NIS_TABLE_OBJ:	return ("TABLE");
    739  0  stevel 	    case NIS_ENTRY_OBJ:	return ("ENTRY");
    740  0  stevel 	    case NIS_LINK_OBJ:	return ("LINK");
    741  0  stevel 	    case NIS_PRIVATE_OBJ:	return ("PRIVATE");
    742  0  stevel 	    default:		sprintf(buf, "** Unknown (%d) **", otype);
    743  0  stevel 				return (buf);
    744  0  stevel 	}
    745  0  stevel }
    746  0  stevel 
    747  0  stevel char *
    748  0  stevel stringof_entry_t(et)
    749  0  stevel 	int et;
    750  0  stevel {
    751  0  stevel 	static char buf[30];
    752  0  stevel 
    753  0  stevel 	switch (et) {
    754  0  stevel 	    case LOG_NOP:	return ("LOG_NOP");	/* === lowercase? */
    755  0  stevel 	    case ADD_NAME:	return ("ADD_NAME");
    756  0  stevel 	    case REM_NAME:	return ("REM_NAME");
    757  0  stevel 	    case MOD_NAME_OLD:	return ("MOD_NAME_OLD");
    758  0  stevel 	    case MOD_NAME_NEW:	return ("MOD_NAME_NEW");
    759  0  stevel 	    case ADD_IBASE:	return ("ADD_IBASE");
    760  0  stevel 	    case REM_IBASE:	return ("REM_IBASE");
    761  0  stevel 	    case MOD_IBASE:	return ("MOD_IBASE");
    762  0  stevel 	    case UPD_STAMP:	return ("UPD_STAMP");
    763  0  stevel 	    default:		sprintf(buf, "** Unknown (%d) **", et);
    764  0  stevel 				return (buf);
    765  0  stevel 	}
    766  0  stevel }
    767  0  stevel 
    768  0  stevel char *
    769  0  stevel stringof_ktype(ktype)
    770  0  stevel 	unsigned ktype;
    771  0  stevel {
    772  0  stevel 	static char buf[40];
    773  0  stevel 	char *p;
    774  0  stevel 
    775  0  stevel 	sprintf(buf, "%d ", ktype);
    776  0  stevel 	p = buf + strlen(buf);
    777  0  stevel 	switch (ktype) {
    778  0  stevel 	    case 0:	strcpy(p, "(None)");		break;
    779  0  stevel 	    case 1:	strcpy(p, "(Diffie-Hellman)");	break;
    780  0  stevel 	    case 2:	strcpy(p, "(RSA)");		break;
    781  0  stevel 	    case 4:	strcpy(p, "(Diffie-Hellman Ext)"); break;
    782  0  stevel 	    default:	strcpy(p, "(** Unknown **)");	break;
    783  0  stevel 	}
    784  0  stevel 	return (buf);
    785  0  stevel }
    786  0  stevel 
    787  0  stevel static void
    788  0  stevel sumxdr_nis_name(line)
    789  0  stevel 	char *line;
    790  0  stevel {
    791  0  stevel 	char buff[NIS_MAXNAMELEN + 1];
    792  0  stevel 
    793  0  stevel 	(void) sprintf(line, " \"%s\"", getxdr_string(buff, NIS_MAXNAMELEN));
    794  0  stevel 	/* ==== ? could/should truncate long names a la showxdr_string() ? */
    795  0  stevel }
    796  0  stevel 
    797  0  stevel static unsigned
    798  0  stevel sumxdr_nis_error(line)
    799  0  stevel 	char *line;
    800  0  stevel {
    801  0  stevel 	unsigned err = getxdr_u_long();
    802  0  stevel 	sprintf(line, "[%s]", nis_sperrno(err));
    803  0  stevel 	return (err);
    804  0  stevel }
    805  0  stevel 
    806  0  stevel static void
    807  0  stevel sum_ns_request(line)
    808  0  stevel 	char *line;
    809  0  stevel {
    810  0  stevel 	sumxdr_nis_name(line);
    811  0  stevel 	/* Leave the optional object for detailed listings */
    812  0  stevel }
    813  0  stevel 
    814  0  stevel int nchars_attrval = 32;
    815  0  stevel 
    816  0  stevel static void
    817  0  stevel sum_ib_request(line)
    818  0  stevel 	char *line;
    819  0  stevel {
    820  0  stevel 	unsigned long nattrs;
    821  0  stevel 	unsigned long len;
    822  0  stevel 	int pos;
    823  0  stevel 	char *val;
    824  0  stevel 	char buff[NIS_MAXATTRNAME + 1];
    825  0  stevel 
    826  0  stevel 	sumxdr_nis_name(line);
    827  0  stevel 	line += strlen(line);
    828  0  stevel 	nattrs = getxdr_u_long();
    829  0  stevel 	switch (nattrs) {
    830  0  stevel 	    case 0:
    831  0  stevel 		/* === Could print "No attrs " */
    832  0  stevel 		break;
    833  0  stevel 	    case 1:
    834  0  stevel 		sprintf(line, " [%s = ", getxdr_string(buff, NIS_MAXATTRNAME));
    835  0  stevel 		line += strlen(line);
    836  0  stevel 		pos = getxdr_pos();
    837  0  stevel 		val = getxdr_bytes((uint_t *)&len);
    838  0  stevel 		if (is_printable(val, len)) {
    839  0  stevel 			if (len - 1 > nchars_attrval) {
    840  0  stevel 				sprintf(line, "(%d-character value)", len);
    841  0  stevel 			} else {
    842  0  stevel 				sprintf(line, "\"%s\"", val);
    843  0  stevel 			}
    844  0  stevel 		} else {
    845  0  stevel 			if ((len - 1) * 2 > nchars_attrval) {
    846  0  stevel 				sprintf(line, "(%d-byte value)", len);
    847  0  stevel 			} else {
    848  0  stevel 				/*
    849  0  stevel 				 * Too lazy to print hex ourselves; instead,
    850  0  stevel 				 *   back up and use snoop's hex-printer
    851  0  stevel 				 */
    852  0  stevel 				setxdr_pos(pos);
    853  0  stevel 				len = getxdr_u_long(); /* Yes, we did know it */
    854  0  stevel 				strcpy(line, getxdr_hex(len));
    855  0  stevel 			}
    856  0  stevel 		}
    857  0  stevel 		line += strlen(line);
    858  0  stevel 		*line++ = ']';
    859  0  stevel 		*line = 0;
    860  0  stevel 		break;
    861  0  stevel 	    default:
    862  0  stevel 		sprintf(line, " (Num attrs = %lu)", nattrs);
    863  0  stevel 		/* === Note that we haven't skipped the attrs */
    864  0  stevel 		break;
    865  0  stevel 	}
    866  0  stevel 	/* === Don't bother with flags, obj, cbhost, bufsize, cookie */
    867  0  stevel }
    868  0  stevel 
    869  0  stevel static void
    870  0  stevel sum_fd_args(line)
    871  0  stevel 	char *line;
    872  0  stevel {
    873  0  stevel 	sumxdr_nis_name(line);
    874  0  stevel #ifdef LESS_TERSE
    875  0  stevel 	strcat(line, " for");
    876  0  stevel 	sumxdr_nis_name(line + strlen(line));
    877  0  stevel #endif /* LESS_TERSE */
    878  0  stevel }
    879  0  stevel 
    880  0  stevel #define	MAXTAGLEN	1024		/* num chars of tag to display */
    881  0  stevel 
    882  0  stevel static void
    883  0  stevel sum_nis_taglist(line)
    884  0  stevel 	char *line;
    885  0  stevel {
    886  0  stevel 	char buff[MAXTAGLEN + 1];
    887  0  stevel 	unsigned ntags;
    888  0  stevel 	unsigned ttype;
    889  0  stevel 
    890  0  stevel 	ntags = getxdr_u_long();
    891  0  stevel 	if (ntags == 0) {
    892  0  stevel 		strcpy(line, " [But no tags !?]");
    893  0  stevel 		return;
    894  0  stevel 	}
    895  0  stevel 	ttype = getxdr_u_long();
    896  0  stevel 	sprintf(line,
    897  0  stevel 		" %s=\"%s\"", stringof_tag(ttype),
    898  0  stevel 		getxdr_string(buff, MAXTAGLEN));
    899  0  stevel 	if (ntags > 1) {
    900  0  stevel 		sprintf(line + strlen(line), " [and %lu more tags]", ntags - 1);
    901  0  stevel 	}
    902  0  stevel }
    903  0  stevel 
    904  0  stevel static void
    905  0  stevel sum_dump_args(line)
    906  0  stevel 	char *line;
    907  0  stevel {
    908  0  stevel 	sumxdr_nis_name(line);
    909  0  stevel 	strcat(line, " from ");
    910  0  stevel 	strcat(line, getxdr_time());
    911  0  stevel }
    912  0  stevel 
    913  0  stevel /*ARGSUSED*/
    914  0  stevel static void
    915  0  stevel sum_callback(line)	/* i.e. the netobj argument to NIS_CALLBACK */
    916  0  stevel 	char *line;
    917  0  stevel {
    918  0  stevel 	/* netobjs are pretty opaque, so don't try to summarize */
    919  0  stevel }
    920  0  stevel 
    921  0  stevel static void
    922  0  stevel sum_ping_args(line)
    923  0  stevel 	char *line;
    924  0  stevel {
    925  0  stevel 	sumxdr_nis_name(line);
    926  0  stevel 	strcat(line, " at ");
    927  0  stevel 	strcat(line, getxdr_time());
    928  0  stevel }
    929  0  stevel 
    930  0  stevel static void
    931  0  stevel sum_nis_name(line)
    932  0  stevel 	char *line;
    933  0  stevel {
    934  0  stevel 	sumxdr_nis_name(line);
    935  0  stevel }
    936  0  stevel 
    937  0  stevel static void
    938  0  stevel sum_cback_data(line)
    939  0  stevel 	char *line;
    940  0  stevel {
    941  0  stevel 	(void) sprintf(line, " (%lu entries)", getxdr_u_long());
    942  0  stevel }
    943  0  stevel 
    944  0  stevel static void
    945  0  stevel sum_nis_result(line)
    946  0  stevel 	char *line;
    947  0  stevel {
    948  0  stevel 	unsigned nobjs;
    949  0  stevel 
    950  0  stevel 	(void) sumxdr_nis_error(line);
    951  0  stevel 	nobjs = getxdr_u_long();
    952  0  stevel 	if (nobjs != 0) {
    953  0  stevel 		sprintf(line + strlen(line),
    954  0  stevel 			" and %lu object%s", nobjs, (nobjs == 1) ? "" : "s");
    955  0  stevel 	}
    956  0  stevel }
    957  0  stevel 
    958  0  stevel static void
    959  0  stevel sum_fd_result(line)
    960  0  stevel 	char *line;
    961  0  stevel {
    962  0  stevel 	(void) sumxdr_nis_error(line);
    963  0  stevel #ifdef LESS_TERSE
    964  0  stevel 	strcat(line, " from");
    965  0  stevel 	sumxdr_nis_name(line + strlen(line));
    966  0  stevel #endif /* LESS_TERSE */
    967  0  stevel }
    968  0  stevel 
    969  0  stevel static void
    970  0  stevel sum_log_result(line)
    971  0  stevel 	char *line;
    972  0  stevel {
    973  0  stevel 	uint_t dummy;
    974  0  stevel 	unsigned nents;
    975  0  stevel 
    976  0  stevel 	(void) sumxdr_nis_error(line);
    977  0  stevel 	(void) getxdr_bytes(&dummy);	/* Skip netobj lr_cookie */
    978  0  stevel 	nents = getxdr_u_long();
    979  0  stevel 	sprintf(line + strlen(line),
    980  0  stevel 		" and %lu log entr%s", nents, (nents == 1) ? "y" : "ies");
    981  0  stevel }
    982  0  stevel 
    983  0  stevel static void
    984  0  stevel sum_bool(line)
    985  0  stevel 	char *line;
    986  0  stevel {
    987  0  stevel 	(void) sprintf(line, getxdr_u_long() ? "true" : "false");
    988  0  stevel }
    989  0  stevel 
    990  0  stevel static void
    991  0  stevel sum_cptime(line)
    992  0  stevel 	char *line;
    993  0  stevel {
    994  0  stevel 	(void) sprintf(line, " %s", getxdr_time());
    995  0  stevel }
    996  0  stevel 
    997  0  stevel static void
    998  0  stevel sum_cp_result(line)
    999  0  stevel 	char *line;
   1000  0  stevel {
   1001  0  stevel 	(void) sumxdr_nis_error(line);
   1002  0  stevel }
   1003  0  stevel 
   1004  0  stevel static void
   1005  0  stevel sum_nis_error(line)
   1006  0  stevel 	char *line;
   1007  0  stevel {
   1008  0  stevel 	(void) sumxdr_nis_error(line);
   1009  0  stevel }
   1010  0  stevel 
   1011  0  stevel #define	SHOW_NIS_NAME(format)	(void) showxdr_string(NIS_MAXNAMELEN, format)
   1012  0  stevel #define	SHOW_NAME()		SHOW_NIS_NAME("Name = %s")
   1013  0  stevel 
   1014  0  stevel /*
   1015  0  stevel  * showxdr_longhex() -- ersatz wrapper around showxdr_hex() to ensure we
   1016  0  stevel  *	don't display too much on one line.  Multi-line results will
   1017  0  stevel  *  ===	probably look pretty awful, but we may at least prevent core-dumps
   1018  0  stevel  */
   1019  0  stevel int nwords_longhex = 8;
   1020  0  stevel 
   1021  0  stevel static void
   1022  0  stevel showxdr_longhex(len, fmt)
   1023  0  stevel 	int len;
   1024  0  stevel 	char *fmt;
   1025  0  stevel {
   1026  0  stevel 	int nbytes_longhex = 4 * nwords_longhex;
   1027  0  stevel 
   1028  0  stevel 	while (len > nbytes_longhex) {
   1029  0  stevel 		showxdr_hex(nbytes_longhex, fmt);
   1030  0  stevel 		len -= nbytes_longhex;
   1031  0  stevel 	}
   1032  0  stevel 	showxdr_hex(len, fmt);
   1033  0  stevel }
   1034  0  stevel 
   1035  0  stevel static void
   1036  0  stevel detail_nis_error()
   1037  0  stevel {
   1038  0  stevel 	enum nis_error status;
   1039  0  stevel 	int pos;
   1040  0  stevel 
   1041  0  stevel 	pos = getxdr_pos();
   1042  0  stevel 	status = (enum nis_error) getxdr_u_long();
   1043  0  stevel 	sprintf(get_line(pos, getxdr_pos()),
   1044  0  stevel 		"Status = %lu (%s)", status, nis_sperrno(status));
   1045  0  stevel }
   1046  0  stevel 
   1047  0  stevel void
   1048  0  stevel detail_nis_oid()
   1049  0  stevel {
   1050  0  stevel 	showxdr_time("    Object created at %s");
   1051  0  stevel 	showxdr_time("     last modified at %s");
   1052  0  stevel }
   1053  0  stevel 
   1054  0  stevel static void
   1055  0  stevel detail_nis_server(outdent)
   1056  0  stevel 	int outdent;	/* Crock to get indentation right.  Normally zero; */
   1057  0  stevel 			/*   set to four instead to remove leading spaces  */
   1058  0  stevel {
   1059  0  stevel 	unsigned nep;
   1060  0  stevel 	unsigned ktype;
   1061  0  stevel 	int pos1;
   1062  0  stevel 
   1063  0  stevel 	SHOW_NIS_NAME(outdent + "        Hostname = %s");
   1064  0  stevel 	nep = getxdr_u_long();
   1065  0  stevel 	while (nep-- > 0) { /* list of endpoints */
   1066  0  stevel 		(void) showxdr_string(1024,
   1067  0  stevel 					outdent + "            Uaddr    = %s");
   1068  0  stevel 		(void) showxdr_string(1024,
   1069  0  stevel 					outdent + "            Family   = %s");
   1070  0  stevel 		(void) showxdr_string(1024,
   1071  0  stevel 					outdent + "            Protocol = %s");
   1072  0  stevel 	}
   1073  0  stevel 	/*
   1074  0  stevel 	 * The format of the public-key information has changed (Aug '91).
   1075  0  stevel 	 *   Ye olde style was a u_char[64] (which XDR's pretty inefficiently,
   1076  0  stevel 	 *   but that's another matter).  The new format has a key-type
   1077  0  stevel 	 *   enumeration followed by an opaque<NIS_MAXKEYLEN>.  For now
   1078  0  stevel 	 *   (hence probably for all time) we'll hard-code the values of the
   1079  0  stevel 	 *   enumeration and of NIS_MAXKEYLEN here rather than getting them
   1080  0  stevel 	 *   from a header file.  Tsk.  Also for now, we'll try to guess
   1081  0  stevel 	 *   whether we're looking at the new format or the old.
   1082  0  stevel 	 */
   1083  0  stevel 	pos1 = getxdr_pos();
   1084  0  stevel 	ktype = getxdr_u_long();
   1085  0  stevel 	if (ktype < KEYTYPE_LIMIT || ktype == NIS_PK_DHEXT) {
   1086  0  stevel 		int	 pos2;
   1087  0  stevel 		unsigned klen;
   1088  0  stevel 
   1089  0  stevel 		pos2 = getxdr_pos();
   1090  0  stevel 		klen = getxdr_u_long();
   1091  0  stevel 		if (klen < KEYLEN_LIMIT) {
   1092  0  stevel 			/*
   1093  0  stevel 			 * Smells like new-style key; let's hope so.  If we're
   1094  0  stevel 			 *   wrong, it may cause XDR underflow.  Ugh.  ====
   1095  0  stevel 			 */
   1096  0  stevel 			sprintf(get_line(pos1, pos2),
   1097  0  stevel 				outdent + "        Key type   = %s",
   1098  0  stevel 				stringof_ktype(ktype));
   1099  0  stevel 			sprintf(get_line(pos2, getxdr_pos()),
   1100  0  stevel 				outdent + "        Key length = %lu", klen);
   1101  0  stevel 			if (klen != 0) {
   1102  0  stevel 				if (ktype == NIS_PK_DHEXT) {
   1103  0  stevel 					int marker;
   1104  0  stevel 					int key_count;
   1105  0  stevel 					marker = getxdr_pos();
   1106  0  stevel 					key_count = 1;
   1107  0  stevel 					while (getxdr_pos() < marker + klen) {
   1108  0  stevel 						ulong_t  a_u_long;
   1109  0  stevel 						ushort_t keylen;
   1110  0  stevel 						ushort_t algtype;
   1111  0  stevel 						size_t  binlen;
   1112  0  stevel 						size_t  binpadlen;
   1113  0  stevel 
   1114  0  stevel 						a_u_long = getxdr_u_long();
   1115  0  stevel 						keylen = a_u_long >> 16;
   1116  0  stevel 						algtype = a_u_long &
   1117  0  stevel 							((ushort_t)0xffff);
   1118  0  stevel 						binlen = (keylen + 7) / 8;
   1119  0  stevel 						binpadlen = ((binlen + 3) / 4)
   1120  0  stevel 								* 4;
   1121  0  stevel 						sprintf(get_line(0, 0),
   1122  0  stevel 					"            Key %d length = %hu bits",
   1123  0  stevel 							key_count, keylen);
   1124  0  stevel 						sprintf(get_line(0, 0),
   1125  0  stevel 					"            Algorithm type = %hu",
   1126  0  stevel 							algtype);
   1127  0  stevel 						if (keylen != 0)
   1128  0  stevel 							showxdr_hex(binpadlen,
   1129  0  stevel 					"            Key value = %s");
   1130  0  stevel 						key_count++;
   1131  0  stevel 					}
   1132  0  stevel 					setxdr_pos(marker + klen);
   1133  0  stevel 				} else {
   1134  0  stevel 					showxdr_hex(klen, outdent +
   1135  0  stevel 					    "        Key value  = %s");
   1136  0  stevel 				}
   1137  0  stevel 			}
   1138  0  stevel 			return;
   1139  0  stevel 		}
   1140  0  stevel 	}
   1141  0  stevel 	/*
   1142  0  stevel 	 * It didn't smell new, so assume it's the old u_char[64], which
   1143  0  stevel 	 *   XDR's as 64 32-bit words (ouch).
   1144  0  stevel 	 */
   1145  0  stevel 	setxdr_pos(4*SZ_PKEY + pos1);
   1146  0  stevel 	sprintf(get_line(pos1, getxdr_pos()),
   1147  0  stevel 		outdent + "        [Public Key not displayed]");
   1148  0  stevel }
   1149  0  stevel 
   1150  0  stevel void
   1151  0  stevel detail_directory_obj()
   1152  0  stevel {
   1153  0  stevel 	unsigned nstyp;
   1154  0  stevel 	unsigned nserv, nar;
   1155  0  stevel 	int pos;
   1156  0  stevel 	char *line;
   1157  0  stevel 
   1158  0  stevel 	SHOW_NIS_NAME("    Name    = %s");
   1159  0  stevel 	pos = getxdr_pos();
   1160  0  stevel 	nstyp = getxdr_u_long();
   1161  0  stevel 	line = get_line(pos, getxdr_pos());
   1162  0  stevel 	(void) sprintf(line, "    NStype  = %lu", nstyp);
   1163  0  stevel 	line += strlen(line);
   1164  0  stevel 
   1165  0  stevel 	switch (nstyp) {
   1166  0  stevel 	    case NIS:
   1167  0  stevel 		sprintf(line, " (NIS+)");
   1168  0  stevel 		break;
   1169  0  stevel 	    case SUNYP:
   1170  0  stevel 		sprintf(line, " (NIS/YP)");
   1171  0  stevel 		break;
   1172  0  stevel 	    case DNS:
   1173  0  stevel 		sprintf(line, " (DNS)");
   1174  0  stevel 		break;
   1175  0  stevel 	    default:
   1176  0  stevel 		break;
   1177  0  stevel 	}
   1178  0  stevel 
   1179  0  stevel 	nserv = showxdr_u_long("    Servers = %lu");
   1180  0  stevel 	while (nserv-- > 0) {	/* array of servers */
   1181  0  stevel 		detail_nis_server(0);
   1182  0  stevel 	}
   1183  0  stevel 	(void) showxdr_u_long("    Time to live  = %lu (seconds)");
   1184  0  stevel 	/* === show time in more useful form too? */
   1185  0  stevel 	nar = showxdr_u_long("    Access Rights = %lu");
   1186  0  stevel 	while (nar-- > 0) {	/* list of ar masks */
   1187  0  stevel 		unsigned ar, otype;
   1188  0  stevel 		pos = getxdr_pos();
   1189  0  stevel 		ar = getxdr_u_long();
   1190  0  stevel 		otype = getxdr_u_long();
   1191  0  stevel 		sprintf(get_line(pos, getxdr_pos()), "        %s for %s",
   1192  0  stevel 			stringof_rights(ar), stringof_otype(otype));
   1193  0  stevel 	}
   1194  0  stevel }
   1195  0  stevel 
   1196  0  stevel void
   1197  0  stevel detail_group_obj()
   1198  0  stevel {
   1199  0  stevel 	unsigned val;
   1200  0  stevel 	int pos;
   1201  0  stevel 
   1202  0  stevel 	pos = getxdr_pos();
   1203  0  stevel 	val = getxdr_u_long();
   1204  0  stevel 	sprintf(get_line(pos, getxdr_pos()),
   1205  0  stevel 		"    Flags    = %s", stringof_groupflags(val));
   1206  0  stevel 	val = showxdr_u_long("    Number of Members = %lu");
   1207  0  stevel 	while (val-- > 0) {
   1208  0  stevel 		SHOW_NIS_NAME("        %s");
   1209  0  stevel 	}
   1210  0  stevel }
   1211  0  stevel 
   1212  0  stevel void
   1213  0  stevel detail_table_obj()
   1214  0  stevel {
   1215  0  stevel 	unsigned ncols;
   1216  0  stevel 	unsigned col;
   1217  0  stevel 	(void) showxdr_string(1024, "    Table Type  = %s");
   1218  0  stevel 	(void) showxdr_long  ("    Max Columns = %d");
   1219  0  stevel 	(void) showxdr_char  ("    Separator   = '%c'"); /* ==== improve */
   1220  0  stevel 	ncols = showxdr_u_long("    Num Columns = %lu");
   1221  0  stevel 	for (col = 1; col <= ncols; col++) {
   1222  0  stevel 		int pos1, pos2;
   1223  0  stevel 		unsigned val;
   1224  0  stevel 		char format[23];
   1225  0  stevel 		/* === Print all three on one line? */
   1226  0  stevel 		sprintf(format, "%6d: ColName = \"%%s\"", col);
   1227  0  stevel 		(void) showxdr_string(NIS_MAXATTRNAME, format);
   1228  0  stevel 		pos1 = getxdr_pos();
   1229  0  stevel 		val = getxdr_u_long();
   1230  0  stevel 		pos2 = getxdr_pos();
   1231  0  stevel 		sprintf(get_line(pos1, pos2),
   1232  0  stevel 			"        Flags   = %s", stringof_colflags(val));
   1233  0  stevel 		val = getxdr_u_long();
   1234  0  stevel 		sprintf(get_line(pos2, getxdr_pos()),
   1235  0  stevel 			"        Rights  = %s", stringof_rights(val));
   1236  0  stevel 	}
   1237  0  stevel 	(void) showxdr_string(NIS_MAXPATH, "    Search Path = \"%s\"");
   1238  0  stevel }
   1239  0  stevel 
   1240  0  stevel void
   1241  0  stevel detail_entry_obj()
   1242  0  stevel {
   1243  0  stevel 	unsigned col, ncols;
   1244  0  stevel 	char *entyp;
   1245  0  stevel 	int is_nis_object = 0;
   1246  0  stevel 
   1247  0  stevel 	entyp = showxdr_string(1024, "    Entry Type  = \"%s\"");
   1248  0  stevel 	is_nis_object = (entyp != 0 && strcmp(entyp, "NIS object") == 0);
   1249  0  stevel 	/* Don't rely on entyp[] remaining valid */
   1250  0  stevel 	ncols = showxdr_u_long("    Num Columns = %lu");
   1251  0  stevel 	for (col = 1; col <= ncols; col++) {
   1252  0  stevel 		int pos1, pos2, len;
   1253  0  stevel 		unsigned flags;
   1254  0  stevel 		/* === Print both on one line? */
   1255  0  stevel 		pos1 = getxdr_pos();
   1256  0  stevel 		flags = getxdr_u_long();
   1257  0  stevel 		pos2 = getxdr_pos();
   1258  0  stevel 		if (ncols == 1) {
   1259  0  stevel 			sprintf(get_line(pos1, pos2),
   1260  0  stevel 				"        Flags = %s",
   1261  0  stevel 				stringof_entryflags(flags));
   1262  0  stevel 		} else {
   1263  0  stevel 			sprintf(get_line(pos1, pos2),
   1264  0  stevel 				"%6d: Flags = %s",
   1265  0  stevel 				col, stringof_entryflags(flags));
   1266  0  stevel 		}
   1267  0  stevel 		if (flags & (EN_BINARY | EN_CRYPT | EN_XDR)) {
   1268  0  stevel 			len = getxdr_u_long();
   1269  0  stevel 			if (is_nis_object &&
   1270  0  stevel 			    len == sizeof (unsigned long) &&
   1271  0  stevel 			    (flags & EN_CRYPT) == 0) {
   1272  0  stevel 				/* Special case for type = "NIS object" */
   1273  0  stevel 				unsigned otype = getxdr_u_long();
   1274  0  stevel 				sprintf(get_line(pos2, getxdr_pos()),
   1275  0  stevel 					"        Value = %08x (ObjType = %s)",
   1276  0  stevel 					otype, stringof_otype(otype));
   1277  0  stevel 			} else {
   1278  0  stevel 				showxdr_longhex(len,
   1279  0  stevel 						"        Value = Binary %s");
   1280  0  stevel 			}
   1281  0  stevel 		} else {
   1282  0  stevel 			showxdr_string(NIS_MAXATTRVAL,
   1283  0  stevel 					"        Value = ASCII \"%s\"");
   1284  0  stevel 		}
   1285  0  stevel 	}
   1286  0  stevel }
   1287  0  stevel 
   1288  0  stevel void
   1289  0  stevel detail_link_obj()
   1290  0  stevel {
   1291  0  stevel 	int pos;
   1292  0  stevel 	int val;
   1293  0  stevel 
   1294  0  stevel 	pos = getxdr_pos();
   1295  0  stevel 	val = getxdr_long();
   1296  0  stevel 	sprintf(get_line(pos, getxdr_pos()),
   1297  0  stevel 		"    Real Type= %08x (%s)", val, stringof_otype(val));
   1298  0  stevel 	detail_nis_attrs(0);
   1299  0  stevel 	SHOW_NIS_NAME("    Real Name= %s");
   1300  0  stevel }
   1301  0  stevel 
   1302  0  stevel void
   1303  0  stevel detail_private_obj()
   1304  0  stevel {
   1305  0  stevel 	/* ==== Need something fancier than this to be really useful */
   1306  0  stevel 	showxdr_longhex(getxdr_u_long(), "    Data     = Binary %s");
   1307  0  stevel }
   1308  0  stevel 
   1309  0  stevel void
   1310  0  stevel detail_nis_object()
   1311  0  stevel {
   1312  0  stevel 	unsigned rights, otype;
   1313  0  stevel 	int pos;
   1314  0  stevel 
   1315  0  stevel 	detail_nis_oid();
   1316  0  stevel 	SHOW_NIS_NAME("    Name     = %s");
   1317  0  stevel 	SHOW_NIS_NAME("    Owner    = %s");
   1318  0  stevel 	SHOW_NIS_NAME("    Group    = %s");
   1319  0  stevel 	SHOW_NIS_NAME("    Domain   = %s");
   1320  0  stevel 	pos = getxdr_pos();
   1321  0  stevel 	rights = getxdr_u_long();
   1322  0  stevel 	sprintf(get_line(pos, getxdr_pos()), "    Rights   = %s",
   1323  0  stevel 		stringof_rights(rights));
   1324  0  stevel 	(void) showxdr_u_long("    Lifetime = %8lu (seconds)");
   1325  0  stevel 
   1326  0  stevel 	/* ?? show_space(); */
   1327  0  stevel 	pos = getxdr_pos();
   1328  0  stevel 	otype = getxdr_u_long();
   1329  0  stevel 	(void) sprintf(get_line(pos, getxdr_pos()),
   1330  0  stevel 			"    ObjType  = %08x (%s)",
   1331  0  stevel 			otype, stringof_otype(otype));
   1332  0  stevel 	switch (otype) {
   1333  0  stevel 	    case NIS_DIRECTORY_OBJ:
   1334  0  stevel 		detail_directory_obj();
   1335  0  stevel 		break;
   1336  0  stevel 	    case NIS_GROUP_OBJ:
   1337  0  stevel 		detail_group_obj();
   1338  0  stevel 		break;
   1339  0  stevel 	    case NIS_TABLE_OBJ:
   1340  0  stevel 		detail_table_obj();
   1341  0  stevel 		break;
   1342  0  stevel 	    case NIS_ENTRY_OBJ:
   1343  0  stevel 		detail_entry_obj();
   1344  0  stevel 		break;
   1345  0  stevel 	    case NIS_LINK_OBJ:
   1346  0  stevel 		detail_link_obj();
   1347  0  stevel 		break;
   1348  0  stevel 	    case NIS_PRIVATE_OBJ:
   1349  0  stevel 		detail_private_obj();
   1350  0  stevel 		break;
   1351  0  stevel 	    default:
   1352  0  stevel 		/* ==== Can't do anything clever, right? */
   1353  0  stevel 		break;
   1354  0  stevel 	}
   1355  0  stevel }
   1356  0  stevel 
   1357  0  stevel static void
   1358  0  stevel detail_ns_request()
   1359  0  stevel {
   1360  0  stevel 	unsigned nobjs;
   1361  0  stevel 
   1362  0  stevel 	SHOW_NAME();
   1363  0  stevel 	nobjs = getxdr_u_long();
   1364  0  stevel 	/* nobjs should be 0 or 1 only; === should check it ? */
   1365  0  stevel 	if (nobjs != 0) {
   1366  0  stevel 		sprintf(get_line(0, 0), "Object included:");
   1367  0  stevel 	}
   1368  0  stevel 	while (nobjs-- > 0) {
   1369  0  stevel 		detail_nis_object();
   1370  0  stevel 	}
   1371  0  stevel }
   1372  0  stevel 
   1373  0  stevel static void
   1374  0  stevel detail_ib_request()
   1375  0  stevel {
   1376  0  stevel 	unsigned len;
   1377  0  stevel 	unsigned flags;
   1378  0  stevel 	int pos;
   1379  0  stevel 
   1380  0  stevel 	SHOW_NAME();
   1381  0  stevel 	detail_nis_attrs(INDENT_SPACES);
   1382  0  stevel 	pos = getxdr_pos();
   1383  0  stevel 	flags = getxdr_u_long();
   1384  0  stevel 	sprintf(get_line(pos, getxdr_pos()),
   1385  0  stevel 		"Flags = %s", stringof_ib_flags(flags));
   1386  0  stevel 	pos = getxdr_pos();
   1387  0  stevel 	len = getxdr_u_long();
   1388  0  stevel 	if (len == 0) {
   1389  0  stevel 		sprintf(get_line(pos, getxdr_pos()), "No included object");
   1390  0  stevel 	} else {
   1391  0  stevel 		/* len should be 0 or 1 only; === should check it ? */
   1392  0  stevel 		sprintf(get_line(pos, getxdr_pos()), "Included object:");
   1393  0  stevel 		while (len-- > 0) {
   1394  0  stevel 			detail_nis_object();
   1395  0  stevel 		}
   1396  0  stevel 	}
   1397  0  stevel 	pos = getxdr_pos();
   1398  0  stevel 	len = getxdr_u_long();
   1399  0  stevel 	if (len == 0) {
   1400  0  stevel 		sprintf(get_line(pos, getxdr_pos()), "No callback");
   1401  0  stevel 	} else {
   1402  0  stevel 		/* len should be 0 or 1 only; === should check it ? */
   1403  0  stevel 		sprintf(get_line(pos, getxdr_pos()), "Callback info:");
   1404  0  stevel 		while (len-- > 0) {
   1405  0  stevel 			detail_nis_server(INDENT_SPACES);
   1406  0  stevel 		}
   1407  0  stevel 	}
   1408  0  stevel 	(void) showxdr_u_long("Bufsize = %lu");
   1409  0  stevel 	detail_cookie();
   1410  0  stevel }
   1411  0  stevel 
   1412  0  stevel static void
   1413  0  stevel detail_fd_args()
   1414  0  stevel {
   1415  0  stevel 	SHOW_NAME();
   1416  0  stevel 	SHOW_NIS_NAME("Requester = %s");
   1417  0  stevel }
   1418  0  stevel 
   1419  0  stevel static void
   1420  0  stevel detail_nis_taglist()
   1421  0  stevel {
   1422  0  stevel 	unsigned ntags;
   1423  0  stevel 	unsigned tagn;
   1424  0  stevel 
   1425  0  stevel 	ntags = showxdr_u_long("Number of tags = %lu");
   1426  0  stevel 	for (tagn = 1; tagn < ntags; tagn++) {
   1427  0  stevel 		unsigned ttype;
   1428  0  stevel 		int pos;
   1429  0  stevel 
   1430  0  stevel 		if (ntags != 1) {
   1431  0  stevel 			sprintf(get_line(0, 0), "  Tag %d:", tagn);
   1432  0  stevel 		}
   1433  0  stevel 		pos = getxdr_pos();
   1434  0  stevel 		ttype = getxdr_u_long();
   1435  0  stevel 		sprintf(get_line(pos, getxdr_pos()),
   1436  0  stevel 			"    Tag name  = %08x (%s)",
   1437  0  stevel 			ttype, stringof_tag(ttype));
   1438  0  stevel 		showxdr_string(1024, "    Tag value = \"%s\"");
   1439  0  stevel 		/* ^ ==== nis.x says it's a string rather than an opaque, */
   1440  0  stevel 		/*	  but is it really?				  */
   1441  0  stevel 	}
   1442  0  stevel }
   1443  0  stevel 
   1444  0  stevel static void
   1445  0  stevel detail_dump_args()
   1446  0  stevel {
   1447  0  stevel 	unsigned nserv;
   1448  0  stevel 	int pos;
   1449  0  stevel 
   1450  0  stevel 	SHOW_NAME();
   1451  0  stevel 	showxdr_time("Time = %s");
   1452  0  stevel 
   1453  0  stevel 	pos = getxdr_pos();
   1454  0  stevel 	nserv = getxdr_u_long();
   1455  0  stevel 	if (nserv == 1) {
   1456  0  stevel 		sprintf(get_line(pos, getxdr_pos()), "Callback:");
   1457  0  stevel 	} else if (nserv > 1) {
   1458  0  stevel 		sprintf(get_line(pos, getxdr_pos()),
   1459  0  stevel 			"Num callbacks = %lu (!?):", nserv);
   1460  0  stevel 	}
   1461  0  stevel 	while (nserv-- > 0) {
   1462  0  stevel 		detail_nis_server(INDENT_SPACES);
   1463  0  stevel 	}
   1464  0  stevel }
   1465  0  stevel 
   1466  0  stevel static void
   1467  0  stevel detail_callback()	/* i.e. the netobj argument to NIS_CALLBACK */
   1468  0  stevel {
   1469  0  stevel 	detail_cookie();
   1470  0  stevel }
   1471  0  stevel 
   1472  0  stevel static void
   1473  0  stevel detail_cookie()
   1474  0  stevel {
   1475  0  stevel 	unsigned len;
   1476  0  stevel 	int pos;
   1477  0  stevel 
   1478  0  stevel 	pos = getxdr_pos();
   1479  0  stevel 	len = getxdr_u_long();
   1480  0  stevel 	if (len == 0) {
   1481  0  stevel 		sprintf(get_line(pos, getxdr_pos()), "Cookie = NULL");
   1482  0  stevel 	} else {
   1483  0  stevel 		showxdr_longhex(len, "Cookie = %s");
   1484  0  stevel 	}
   1485  0  stevel }
   1486  0  stevel 
   1487  0  stevel static void
   1488  0  stevel detail_ping_args()
   1489  0  stevel {
   1490  0  stevel 	SHOW_NAME();
   1491  0  stevel 	showxdr_time("Time = %s");
   1492  0  stevel }
   1493  0  stevel 
   1494  0  stevel static void
   1495  0  stevel detail_nis_name()
   1496  0  stevel {
   1497  0  stevel 	SHOW_NAME();
   1498  0  stevel }
   1499  0  stevel 
   1500  0  stevel static void
   1501  0  stevel detail_cback_data()
   1502  0  stevel {
   1503  0  stevel 	unsigned nobjs, no;
   1504  0  stevel 	nobjs = showxdr_u_long("Number of entries = %lu");
   1505  0  stevel 	for (no = 1; no <= nobjs; no++) {
   1506  0  stevel 		if (getxdr_long() == 0) {
   1507  0  stevel 			sprintf(get_line(0, 0), "  Entry %d is NULL (!?)", no);
   1508  0  stevel 		} else {
   1509  0  stevel 			if (nobjs != 1) {
   1510  0  stevel 
   1511  0  stevel 				sprintf(get_line(0, 0), "  Entry %d:", no);
   1512  0  stevel 			}
   1513  0  stevel 			detail_nis_object();
   1514  0  stevel 		}
   1515  0  stevel 	}
   1516  0  stevel }
   1517  0  stevel 
   1518  0  stevel static void
   1519  0  stevel detail_nis_result()
   1520  0  stevel {
   1521  0  stevel 	int pos;
   1522  0  stevel 	unsigned no, nobjs;
   1523  0  stevel 
   1524  0  stevel 	detail_nis_error();
   1525  0  stevel 	pos = getxdr_pos();
   1526  0  stevel 	nobjs = getxdr_u_long();
   1527  0  stevel 	sprintf(get_line(pos, getxdr_pos()), "Number of objects = %lu", nobjs);
   1528  0  stevel 	for (no = 1; no <= nobjs; no++) {
   1529  0  stevel 		if (nobjs != 1) {
   1530  0  stevel 			sprintf(get_line(0, 0), "  Object %d:", no);
   1531  0  stevel 		}
   1532  0  stevel 		detail_nis_object();
   1533  0  stevel 	}
   1534  0  stevel 	detail_cookie();
   1535  0  stevel 	showxdr_u_long("Server   ticks = %8lu");
   1536  0  stevel 	showxdr_u_long("Database ticks = %8lu");
   1537  0  stevel 	showxdr_u_long("Cache    ticks = %8lu"); /* These should always be   */
   1538  0  stevel 	showxdr_u_long("Client   ticks = %8lu"); /*   zero on the wire, yes? */
   1539  0  stevel }
   1540  0  stevel 
   1541  0  stevel static void
   1542  0  stevel detail_fd_result()
   1543  0  stevel {
   1544  0  stevel 	int pos;
   1545  0  stevel 	unsigned len;
   1546  0  stevel 	int dir_pos;
   1547  0  stevel 	unsigned dir_len;
   1548  0  stevel 	int dir_end;
   1549  0  stevel 
   1550  0  stevel 	detail_nis_error();
   1551  0  stevel 	SHOW_NAME();
   1552  0  stevel 	/* nis.x doesn't say so, but the opaque contains a directory_obj */
   1553  0  stevel 	dir_len = getxdr_u_long(); /* Byte-count at start of opaque */
   1554  0  stevel 	if (dir_len == 0) {
   1555  0  stevel 		sprintf(get_line(0, 0), "Directory object = NULL");
   1556  0  stevel 	} else {
   1557  0  stevel 		sprintf(get_line(0, 0), "Directory object:");
   1558  0  stevel 		dir_pos = getxdr_pos();
   1559  0  stevel 		dir_end = ((dir_len + 3) & ~3) + dir_pos;
   1560  0  stevel 		/*		^^^^^^^^^^ Did XDR do this already? */
   1561  0  stevel 		detail_directory_obj();
   1562  0  stevel 		pos = getxdr_pos();
   1563  0  stevel 		if (pos != dir_end) {
   1564  0  stevel 			sprintf(get_line(pos, dir_end),
   1565  0  stevel 			"(Skipping %d unused bytes at end of directory object)",
   1566  0  stevel 				dir_end - pos);
   1567  0  stevel 			setxdr_pos(dir_end);
   1568  0  stevel 		}
   1569  0  stevel 	}
   1570  0  stevel 	len = getxdr_u_long();
   1571  0  stevel 	if (len == 0) {
   1572  0  stevel 		sprintf(get_line(pos, getxdr_pos()),
   1573  0  stevel 			"Signature = NULL");
   1574  0  stevel 	} else {
   1575  0  stevel 		if (len > 8) {
   1576  0  stevel 			sprintf(get_line(pos, getxdr_pos()),
   1577  0  stevel 				"Signature length is %lu, expected <= 8 bytes",
   1578  0  stevel 				len);
   1579  0  stevel 		}
   1580  0  stevel 		showxdr_longhex(len, "Signature = %s");
   1581  0  stevel 	}
   1582  0  stevel }
   1583  0  stevel 
   1584  0  stevel /*
   1585  0  stevel  * is_printable() -- looks for a string of (len-1) printable characters
   1586  0  stevel  *	followed by a NUL.  Characters are deemed printable iff ctype's
   1587  0  stevel  *	isprint() macro says so, thus tab (^I) is regarded as unprintable.
   1588  0  stevel  * === Is this test more stringent than we want, esp wrt placement of NUL?
   1589  0  stevel  */
   1590  0  stevel static int
   1591  0  stevel is_printable(str, len)
   1592  0  stevel 	char	 *str;
   1593  0  stevel 	unsigned len;
   1594  0  stevel {
   1595  0  stevel 	while (len > 1) {
   1596  0  stevel 		if (!isprint(*str)) {
   1597  0  stevel 			return (0);
   1598  0  stevel 		}
   1599  0  stevel 		str++, len--;
   1600  0  stevel 	}
   1601  0  stevel 	return (len == 1 && *str == 0);
   1602  0  stevel }
   1603  0  stevel 
   1604  0  stevel static void
   1605  0  stevel detail_nis_attrs(outdent)
   1606  0  stevel 	int outdent;	/* Crock to get indentation right.  Normally zero; */
   1607  0  stevel 			/*   set to four instead to remove leading spaces  */
   1608  0  stevel {
   1609  0  stevel 	unsigned nattrs;
   1610  0  stevel 
   1611  0  stevel 	nattrs = showxdr_u_long(outdent + "    Number of attributes = %lu");
   1612  0  stevel 	while (nattrs-- > 0) {
   1613  0  stevel 		char	 *str;
   1614  0  stevel 		unsigned len;
   1615  0  stevel 		int pos;
   1616  0  stevel 
   1617  0  stevel 		showxdr_string(NIS_MAXATTRNAME,
   1618  0  stevel 				outdent + "        AttrName = %s");
   1619  0  stevel 		pos = getxdr_pos();
   1620  0  stevel 		str = getxdr_bytes(&len);
   1621  0  stevel 		if (is_printable(str, len)) {
   1622  0  stevel 			setxdr_pos(pos);
   1623  0  stevel 			showxdr_string(NIS_MAXATTRVAL, outdent +
   1624  0  stevel 					"        AttrVal  = ASCII \"%s\"");
   1625  0  stevel 		} else {
   1626  0  stevel 			setxdr_pos(pos);
   1627  0  stevel 			len = getxdr_u_long();	/* Yes, we knew it already */
   1628  0  stevel 			showxdr_longhex(len, outdent +
   1629  0  stevel 					"        AttrVal  = Binary %s");
   1630  0  stevel 		}
   1631  0  stevel 	}
   1632  0  stevel }
   1633  0  stevel 
   1634  0  stevel static void
   1635  0  stevel detail_log_entry()
   1636  0  stevel {
   1637  0  stevel 	int pos;
   1638  0  stevel 	long val;
   1639  0  stevel 
   1640  0  stevel 	showxdr_time("    Log Time  = %s");
   1641  0  stevel 	pos = getxdr_pos();
   1642  0  stevel 	val = getxdr_long();
   1643  0  stevel 	sprintf(get_line(pos, getxdr_pos()), "    Log Type  = %d (%s)",
   1644  0  stevel 		val, stringof_entry_t(val));
   1645  0  stevel 	SHOW_NIS_NAME("    Principal = %s");
   1646  0  stevel 	SHOW_NIS_NAME("    Table/dir = %s");
   1647  0  stevel 	detail_nis_attrs(0);
   1648  0  stevel 	sprintf(get_line(0, 0), "    Object Value:");
   1649  0  stevel 	detail_nis_object();
   1650  0  stevel }
   1651  0  stevel 
   1652  0  stevel static void
   1653  0  stevel detail_log_result()
   1654  0  stevel {
   1655  0  stevel 	unsigned len, nents, en;
   1656  0  stevel 	int pos;
   1657  0  stevel 
   1658  0  stevel 	detail_nis_error();
   1659  0  stevel 	pos = getxdr_pos();
   1660  0  stevel 	len = getxdr_u_long();
   1661  0  stevel 	detail_cookie();
   1662  0  stevel 	nents = showxdr_u_long("Number of log entries = %lu");
   1663  0  stevel 	for (en = 1; en <= nents; en++) {
   1664  0  stevel 		if (nents != 1) {
   1665  0  stevel 			sprintf(get_line(0, 0), "  Log Entry %d", en);
   1666  0  stevel 		}
   1667  0  stevel 		detail_log_entry();
   1668  0  stevel 	}
   1669  0  stevel }
   1670  0  stevel 
   1671  0  stevel static void
   1672  0  stevel detail_bool()
   1673  0  stevel {
   1674  0  stevel 	int pos;
   1675  0  stevel 	unsigned val;
   1676  0  stevel 
   1677  0  stevel 	pos = getxdr_pos();
   1678  0  stevel 	val = getxdr_u_long();
   1679  0  stevel 	sprintf(get_line(pos, getxdr_pos()),
   1680  0  stevel 		"Result = %s", val ? "true" : "false");
   1681  0  stevel }
   1682  0  stevel 
   1683  0  stevel static void
   1684  0  stevel detail_cptime()
   1685  0  stevel {
   1686  0  stevel 	showxdr_time("Time = %s");
   1687  0  stevel }
   1688  0  stevel 
   1689  0  stevel static void
   1690  0  stevel detail_cp_result()
   1691  0  stevel {
   1692  0  stevel 	detail_nis_error();
   1693  0  stevel 	showxdr_u_long("Ticks (Server) = %lu");
   1694  0  stevel 	showxdr_u_long("    (Database) = %lu");
   1695  0  stevel }
   1696