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-2000 by Sun Microsystems, Inc.
     24  0  stevel  * All rights reserved.
     25  0  stevel  */
     26  0  stevel 
     27  0  stevel #ident	"%Z%%M%	%I%	%E% SMI"	/* SunOS	*/
     28  0  stevel 
     29  0  stevel #include <sys/types.h>
     30  0  stevel #include <sys/errno.h>
     31  0  stevel #include <setjmp.h>
     32  0  stevel #include <sys/tiuser.h>
     33  0  stevel 
     34  0  stevel #include <rpc/types.h>
     35  0  stevel #include <rpc/xdr.h>
     36  0  stevel #include <rpc/auth.h>
     37  0  stevel #include <rpc/clnt.h>
     38  0  stevel #include <rpc/rpc_msg.h>
     39  0  stevel #include <nfs/nfs.h>
     40  0  stevel #include <rpcsvc/mount.h>
     41  0  stevel #include <string.h>
     42  0  stevel #include "snoop.h"
     43  0  stevel #include "snoop_nfs.h"
     44  0  stevel 
     45  0  stevel #ifndef MIN
     46  0  stevel #define	MIN(a, b) ((a) < (b) ? (a) : (b))
     47  0  stevel #endif
     48  0  stevel 
     49  0  stevel extern char *dlc_header;
     50  0  stevel extern jmp_buf xdr_err;
     51  0  stevel 
     52  0  stevel static void mountcall(int, int);
     53  0  stevel static void mountreply(int, int);
     54  0  stevel 
     55  0  stevel static void sum_mountstat(char *);
     56  0  stevel static void sum_mountstat3(char *);
     57  0  stevel static char *sum_mountfh(void);
     58  0  stevel static char *sum_mountfh3(void);
     59  0  stevel static char *sum_exports(void);
     60  0  stevel static char *sum_mounts(void);
     61  0  stevel 
     62  0  stevel static int detail_mountstat(void);
     63  0  stevel static void detail_mountstat3(void);
     64  0  stevel static void detail_mountfh(void);
     65  0  stevel static void detail_mountfh3(void);
     66  0  stevel static void detail_exports(void);
     67  0  stevel static void detail_mounts(void);
     68  0  stevel 
     69  0  stevel static char *statusmsg3(ulong_t);
     70  0  stevel 
     71  0  stevel static char *procnames_short[] = {
     72  0  stevel 	"Null",			/*  0 */
     73  0  stevel 	"Mount",		/*  1 */
     74  0  stevel 	"Get mount list",	/*  2 */
     75  0  stevel 	"Unmount",		/*  3 */
     76  0  stevel 	"Unmountall",		/*  4 */
     77  0  stevel 	"Get export list",	/*  5 */
     78  0  stevel 	"Get export list",	/*  6 */
     79  0  stevel 	"PATHCONF",		/*  7 */
     80  0  stevel };
     81  0  stevel 
     82  0  stevel static char *procnames_long[] = {
     83  0  stevel 	"Null procedure",		/*  0 */
     84  0  stevel 	"Add mount entry",		/*  1 */
     85  0  stevel 	"Return mount entries",		/*  2 */
     86  0  stevel 	"Remove mount entry",		/*  3 */
     87  0  stevel 	"Remove all mount entries",	/*  4 */
     88  0  stevel 	"Return export list",		/*  5 */
     89  0  stevel 	"Return export list",		/*  6 */
     90  0  stevel 	"Get POSIX Pathconf info",	/*  7 */
     91  0  stevel };
     92  0  stevel 
     93  0  stevel #define	MAXPROC	7
     94  0  stevel 
     95  0  stevel void
     96  0  stevel interpret_mount(flags, type, xid, vers, proc, data, len)
     97  0  stevel 	int flags, type, xid, vers, proc;
     98  0  stevel 	char *data;
     99  0  stevel 	int len;
    100  0  stevel {
    101  0  stevel 	char *line;
    102  0  stevel 	char buff[MNTPATHLEN + 1];
    103  0  stevel 
    104  0  stevel 	if (proc < 0 || proc > MAXPROC)
    105  0  stevel 		return;
    106  0  stevel 
    107  0  stevel 	if (flags & F_SUM) {
    108  0  stevel 		if (setjmp(xdr_err)) {
    109  0  stevel 			return;
    110  0  stevel 		}
    111  0  stevel 
    112  0  stevel 		line = get_sum_line();
    113  0  stevel 
    114  0  stevel 		if (type == CALL) {
    115  0  stevel 			(void) sprintf(line, "MOUNT%d C %s",
    116  0  stevel 				vers, procnames_short[proc]);
    117  0  stevel 			line += strlen(line);
    118  0  stevel 			switch (proc) {
    119  0  stevel 			case MOUNTPROC_MNT:
    120  0  stevel 			case MOUNTPROC_UMNT:
    121  0  stevel 				(void) sprintf(line, " %s",
    122  0  stevel 					getxdr_string(buff, MNTPATHLEN));
    123  0  stevel 				break;
    124  0  stevel 			case MOUNTPROC_DUMP:
    125  0  stevel 			case MOUNTPROC_UMNTALL:
    126  0  stevel 			case MOUNTPROC_EXPORT:
    127  0  stevel 			case MOUNTPROC_EXPORTALL:
    128  0  stevel #ifdef MOUNTPROC_PATHCONF
    129  0  stevel 			case MOUNTPROC_PATHCONF:
    130  0  stevel 				if (vers != 3)
    131  0  stevel 					(void) sprintf(line, " %s",
    132  0  stevel 						getxdr_string(buff,
    133  0  stevel 						    MNTPATHLEN));
    134  0  stevel #endif
    135  0  stevel 				break;
    136  0  stevel 			default:
    137  0  stevel 				break;
    138  0  stevel 			}
    139  0  stevel 
    140  0  stevel 			check_retransmit(line, xid);
    141  0  stevel 		} else {
    142  0  stevel 			(void) sprintf(line, "MOUNT%d R %s ",
    143  0  stevel 				vers, procnames_short[proc]);
    144  0  stevel 			line += strlen(line);
    145  0  stevel 			switch (proc) {
    146  0  stevel 			case MOUNTPROC_MNT:
    147  0  stevel 				if (vers == 3)
    148  0  stevel 					sum_mountstat3(line);
    149  0  stevel 				else
    150  0  stevel 					sum_mountstat(line);
    151  0  stevel 				break;
    152  0  stevel 			case MOUNTPROC_DUMP:
    153  0  stevel 				(void) sprintf(line, sum_mounts());
    154  0  stevel 				break;
    155  0  stevel 			case MOUNTPROC_UMNT:
    156  0  stevel 			case MOUNTPROC_UMNTALL:
    157  0  stevel 				(void) sprintf(line, "reply");
    158  0  stevel 				break;
    159  0  stevel 			case MOUNTPROC_EXPORTALL:
    160  0  stevel 				/*
    161  0  stevel 				 * EXPORTALL is the same as EXPORT in v1
    162  0  stevel 				 * and v2, and it doesn't exist in v3.
    163  0  stevel 				 */
    164  0  stevel 				if (vers == 3)
    165  0  stevel 					break;
    166  0  stevel 				/*FALLTHROUGH*/
    167  0  stevel 			case MOUNTPROC_EXPORT:
    168  0  stevel 				(void) sprintf(line, sum_exports());
    169  0  stevel 				break;
    170  0  stevel #ifdef MOUNTPROC_PATHCONF
    171  0  stevel 			case MOUNTPROC_PATHCONF:
    172  0  stevel 				if (vers != 2)
    173  0  stevel 					break;
    174  0  stevel #ifdef notyet
    175  0  stevel 				(void) sprintf(line, sum_ppathcnf());
    176  0  stevel #endif
    177  0  stevel 				break;
    178  0  stevel #endif
    179  0  stevel 			default:
    180  0  stevel 				break;
    181  0  stevel 			}
    182  0  stevel 		}
    183  0  stevel 	}
    184  0  stevel 
    185  0  stevel 	if (flags & F_DTAIL) {
    186  0  stevel 		show_header("MOUNT:", "NFS MOUNT", len);
    187  0  stevel 		show_space();
    188  0  stevel 		if (setjmp(xdr_err)) {
    189  0  stevel 			return;
    190  0  stevel 		}
    191  0  stevel 		(void) sprintf(get_line(0, 0),
    192  0  stevel 			"Proc = %d (%s)",
    193  0  stevel 			proc, procnames_long[proc]);
    194  0  stevel 		if (type == CALL)
    195  0  stevel 			mountcall(proc, vers);
    196  0  stevel 		else
    197  0  stevel 			mountreply(proc, vers);
    198  0  stevel 		show_trailer();
    199  0  stevel 	}
    200  0  stevel }
    201  0  stevel 
    202  0  stevel /*
    203  0  stevel  *  Interpret call packets in detail
    204  0  stevel  */
    205  0  stevel 
    206  0  stevel static void
    207  0  stevel mountcall(proc, vers)
    208  0  stevel 	int proc, vers;
    209  0  stevel {
    210  0  stevel 
    211  0  stevel 	switch (proc) {
    212  0  stevel 	case MOUNTPROC_MNT:
    213  0  stevel 	case MOUNTPROC_UMNT:
    214  0  stevel 		(void) showxdr_string(MNTPATHLEN, "Directory = %s");
    215  0  stevel 		break;
    216  0  stevel 	case MOUNTPROC_DUMP:
    217  0  stevel 		break;
    218  0  stevel 	case MOUNTPROC_UMNTALL:
    219  0  stevel 		break;
    220  0  stevel 	case MOUNTPROC_EXPORTALL:
    221  0  stevel 		if (vers == 3)
    222  0  stevel 			break;
    223  0  stevel 		break;
    224  0  stevel 	case MOUNTPROC_EXPORT:
    225  0  stevel 		break;
    226  0  stevel #ifdef MOUNTPROC_PATHCONF
    227  0  stevel 	case MOUNTPROC_PATHCONF:
    228  0  stevel 		if (vers != 2)
    229  0  stevel 			break;
    230  0  stevel 		(void) showxdr_string(MNTPATHLEN, "File = %s");
    231  0  stevel #endif
    232  0  stevel 		break;
    233  0  stevel 	default:
    234  0  stevel 		break;
    235  0  stevel 	}
    236  0  stevel }
    237  0  stevel 
    238  0  stevel /*
    239  0  stevel  *  Interpret reply packets in detail
    240  0  stevel  */
    241  0  stevel 
    242  0  stevel static void
    243  0  stevel mountreply(proc, vers)
    244  0  stevel 	int proc, vers;
    245  0  stevel {
    246  0  stevel 
    247  0  stevel 	switch (proc) {
    248  0  stevel 	case MOUNTPROC_MNT:
    249  0  stevel 		if (vers == 3) {
    250  0  stevel 			detail_mountstat3();
    251  0  stevel 		} else {
    252  0  stevel 			if (detail_mountstat() == 0) {
    253  0  stevel 				detail_mountfh();
    254  0  stevel 			}
    255  0  stevel 		}
    256  0  stevel 		break;
    257  0  stevel 	case MOUNTPROC_DUMP:
    258  0  stevel 		detail_mounts();
    259  0  stevel 		break;
    260  0  stevel 	case MOUNTPROC_UMNT:
    261  0  stevel 	case MOUNTPROC_UMNTALL:
    262  0  stevel 		(void) detail_mountstat();
    263  0  stevel 		break;
    264  0  stevel 	case MOUNTPROC_EXPORTALL:
    265  0  stevel 		if (vers == 3)
    266  0  stevel 			break;
    267  0  stevel 		/*FALLTHROUGH*/
    268  0  stevel 	case MOUNTPROC_EXPORT:
    269  0  stevel 		detail_exports();
    270  0  stevel 		break;
    271  0  stevel #ifdef MOUNTPROC_PATHCONF
    272  0  stevel 	case MOUNTPROC_PATHCONF:
    273  0  stevel #ifdef notyet
    274  0  stevel 		(void) detail_ppathcnf();
    275  0  stevel #endif
    276  0  stevel 		break;
    277  0  stevel #endif
    278  0  stevel 	default:
    279  0  stevel 		break;
    280  0  stevel 	}
    281  0  stevel }
    282  0  stevel 
    283  0  stevel static void
    284  0  stevel sum_mountstat(line)
    285  0  stevel 	char *line;
    286  0  stevel {
    287  0  stevel 	ulong_t status;
    288  0  stevel 	char *str;
    289  0  stevel 
    290  0  stevel 	status = getxdr_u_long();
    291  0  stevel 	if (status == 0)
    292  0  stevel 		str = "OK";
    293  0  stevel 	else if ((str = strerror(status)) == (char *)NULL)
    294  0  stevel 		str = "";
    295  0  stevel 	(void) strcpy(line, str);
    296  0  stevel 	if (status == 0) {
    297  0  stevel 		(void) strcat(line, sum_mountfh());
    298  0  stevel 	}
    299  0  stevel }
    300  0  stevel 
    301  0  stevel static int
    302  0  stevel detail_mountstat()
    303  0  stevel {
    304  0  stevel 	ulong_t status;
    305  0  stevel 	char *str;
    306  0  stevel 
    307  0  stevel 	status = getxdr_u_long();
    308  0  stevel 	if (status == 0)
    309  0  stevel 		str = "OK";
    310  0  stevel 	else if ((str = strerror(status)) == (char *)NULL)
    311  0  stevel 		str = "";
    312  0  stevel 
    313  0  stevel 	(void) sprintf(get_line(0, 0), "Status = %d (%s)", status, str);
    314  0  stevel 
    315  0  stevel 	return ((int)status);
    316  0  stevel }
    317  0  stevel 
    318  0  stevel char *
    319  0  stevel sum_mountfh()
    320  0  stevel {
    321  0  stevel 	int fh;
    322  0  stevel 	static char buff[8];
    323  0  stevel 
    324  0  stevel 	fh = sum_filehandle(NFS_FHSIZE);
    325  0  stevel 	(void) sprintf(buff, " FH=%04X", fh & 0xFFFF);
    326  0  stevel 	return (buff);
    327  0  stevel }
    328  0  stevel 
    329  0  stevel static void
    330  0  stevel detail_mountfh()
    331  0  stevel {
    332  0  stevel 	int pos;
    333  0  stevel 	int fh;
    334  0  stevel 
    335  0  stevel 	pos = getxdr_pos();
    336  0  stevel 	fh = sum_filehandle(NFS_FHSIZE);
    337  0  stevel 	setxdr_pos(pos);
    338  0  stevel 	(void) sprintf(get_line(0, 0), "File handle = [%04X]", fh & 0xFFFF);
    339  0  stevel 	(void) showxdr_hex(NFS_FHSIZE, " %s");
    340  0  stevel }
    341  0  stevel 
    342  0  stevel static char *
    343  0  stevel print_auth()
    344  0  stevel {
    345  0  stevel 	int i, auth, flavors;
    346  0  stevel 	char *p;
    347  0  stevel 	static char buff[64];
    348  0  stevel 
    349  0  stevel 	buff[0] = '\0';
    350  0  stevel 	flavors = getxdr_long();
    351  0  stevel 	for (i = 0; i < flavors; i++) {
    352  0  stevel 		if (i > 0)
    353  0  stevel 			(void) strlcat(buff, ",", sizeof (buff));
    354  0  stevel 		switch (auth = getxdr_u_long()) {
    355  0  stevel 		case AUTH_NONE:
    356  0  stevel 			(void) strlcat(buff, "none", sizeof (buff));
    357  0  stevel 			break;
    358  0  stevel 		case AUTH_UNIX:
    359  0  stevel 			(void) strlcat(buff, "unix", sizeof (buff));
    360  0  stevel 			break;
    361  0  stevel 		case AUTH_SHORT:
    362  0  stevel 			(void) strlcat(buff, "short", sizeof (buff));
    363  0  stevel 			break;
    364  0  stevel 		case AUTH_DES:
    365  0  stevel 			(void) strlcat(buff, "des", sizeof (buff));
    366  0  stevel 			break;
    367  0  stevel 		default:
    368  0  stevel 			p = buff + strlen(buff);
    369  0  stevel 			if (p < &buff[sizeof (buff)])
    370  0  stevel 				(void) snprintf(p, sizeof (buff) - strlen(buff),
    371  0  stevel 					"%d", auth);
    372  0  stevel 			break;
    373  0  stevel 		}
    374  0  stevel 	}
    375  0  stevel 	return (buff);
    376  0  stevel }
    377  0  stevel 
    378  0  stevel static void
    379  0  stevel sum_mountstat3(line)
    380  0  stevel 	char *line;
    381  0  stevel {
    382  0  stevel 	ulong_t status;
    383  0  stevel 
    384  0  stevel 	status = getxdr_u_long();
    385  0  stevel 	(void) strcpy(line, statusmsg3(status));
    386  0  stevel 	if (status == 0) {
    387  0  stevel 		(void) strcat(line, sum_mountfh3());
    388  0  stevel 		(void) strcat(line, " Auth=");
    389  0  stevel 		(void) strcat(line, print_auth());
    390  0  stevel 	}
    391  0  stevel }
    392  0  stevel 
    393  0  stevel static void
    394  0  stevel detail_mountstat3()
    395  0  stevel {
    396  0  stevel 	ulong_t status;
    397  0  stevel 
    398  0  stevel 	status = getxdr_u_long();
    399  0  stevel 	(void) sprintf(get_line(0, 0), "Status = %d (%s)", status,
    400  0  stevel 			statusmsg3(status));
    401  0  stevel 	if (status == 0) {
    402  0  stevel 		detail_mountfh3();
    403  0  stevel 		(void) sprintf(get_line(0, 0), "Authentication flavor = %s",
    404  0  stevel 				print_auth());
    405  0  stevel 	}
    406  0  stevel }
    407  0  stevel 
    408  0  stevel char *
    409  0  stevel sum_mountfh3()
    410  0  stevel {
    411  0  stevel 	int len;
    412  0  stevel 	int fh;
    413  0  stevel 	static char buff[8];
    414  0  stevel 
    415  0  stevel 	len = getxdr_long();
    416  0  stevel 	fh = sum_filehandle(len);
    417  0  stevel 	(void) sprintf(buff, " FH=%04X", fh & 0xFFFF);
    418  0  stevel 	return (buff);
    419  0  stevel }
    420  0  stevel 
    421  0  stevel static void
    422  0  stevel detail_mountfh3()
    423  0  stevel {
    424  0  stevel 	int pos;
    425  0  stevel 	int i, l, len;
    426  0  stevel 	int fh;
    427  0  stevel 
    428  0  stevel 	len = getxdr_long();
    429  0  stevel 	pos = getxdr_pos();
    430  0  stevel 	fh = sum_filehandle(len);
    431  0  stevel 	setxdr_pos(pos);
    432  0  stevel 	(void) sprintf(get_line(0, 0), "File handle = [%04X]", fh & 0xFFFF);
    433  0  stevel 	i = 0;
    434  0  stevel 	while (i < len) {
    435  0  stevel 		l = MIN(len - i, 32);
    436  0  stevel 		(void) showxdr_hex(l, " %s");
    437  0  stevel 		i += l;
    438  0  stevel 	}
    439  0  stevel }
    440  0  stevel 
    441  0  stevel static char *
    442  0  stevel sum_exports()
    443  0  stevel {
    444  0  stevel 	static char buff[MNTPATHLEN + 1];
    445  0  stevel 	int entries = 0;
    446  0  stevel 
    447  0  stevel 	if (setjmp(xdr_err)) {
    448  0  stevel 		(void) sprintf(buff, "%d+ entries", entries);
    449  0  stevel 		return (buff);
    450  0  stevel 	}
    451  0  stevel 
    452  0  stevel 	while (getxdr_long()) {
    453  0  stevel 		(void) getxdr_string(buff, MNTPATHLEN);
    454  0  stevel 		while (getxdr_long()) {
    455  0  stevel 			(void) getxdr_string(buff, MNTNAMLEN);
    456  0  stevel 		}
    457  0  stevel 		entries++;
    458  0  stevel 	}
    459  0  stevel 
    460  0  stevel 	(void) sprintf(buff, "%d entries", entries);
    461  0  stevel 	return (buff);
    462  0  stevel }
    463  0  stevel 
    464  0  stevel static void
    465  0  stevel detail_exports()
    466  0  stevel {
    467  0  stevel 	int entries = 0;
    468  0  stevel 	char *dirpath, *grpname;
    469  0  stevel 	char buff[MNTPATHLEN + 1];
    470  0  stevel 
    471  0  stevel 	if (setjmp(xdr_err)) {
    472  0  stevel 		(void) sprintf(get_line(0, 0),
    473  0  stevel 			" %d+ entries. (Frame is incomplete)",
    474  0  stevel 			entries);
    475  0  stevel 		return;
    476  0  stevel 	}
    477  0  stevel 
    478  0  stevel 	while (getxdr_long()) {
    479  0  stevel 		dirpath = (char *)getxdr_string(buff, MNTPATHLEN);
    480  0  stevel 		(void) sprintf(get_line(0, 0), "Directory = %s", dirpath);
    481  0  stevel 		entries++;
    482  0  stevel 		while (getxdr_long()) {
    483  0  stevel 			grpname = (char *)getxdr_string(buff, MNTNAMLEN);
    484  0  stevel 			(void) sprintf(get_line(0, 0), " Group = %s", grpname);
    485  0  stevel 		}
    486  0  stevel 	}
    487  0  stevel }
    488  0  stevel 
    489  0  stevel static char *
    490  0  stevel sum_mounts()
    491  0  stevel {
    492  0  stevel 	int entries = 0;
    493  0  stevel 	static char buff[MNTPATHLEN + 1];
    494  0  stevel 
    495  0  stevel 	if (setjmp(xdr_err)) {
    496  0  stevel 		(void) sprintf(buff, "%d+ entries", entries);
    497  0  stevel 		return (buff);
    498  0  stevel 	}
    499  0  stevel 
    500  0  stevel 	while (getxdr_long()) {
    501  0  stevel 		(void) getxdr_string(buff, MNTNAMLEN);
    502  0  stevel 		(void) getxdr_string(buff, MNTPATHLEN);
    503  0  stevel 		entries++;
    504  0  stevel 	}
    505  0  stevel 
    506  0  stevel 	(void) sprintf(buff, "%d entries", entries);
    507  0  stevel 	return (buff);
    508  0  stevel }
    509  0  stevel 
    510  0  stevel static void
    511  0  stevel detail_mounts()
    512  0  stevel {
    513  0  stevel 	int entries = 0;
    514  0  stevel 	char *hostname, *directory;
    515  0  stevel 	char buff1[MNTNAMLEN + 1], buff2[MNTPATHLEN + 1];
    516  0  stevel 
    517  0  stevel 	if (setjmp(xdr_err)) {
    518  0  stevel 		(void) sprintf(get_line(0, 0),
    519  0  stevel 			" %d+ entries. (Frame is incomplete)",
    520  0  stevel 			entries);
    521  0  stevel 		return;
    522  0  stevel 	}
    523  0  stevel 
    524  0  stevel 	(void) sprintf(get_line(0, 0), "Mount list");
    525  0  stevel 
    526  0  stevel 	while (getxdr_long()) {
    527  0  stevel 		hostname  = (char *)getxdr_string(buff1, MNTNAMLEN);
    528  0  stevel 		directory = (char *)getxdr_string(buff2, MNTPATHLEN);
    529  0  stevel 		(void) sprintf(get_line(0, 0), "   %s:%s", hostname, directory);
    530  0  stevel 		entries++;
    531  0  stevel 	}
    532  0  stevel }
    533  0  stevel 
    534  0  stevel char *
    535  0  stevel statusmsg3(status)
    536  0  stevel 	ulong_t status;
    537  0  stevel {
    538  0  stevel 
    539  0  stevel 	switch (status) {
    540  0  stevel 	case MNT_OK:
    541  0  stevel 		return ("OK");
    542  0  stevel 	case MNT3ERR_PERM:
    543  0  stevel 		return ("Not owner");
    544  0  stevel 	case MNT3ERR_NOENT:
    545  0  stevel 		return ("No such file or directory");
    546  0  stevel 	case MNT3ERR_IO:
    547  0  stevel 		return ("I/O error");
    548  0  stevel 	case MNT3ERR_ACCES:
    549  0  stevel 		return ("Permission denied");
    550  0  stevel 	case MNT3ERR_NOTDIR:
    551  0  stevel 		return ("Not a directory");
    552  0  stevel 	case MNT3ERR_INVAL:
    553  0  stevel 		return ("Invalid argument");
    554  0  stevel 	case MNT3ERR_NAMETOOLONG:
    555  0  stevel 		return ("File name too long");
    556  0  stevel 	case MNT3ERR_NOTSUPP:
    557  0  stevel 		return ("Operation not supported");
    558  0  stevel 	case MNT3ERR_SERVERFAULT:
    559  0  stevel 		return ("Server error");
    560  0  stevel 	default:
    561  0  stevel 		return ("(unknown error)");
    562  0  stevel 	}
    563  0  stevel }
    564