xref: /titanic_51/usr/src/cmd/devmgmt/cmds/putdev.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2002-2003 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate /*
34*7c478bd9Sstevel@tonic-gate  *	Implements the "putdev" command.
35*7c478bd9Sstevel@tonic-gate  */
36*7c478bd9Sstevel@tonic-gate #include	<sys/types.h>
37*7c478bd9Sstevel@tonic-gate #include	<stdio.h>
38*7c478bd9Sstevel@tonic-gate #include	<stdlib.h>
39*7c478bd9Sstevel@tonic-gate #include	<string.h>
40*7c478bd9Sstevel@tonic-gate #include	<errno.h>
41*7c478bd9Sstevel@tonic-gate #include	<unistd.h>
42*7c478bd9Sstevel@tonic-gate #include	<fmtmsg.h>
43*7c478bd9Sstevel@tonic-gate #include	<devmgmt.h>
44*7c478bd9Sstevel@tonic-gate #include	<devtab.h>
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate /*
48*7c478bd9Sstevel@tonic-gate  * General Purpose Constants
49*7c478bd9Sstevel@tonic-gate  *	TRUE		Boolean TRUE (if not already defined)
50*7c478bd9Sstevel@tonic-gate  *	FALSE		Boolean FALSE (if not already defined)
51*7c478bd9Sstevel@tonic-gate  *	NULL		Null address (if not already defined)
52*7c478bd9Sstevel@tonic-gate  */
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate #ifndef	TRUE
55*7c478bd9Sstevel@tonic-gate #define	TRUE	(1)
56*7c478bd9Sstevel@tonic-gate #endif
57*7c478bd9Sstevel@tonic-gate 
58*7c478bd9Sstevel@tonic-gate #ifndef	FALSE
59*7c478bd9Sstevel@tonic-gate #define	FALSE	(0)
60*7c478bd9Sstevel@tonic-gate #endif
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate /*
63*7c478bd9Sstevel@tonic-gate  * Exit codes
64*7c478bd9Sstevel@tonic-gate  *	EX_OK		All went well
65*7c478bd9Sstevel@tonic-gate  *	EX_ERROR	Usage or internal error
66*7c478bd9Sstevel@tonic-gate  *	EX_DEVTAB	Had trouble accessing/reading/writing the device table
67*7c478bd9Sstevel@tonic-gate  *	EX_EXISTS	The specified alias already exists
68*7c478bd9Sstevel@tonic-gate  *	EX_ATTRIB	One or more attributes requested for removal was not
69*7c478bd9Sstevel@tonic-gate  *			defined for the device
70*7c478bd9Sstevel@tonic-gate  *	EX_RELPATH	Pathname supplied for cdevice, bdevice or pathname
71*7c478bd9Sstevel@tonic-gate  *			attributes was not a full pathname
72*7c478bd9Sstevel@tonic-gate  */
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate #define	EX_OK		0
75*7c478bd9Sstevel@tonic-gate #define	EX_ERROR	1
76*7c478bd9Sstevel@tonic-gate #define	EX_DEVTAB	2
77*7c478bd9Sstevel@tonic-gate #define	EX_EXISTS	3
78*7c478bd9Sstevel@tonic-gate #define	EX_ATTRIB	4
79*7c478bd9Sstevel@tonic-gate #define	EX_RELPATH	4
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate /*
83*7c478bd9Sstevel@tonic-gate  * Error messages
84*7c478bd9Sstevel@tonic-gate  */
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate #define	E_USAGE		"usage: putdev -a alias [attribute=value [...]]\n       putdev -m device attribute=value [attribute=value [...]]\n       putdev -d device [attribute [...]]"
87*7c478bd9Sstevel@tonic-gate #define	E_ALIASIS	"Alias already exists in table: %s"
88*7c478bd9Sstevel@tonic-gate #define	E_NODEV		"Device does not exist in table: %s"
89*7c478bd9Sstevel@tonic-gate #define	E_NOALIAS	"Cannot use \"alias\" as an attribute"
90*7c478bd9Sstevel@tonic-gate #define	E_NOATTR	"Attribute not found: %s"
91*7c478bd9Sstevel@tonic-gate #define	E_NODEVTAB	"Cannot open the device table: %s"
92*7c478bd9Sstevel@tonic-gate #define	E_NOMKDTAB	"Cannot create a new device table: %s"
93*7c478bd9Sstevel@tonic-gate #define	E_INVALIAS	"Not a valid device alias: %s"
94*7c478bd9Sstevel@tonic-gate #define E_MULTIPLE	"Multiple definitions of an attribute are not allowed."
95*7c478bd9Sstevel@tonic-gate #define	E_INTERNAL	"Internal error, errno=%d"
96*7c478bd9Sstevel@tonic-gate #define	E_RELPATH	"Full pathname required for cdevice,bdevice and pathname attributes."
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate /*
100*7c478bd9Sstevel@tonic-gate  * Macros
101*7c478bd9Sstevel@tonic-gate  *	stdmsg(r,l,s,t)	    Using fmtmsg(), write a standard message to the
102*7c478bd9Sstevel@tonic-gate  *			    standard error stream.
103*7c478bd9Sstevel@tonic-gate  *			    Where:
104*7c478bd9Sstevel@tonic-gate  *				r   The recoverability of the error
105*7c478bd9Sstevel@tonic-gate  *				l   The label-component
106*7c478bd9Sstevel@tonic-gate  *				s   The severity-component
107*7c478bd9Sstevel@tonic-gate  *				t   The text-component
108*7c478bd9Sstevel@tonic-gate  */
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate #define stdmsg(r,l,s,t) (void) fmtmsg(MM_PRINT|MM_UTIL|r,l,s,t,MM_NULLACT,MM_NULLTAG)
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate /*
114*7c478bd9Sstevel@tonic-gate  * Static data
115*7c478bd9Sstevel@tonic-gate  *	msg		Space for message's text-component
116*7c478bd9Sstevel@tonic-gate  */
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate static	char		msg[256];	/* Space for text of message */
119*7c478bd9Sstevel@tonic-gate 
120*7c478bd9Sstevel@tonic-gate /*
121*7c478bd9Sstevel@tonic-gate  * char *mklbl(cmd)
122*7c478bd9Sstevel@tonic-gate  *	char   *cmd
123*7c478bd9Sstevel@tonic-gate  *
124*7c478bd9Sstevel@tonic-gate  *	This function builds a standard label from the command used to invoke
125*7c478bd9Sstevel@tonic-gate  *	this process and the standard label prefix ("UX:")
126*7c478bd9Sstevel@tonic-gate  *
127*7c478bd9Sstevel@tonic-gate  * Arguments:
128*7c478bd9Sstevel@tonic-gate  *	char *cmd	The command used to invoke this process.
129*7c478bd9Sstevel@tonic-gate  *
130*7c478bd9Sstevel@tonic-gate  * Returns:  char *
131*7c478bd9Sstevel@tonic-gate  *	Pointer to malloc()ed space containing the standard label,
132*7c478bd9Sstevel@tonic-gate  *	or (char *) NULL if an error occurred.
133*7c478bd9Sstevel@tonic-gate  */
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate static char *
136*7c478bd9Sstevel@tonic-gate mklbl(cmd)
137*7c478bd9Sstevel@tonic-gate 	char   *cmd;
138*7c478bd9Sstevel@tonic-gate {
139*7c478bd9Sstevel@tonic-gate 	/* Automatic data */
140*7c478bd9Sstevel@tonic-gate 	char   *rtn;		/* Value to return */
141*7c478bd9Sstevel@tonic-gate 	char   *p;		/* Temporary */
142*7c478bd9Sstevel@tonic-gate 
143*7c478bd9Sstevel@tonic-gate 	/* Find the 1st char of the basename of the command */
144*7c478bd9Sstevel@tonic-gate 	if (p = strrchr(cmd, '/')) p++;
145*7c478bd9Sstevel@tonic-gate 	else p = cmd;
146*7c478bd9Sstevel@tonic-gate 
147*7c478bd9Sstevel@tonic-gate 	/* Allocate and build the string value to return */
148*7c478bd9Sstevel@tonic-gate 	if (rtn = (char *) malloc(strlen("UX:")+strlen(p)+1)) {
149*7c478bd9Sstevel@tonic-gate 	    (void) strcpy(rtn, "UX:");
150*7c478bd9Sstevel@tonic-gate 	    (void) strcat(rtn, p);
151*7c478bd9Sstevel@tonic-gate 	}
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate 
154*7c478bd9Sstevel@tonic-gate 	/* Now that we've done all of that work, change the environment
155*7c478bd9Sstevel@tonic-gate 	 * so that only the text-component is written by fmtmsg().
156*7c478bd9Sstevel@tonic-gate 	 * (This should go away in SVR4.1)
157*7c478bd9Sstevel@tonic-gate 	 */
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate 	(void) putenv("MSGVERB=text");
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate 	/* Done */
163*7c478bd9Sstevel@tonic-gate 	return(rtn);
164*7c478bd9Sstevel@tonic-gate }
165*7c478bd9Sstevel@tonic-gate 
166*7c478bd9Sstevel@tonic-gate /*
167*7c478bd9Sstevel@tonic-gate  * putdev -a alias [attribute=value [...]]
168*7c478bd9Sstevel@tonic-gate  * putdev -m alias attribute=value [attribute=value [...]]
169*7c478bd9Sstevel@tonic-gate  * putdev -d alias [attribute [...]]
170*7c478bd9Sstevel@tonic-gate  *
171*7c478bd9Sstevel@tonic-gate  * 	Modify the device-table.  If -a specified, add a record for <alias>
172*7c478bd9Sstevel@tonic-gate  * 	to the table.  If -m specified, modify the attributes specified for
173*7c478bd9Sstevel@tonic-gate  *	the <device> specified.  If -d specified, remove the specified
174*7c478bd9Sstevel@tonic-gate  *	attributes from the specified device or remove the specified device.
175*7c478bd9Sstevel@tonic-gate  *
176*7c478bd9Sstevel@tonic-gate  * Options:
177*7c478bd9Sstevel@tonic-gate  *	-a		Add an alias description to the device table
178*7c478bd9Sstevel@tonic-gate  *	-m		Modify an existing device description
179*7c478bd9Sstevel@tonic-gate  *	-d		(if no attributes specified) remove the specified
180*7c478bd9Sstevel@tonic-gate  *			device from the device table, or (if attributes
181*7c478bd9Sstevel@tonic-gate  *			specified) remove the specified attributes from
182*7c478bd9Sstevel@tonic-gate  *			the specified device.
183*7c478bd9Sstevel@tonic-gate  *
184*7c478bd9Sstevel@tonic-gate  * Exit values:
185*7c478bd9Sstevel@tonic-gate  *	0		All went well
186*7c478bd9Sstevel@tonic-gate  *	1		Usage error (includes specifying "alias" as an
187*7c478bd9Sstevel@tonic-gate  *			<attribute>)
188*7c478bd9Sstevel@tonic-gate  *	2		The device table file could not be opened, read
189*7c478bd9Sstevel@tonic-gate  *			or modified
190*7c478bd9Sstevel@tonic-gate  *	3		If -a, the alias already exists.  Otherwise, the
191*7c478bd9Sstevel@tonic-gate  *			specified device does not exist in the table
192*7c478bd9Sstevel@tonic-gate  *	4		One of the specified attributes did not exist
193*7c478bd9Sstevel@tonic-gate  *			for the device and therefore wasn't removed
194*7c478bd9Sstevel@tonic-gate  */
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate main(argc, argv)
197*7c478bd9Sstevel@tonic-gate 	int	argc;			/* Argument count */
198*7c478bd9Sstevel@tonic-gate 	char   *argv[];			/* Argument list */
199*7c478bd9Sstevel@tonic-gate {
200*7c478bd9Sstevel@tonic-gate 	/* Automatic data */
201*7c478bd9Sstevel@tonic-gate 	char	      **plist;		/* Ptr to list of undef'nd attrs */
202*7c478bd9Sstevel@tonic-gate 	char	       *lbl;		/* Ptr to label for messages */
203*7c478bd9Sstevel@tonic-gate 	char	       *alias;		/* Ptr to <alias> on command-line */
204*7c478bd9Sstevel@tonic-gate 	char	       *device;		/* Ptr to <device> on command-line */
205*7c478bd9Sstevel@tonic-gate 	char	       *p;		/* Temp ptr to char */
206*7c478bd9Sstevel@tonic-gate 	int		noerr;		/* FLAG, TRUE if all's well */
207*7c478bd9Sstevel@tonic-gate 	int		a_seen;		/* TRUE if -a seen on command-line */
208*7c478bd9Sstevel@tonic-gate 	int		m_seen;		/* TRUE if -m seen on command-line */
209*7c478bd9Sstevel@tonic-gate 	int		d_seen;		/* TRUE if -a seen on command-line */
210*7c478bd9Sstevel@tonic-gate 	int		optchar;	/* Option extracted */
211*7c478bd9Sstevel@tonic-gate 	int		exitcd;		/* Value to return at exit */
212*7c478bd9Sstevel@tonic-gate 	int		nattrs;		/* Number of attributes on command */
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate 
215*7c478bd9Sstevel@tonic-gate 	/* Generate the label for messages */
216*7c478bd9Sstevel@tonic-gate 	lbl = mklbl(argv[0]);
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate 	/* Extract arguments - validate usage */
219*7c478bd9Sstevel@tonic-gate 	noerr = TRUE;
220*7c478bd9Sstevel@tonic-gate 	a_seen = FALSE;
221*7c478bd9Sstevel@tonic-gate 	m_seen = FALSE;
222*7c478bd9Sstevel@tonic-gate 	d_seen = FALSE;
223*7c478bd9Sstevel@tonic-gate 	opterr = FALSE;
224*7c478bd9Sstevel@tonic-gate 	while ((optchar = getopt(argc, argv, "a:d:m:")) != EOF) switch (optchar) {
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate 	case 'a':
227*7c478bd9Sstevel@tonic-gate 	    if (!(a_seen || m_seen || d_seen)) {
228*7c478bd9Sstevel@tonic-gate 		a_seen = TRUE;
229*7c478bd9Sstevel@tonic-gate 		alias = optarg;
230*7c478bd9Sstevel@tonic-gate 	    }
231*7c478bd9Sstevel@tonic-gate 	    else noerr = FALSE;
232*7c478bd9Sstevel@tonic-gate 	    break;
233*7c478bd9Sstevel@tonic-gate 
234*7c478bd9Sstevel@tonic-gate 	case 'd':
235*7c478bd9Sstevel@tonic-gate 	    if (!(a_seen || m_seen || d_seen)) {
236*7c478bd9Sstevel@tonic-gate 		d_seen = TRUE;
237*7c478bd9Sstevel@tonic-gate 		device = optarg;
238*7c478bd9Sstevel@tonic-gate 	    }
239*7c478bd9Sstevel@tonic-gate 	    else noerr = FALSE;
240*7c478bd9Sstevel@tonic-gate 	    break;
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate 	case 'm':
243*7c478bd9Sstevel@tonic-gate 	    if (!(a_seen || m_seen || d_seen)) {
244*7c478bd9Sstevel@tonic-gate 		m_seen = TRUE;
245*7c478bd9Sstevel@tonic-gate 		device = optarg;
246*7c478bd9Sstevel@tonic-gate 	    }
247*7c478bd9Sstevel@tonic-gate 	    else noerr = FALSE;
248*7c478bd9Sstevel@tonic-gate 	    break;
249*7c478bd9Sstevel@tonic-gate 
250*7c478bd9Sstevel@tonic-gate 	case '?':
251*7c478bd9Sstevel@tonic-gate 	default:
252*7c478bd9Sstevel@tonic-gate 	    noerr = FALSE;
253*7c478bd9Sstevel@tonic-gate 	}
254*7c478bd9Sstevel@tonic-gate 
255*7c478bd9Sstevel@tonic-gate 
256*7c478bd9Sstevel@tonic-gate 	/* Write a usage message if we've seen a blatant error */
257*7c478bd9Sstevel@tonic-gate 	if (!(a_seen || m_seen || d_seen) || !noerr) {
258*7c478bd9Sstevel@tonic-gate 	    stdmsg(MM_NRECOV, lbl, MM_ERROR, E_USAGE);
259*7c478bd9Sstevel@tonic-gate 	    exit(EX_ERROR);
260*7c478bd9Sstevel@tonic-gate 	}
261*7c478bd9Sstevel@tonic-gate 
262*7c478bd9Sstevel@tonic-gate 
263*7c478bd9Sstevel@tonic-gate 	/* Set up */
264*7c478bd9Sstevel@tonic-gate 	exitcd = EX_OK;
265*7c478bd9Sstevel@tonic-gate 	nattrs = argc - optind;
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 
268*7c478bd9Sstevel@tonic-gate 	/*  putdev -a alias [attr=value [...]] */
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 	if (a_seen) {
271*7c478bd9Sstevel@tonic-gate 
272*7c478bd9Sstevel@tonic-gate 	    /* Syntax check */
273*7c478bd9Sstevel@tonic-gate 	    if (nattrs < 0) {
274*7c478bd9Sstevel@tonic-gate 		stdmsg(MM_NRECOV, lbl, MM_ERROR, E_USAGE);
275*7c478bd9Sstevel@tonic-gate 		exitcd = EX_ERROR;
276*7c478bd9Sstevel@tonic-gate 	    } else {
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate 		/* Attempt to add the new alias */
279*7c478bd9Sstevel@tonic-gate 		if (!(_adddevtabrec(alias, &argv[optind]))) {
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate 		    /* Attempt failed.  Write appropriate error message. */
282*7c478bd9Sstevel@tonic-gate 
283*7c478bd9Sstevel@tonic-gate 		    switch(errno) {
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate 		    /*
286*7c478bd9Sstevel@tonic-gate 		     * EINVAL indicates that <alias> is not valid or "alias"
287*7c478bd9Sstevel@tonic-gate 		     * was mentioned as <attr> in <attr>=<value> pair.  If the
288*7c478bd9Sstevel@tonic-gate 		     * alias is a valid alias, assume that's the problem.
289*7c478bd9Sstevel@tonic-gate 		     */
290*7c478bd9Sstevel@tonic-gate 
291*7c478bd9Sstevel@tonic-gate 		    case EINVAL:
292*7c478bd9Sstevel@tonic-gate 			if (_validalias(alias))
293*7c478bd9Sstevel@tonic-gate 			    p = E_NOALIAS;
294*7c478bd9Sstevel@tonic-gate 			else (void) snprintf(p=msg, sizeof(msg), E_INVALIAS, alias);
295*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, p);
296*7c478bd9Sstevel@tonic-gate 			exitcd = EX_ERROR;
297*7c478bd9Sstevel@tonic-gate 			break;
298*7c478bd9Sstevel@tonic-gate 
299*7c478bd9Sstevel@tonic-gate 		    /*
300*7c478bd9Sstevel@tonic-gate 		     * EEXIST indicates that the alias <alias> already exists
301*7c478bd9Sstevel@tonic-gate 		     * in the device table.
302*7c478bd9Sstevel@tonic-gate 		     */
303*7c478bd9Sstevel@tonic-gate 
304*7c478bd9Sstevel@tonic-gate 		    case EEXIST:
305*7c478bd9Sstevel@tonic-gate 			(void) snprintf(msg, sizeof(msg), E_ALIASIS, alias);
306*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
307*7c478bd9Sstevel@tonic-gate 			exitcd = EX_EXISTS;
308*7c478bd9Sstevel@tonic-gate 			break;
309*7c478bd9Sstevel@tonic-gate 
310*7c478bd9Sstevel@tonic-gate 		    /*
311*7c478bd9Sstevel@tonic-gate 		     * EACCES and ENOENT indicate problems reading or writing
312*7c478bd9Sstevel@tonic-gate 		     * the device table.
313*7c478bd9Sstevel@tonic-gate 		     */
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate 		    case EACCES:
316*7c478bd9Sstevel@tonic-gate 		    case ENOENT:
317*7c478bd9Sstevel@tonic-gate 	                p = _devtabpath();
318*7c478bd9Sstevel@tonic-gate 			if (access(p, R_OK) == 0)
319*7c478bd9Sstevel@tonic-gate 			    (void) snprintf(msg, sizeof(msg), E_NOMKDTAB, p);
320*7c478bd9Sstevel@tonic-gate 			else
321*7c478bd9Sstevel@tonic-gate 			    (void) snprintf(msg, sizeof(msg), E_NODEVTAB, p);
322*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
323*7c478bd9Sstevel@tonic-gate 			exitcd = EX_DEVTAB;
324*7c478bd9Sstevel@tonic-gate 			break;
325*7c478bd9Sstevel@tonic-gate 
326*7c478bd9Sstevel@tonic-gate 		    /*
327*7c478bd9Sstevel@tonic-gate 		     * EAGAIN indicates that an attribute was defined on the
328*7c478bd9Sstevel@tonic-gate 		     * command line more than once.
329*7c478bd9Sstevel@tonic-gate 		     */
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate 		    case EAGAIN:
332*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, E_MULTIPLE);
333*7c478bd9Sstevel@tonic-gate 			exitcd = EX_ERROR;
334*7c478bd9Sstevel@tonic-gate 			break;
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate 		    /*
337*7c478bd9Sstevel@tonic-gate 		     * ENXIO indicates that a relative pathname was supplied
338*7c478bd9Sstevel@tonic-gate 		     * for the cdevice, bdevice or pathname attributes.  Full
339*7c478bd9Sstevel@tonic-gate 		     * pathnames are required for these attributes.
340*7c478bd9Sstevel@tonic-gate 		     */
341*7c478bd9Sstevel@tonic-gate 		    case ENXIO:
342*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, E_RELPATH);
343*7c478bd9Sstevel@tonic-gate 			exitcd = EX_RELPATH;
344*7c478bd9Sstevel@tonic-gate 			break;
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 		    /*
347*7c478bd9Sstevel@tonic-gate 		     * Some other problem (odd?)
348*7c478bd9Sstevel@tonic-gate 		     */
349*7c478bd9Sstevel@tonic-gate 
350*7c478bd9Sstevel@tonic-gate 		    default:
351*7c478bd9Sstevel@tonic-gate 			(void) sprintf(msg, E_INTERNAL, errno);
352*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
353*7c478bd9Sstevel@tonic-gate 			exitcd = EX_ERROR;
354*7c478bd9Sstevel@tonic-gate 		    }
355*7c478bd9Sstevel@tonic-gate 		}
356*7c478bd9Sstevel@tonic-gate 	    }
357*7c478bd9Sstevel@tonic-gate 	}   /* End -a case */
358*7c478bd9Sstevel@tonic-gate 
359*7c478bd9Sstevel@tonic-gate 
360*7c478bd9Sstevel@tonic-gate 	/* putdev -m device attr=value [...] */
361*7c478bd9Sstevel@tonic-gate 
362*7c478bd9Sstevel@tonic-gate 	else if (m_seen) {
363*7c478bd9Sstevel@tonic-gate 
364*7c478bd9Sstevel@tonic-gate 	    /* Check usage */
365*7c478bd9Sstevel@tonic-gate 
366*7c478bd9Sstevel@tonic-gate 	    if (nattrs <= 0) {
367*7c478bd9Sstevel@tonic-gate 		stdmsg(MM_NRECOV, lbl, MM_ERROR, E_USAGE);
368*7c478bd9Sstevel@tonic-gate 		exitcd = EX_ERROR;
369*7c478bd9Sstevel@tonic-gate 	    } else {
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate 		/* Attempt to modify a device's record */
372*7c478bd9Sstevel@tonic-gate 		if (!(_moddevtabrec(device, &argv[optind]))) {
373*7c478bd9Sstevel@tonic-gate 
374*7c478bd9Sstevel@tonic-gate 		    /* Modification attempt failed */
375*7c478bd9Sstevel@tonic-gate 
376*7c478bd9Sstevel@tonic-gate 		    switch(errno) {
377*7c478bd9Sstevel@tonic-gate 
378*7c478bd9Sstevel@tonic-gate 		    /*
379*7c478bd9Sstevel@tonic-gate 		     * EINVAL indicates that "alias" was used as an attribute
380*7c478bd9Sstevel@tonic-gate 		     * in an <attr>=<value> pair.
381*7c478bd9Sstevel@tonic-gate 		     */
382*7c478bd9Sstevel@tonic-gate 
383*7c478bd9Sstevel@tonic-gate 		    case EINVAL:
384*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, E_NOALIAS);
385*7c478bd9Sstevel@tonic-gate 			exitcd = EX_ERROR;
386*7c478bd9Sstevel@tonic-gate 			break;
387*7c478bd9Sstevel@tonic-gate 
388*7c478bd9Sstevel@tonic-gate 		    /*
389*7c478bd9Sstevel@tonic-gate 		     * ENODEV indicates that the device that was to
390*7c478bd9Sstevel@tonic-gate 		     * be modified doesn't exist.
391*7c478bd9Sstevel@tonic-gate 		     */
392*7c478bd9Sstevel@tonic-gate 
393*7c478bd9Sstevel@tonic-gate 		    case ENODEV:
394*7c478bd9Sstevel@tonic-gate 			(void) snprintf(msg, sizeof(msg), E_NODEV, device);
395*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
396*7c478bd9Sstevel@tonic-gate 			exitcd = EX_EXISTS;
397*7c478bd9Sstevel@tonic-gate 			break;
398*7c478bd9Sstevel@tonic-gate 
399*7c478bd9Sstevel@tonic-gate 		    /*
400*7c478bd9Sstevel@tonic-gate 		     * ENOENT indicates that the device-table doesn't exist.
401*7c478bd9Sstevel@tonic-gate 		     */
402*7c478bd9Sstevel@tonic-gate 
403*7c478bd9Sstevel@tonic-gate 		    case ENOENT:
404*7c478bd9Sstevel@tonic-gate 			(void) snprintf(msg, sizeof(msg), E_NODEVTAB, _devtabpath());
405*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
406*7c478bd9Sstevel@tonic-gate 			exitcd = EX_DEVTAB;
407*7c478bd9Sstevel@tonic-gate 			break;
408*7c478bd9Sstevel@tonic-gate 
409*7c478bd9Sstevel@tonic-gate 		    /*
410*7c478bd9Sstevel@tonic-gate 		     * EACCES indicates that there was a problem reading the
411*7c478bd9Sstevel@tonic-gate 		     * old device table or creating the new table.  If the
412*7c478bd9Sstevel@tonic-gate 		     * old table is readable, assume that we can't create the
413*7c478bd9Sstevel@tonic-gate 		     * new table.  Otherwise, assume that the old table isn't
414*7c478bd9Sstevel@tonic-gate 		     * accessible.
415*7c478bd9Sstevel@tonic-gate 		     */
416*7c478bd9Sstevel@tonic-gate 
417*7c478bd9Sstevel@tonic-gate 		    case EACCES:
418*7c478bd9Sstevel@tonic-gate 	                p = _devtabpath();
419*7c478bd9Sstevel@tonic-gate 			if (access(p, R_OK) == 0)
420*7c478bd9Sstevel@tonic-gate 			    (void) snprintf(msg, sizeof(msg), E_NOMKDTAB, p);
421*7c478bd9Sstevel@tonic-gate 			else
422*7c478bd9Sstevel@tonic-gate 			    (void) snprintf(msg, sizeof(msg), E_NODEVTAB, p);
423*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
424*7c478bd9Sstevel@tonic-gate 			exitcd = EX_DEVTAB;
425*7c478bd9Sstevel@tonic-gate 			break;
426*7c478bd9Sstevel@tonic-gate 
427*7c478bd9Sstevel@tonic-gate 		    /*
428*7c478bd9Sstevel@tonic-gate 		     * EAGAIN indicates that an attribute was specified more than
429*7c478bd9Sstevel@tonic-gate 		     * once on the command line.
430*7c478bd9Sstevel@tonic-gate 		     */
431*7c478bd9Sstevel@tonic-gate 
432*7c478bd9Sstevel@tonic-gate 		    case EAGAIN:
433*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, E_MULTIPLE);
434*7c478bd9Sstevel@tonic-gate 			exitcd = EX_ERROR;
435*7c478bd9Sstevel@tonic-gate 			break;
436*7c478bd9Sstevel@tonic-gate 
437*7c478bd9Sstevel@tonic-gate 		    /*
438*7c478bd9Sstevel@tonic-gate 		     * ENXIO indicates that a relative pathname was supplied
439*7c478bd9Sstevel@tonic-gate 		     * for the cdevice, bdevice or pathname attributes.  Full
440*7c478bd9Sstevel@tonic-gate 		     * pathnames are required for these attributes.
441*7c478bd9Sstevel@tonic-gate 		     */
442*7c478bd9Sstevel@tonic-gate 		    case ENXIO:
443*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, E_RELPATH);
444*7c478bd9Sstevel@tonic-gate 			exitcd = EX_RELPATH;
445*7c478bd9Sstevel@tonic-gate 			break;
446*7c478bd9Sstevel@tonic-gate 
447*7c478bd9Sstevel@tonic-gate 		    /*
448*7c478bd9Sstevel@tonic-gate 		     * Some strange problem...
449*7c478bd9Sstevel@tonic-gate 		     */
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate 		    default:
452*7c478bd9Sstevel@tonic-gate 			(void) sprintf(msg, E_INTERNAL, errno);
453*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
454*7c478bd9Sstevel@tonic-gate 			exitcd = EX_ERROR;
455*7c478bd9Sstevel@tonic-gate 		    }
456*7c478bd9Sstevel@tonic-gate 		}
457*7c478bd9Sstevel@tonic-gate 	    }
458*7c478bd9Sstevel@tonic-gate 	}   /* End -m case */
459*7c478bd9Sstevel@tonic-gate 
460*7c478bd9Sstevel@tonic-gate 	else if (d_seen) {
461*7c478bd9Sstevel@tonic-gate 
462*7c478bd9Sstevel@tonic-gate 	    /* putdev -d device [attr [...]] */
463*7c478bd9Sstevel@tonic-gate 
464*7c478bd9Sstevel@tonic-gate 	    /* Check usage */
465*7c478bd9Sstevel@tonic-gate 	    if (nattrs < 0) {
466*7c478bd9Sstevel@tonic-gate 		stdmsg(MM_NRECOV, lbl, MM_ERROR, E_USAGE);
467*7c478bd9Sstevel@tonic-gate 		exitcd = EX_ERROR;
468*7c478bd9Sstevel@tonic-gate 	    } else {
469*7c478bd9Sstevel@tonic-gate 
470*7c478bd9Sstevel@tonic-gate 		/*
471*7c478bd9Sstevel@tonic-gate 		 * Determine case (removing a device or attributes
472*7c478bd9Sstevel@tonic-gate 		 * to a device.
473*7c478bd9Sstevel@tonic-gate 		 */
474*7c478bd9Sstevel@tonic-gate 
475*7c478bd9Sstevel@tonic-gate 		if (nattrs == 0) {
476*7c478bd9Sstevel@tonic-gate 
477*7c478bd9Sstevel@tonic-gate 		    /* putdev -d device */
478*7c478bd9Sstevel@tonic-gate 
479*7c478bd9Sstevel@tonic-gate 		    /* Attempt to remove the specified device */
480*7c478bd9Sstevel@tonic-gate 		    if (!(_rmdevtabrec(device))) switch(errno) {
481*7c478bd9Sstevel@tonic-gate 
482*7c478bd9Sstevel@tonic-gate 			/*
483*7c478bd9Sstevel@tonic-gate 			 * ENODEV indicates that the named device is not
484*7c478bd9Sstevel@tonic-gate 			 * defined in the device table.
485*7c478bd9Sstevel@tonic-gate 			 */
486*7c478bd9Sstevel@tonic-gate 
487*7c478bd9Sstevel@tonic-gate 		    case ENODEV:
488*7c478bd9Sstevel@tonic-gate 			(void) snprintf(msg, sizeof(msg), E_NODEV, device);
489*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
490*7c478bd9Sstevel@tonic-gate 			exitcd = EX_EXISTS;
491*7c478bd9Sstevel@tonic-gate 			break;
492*7c478bd9Sstevel@tonic-gate 
493*7c478bd9Sstevel@tonic-gate 			/*
494*7c478bd9Sstevel@tonic-gate 			 * ENOENT indicates that the device table can't
495*7c478bd9Sstevel@tonic-gate 			 * be found.
496*7c478bd9Sstevel@tonic-gate 			 */
497*7c478bd9Sstevel@tonic-gate 
498*7c478bd9Sstevel@tonic-gate 		    case ENOENT:
499*7c478bd9Sstevel@tonic-gate 			(void) snprintf(msg, sizeof(msg), E_NODEVTAB, _devtabpath());
500*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
501*7c478bd9Sstevel@tonic-gate 			exitcd = EX_DEVTAB;
502*7c478bd9Sstevel@tonic-gate 			break;
503*7c478bd9Sstevel@tonic-gate 
504*7c478bd9Sstevel@tonic-gate 			/*
505*7c478bd9Sstevel@tonic-gate 			 * EACCES indicates that there was a problem reading the
506*7c478bd9Sstevel@tonic-gate 			 * old device table or creating the new table.  If the
507*7c478bd9Sstevel@tonic-gate 			 * old table is readable, assume that we can't create the
508*7c478bd9Sstevel@tonic-gate 			 * new table.  Otherwise, assume that the old table isn't
509*7c478bd9Sstevel@tonic-gate 			 * accessible.
510*7c478bd9Sstevel@tonic-gate 			 */
511*7c478bd9Sstevel@tonic-gate 
512*7c478bd9Sstevel@tonic-gate 		    case EACCES:
513*7c478bd9Sstevel@tonic-gate 			p = _devtabpath();
514*7c478bd9Sstevel@tonic-gate 			if (access(p, R_OK) == 0)
515*7c478bd9Sstevel@tonic-gate 			    (void) snprintf(msg, sizeof(msg), E_NOMKDTAB, p);
516*7c478bd9Sstevel@tonic-gate 			else
517*7c478bd9Sstevel@tonic-gate 			    (void) snprintf(msg, sizeof(msg), E_NODEVTAB, p);
518*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
519*7c478bd9Sstevel@tonic-gate 			exitcd = EX_DEVTAB;
520*7c478bd9Sstevel@tonic-gate 			break;
521*7c478bd9Sstevel@tonic-gate 
522*7c478bd9Sstevel@tonic-gate 			/*
523*7c478bd9Sstevel@tonic-gate 			 * Some strange problem...
524*7c478bd9Sstevel@tonic-gate 			 */
525*7c478bd9Sstevel@tonic-gate 
526*7c478bd9Sstevel@tonic-gate 		    default:
527*7c478bd9Sstevel@tonic-gate 			(void) sprintf(msg, E_INTERNAL, errno);
528*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
529*7c478bd9Sstevel@tonic-gate 			exitcd = EX_ERROR;
530*7c478bd9Sstevel@tonic-gate 
531*7c478bd9Sstevel@tonic-gate 		    }   /* End switch */
532*7c478bd9Sstevel@tonic-gate 		}
533*7c478bd9Sstevel@tonic-gate 		else {
534*7c478bd9Sstevel@tonic-gate 
535*7c478bd9Sstevel@tonic-gate 		    /* putdev -d device attr [attr [...]] */
536*7c478bd9Sstevel@tonic-gate 
537*7c478bd9Sstevel@tonic-gate 		    /*
538*7c478bd9Sstevel@tonic-gate 		     * Attempt to remove the specified attributes from the
539*7c478bd9Sstevel@tonic-gate 		     * specified device.
540*7c478bd9Sstevel@tonic-gate 		     */
541*7c478bd9Sstevel@tonic-gate 		    if (!(_rmdevtabattrs(device, &argv[optind], &plist))) switch(errno) {
542*7c478bd9Sstevel@tonic-gate 
543*7c478bd9Sstevel@tonic-gate 			/*
544*7c478bd9Sstevel@tonic-gate 			 * EINVAL indicates that a named attribute was not
545*7c478bd9Sstevel@tonic-gate 			 * defined for the specified device or "alias" was
546*7c478bd9Sstevel@tonic-gate 			 * requested.  If "plist" points to a list of attrs,
547*7c478bd9Sstevel@tonic-gate 			 * the former is the problem.  Otherwise, the latter
548*7c478bd9Sstevel@tonic-gate 			 * is the problem.
549*7c478bd9Sstevel@tonic-gate 			 */
550*7c478bd9Sstevel@tonic-gate 
551*7c478bd9Sstevel@tonic-gate 		    case EINVAL:
552*7c478bd9Sstevel@tonic-gate 			if (plist) {
553*7c478bd9Sstevel@tonic-gate 			    exitcd = EX_ATTRIB;
554*7c478bd9Sstevel@tonic-gate 			    for (; *plist; plist++) {
555*7c478bd9Sstevel@tonic-gate 				(void) snprintf(msg, sizeof(msg), E_NOATTR, *plist);
556*7c478bd9Sstevel@tonic-gate 				stdmsg(MM_RECOVER, lbl, MM_WARNING, msg);
557*7c478bd9Sstevel@tonic-gate 			    }
558*7c478bd9Sstevel@tonic-gate 			} else {
559*7c478bd9Sstevel@tonic-gate 			    stdmsg(MM_NRECOV, lbl, MM_ERROR, E_NOALIAS);
560*7c478bd9Sstevel@tonic-gate 			    exitcd = EX_ERROR;
561*7c478bd9Sstevel@tonic-gate 			}
562*7c478bd9Sstevel@tonic-gate 			break;
563*7c478bd9Sstevel@tonic-gate 
564*7c478bd9Sstevel@tonic-gate 			/*
565*7c478bd9Sstevel@tonic-gate 			 * ENODEV indicates that the named device is not
566*7c478bd9Sstevel@tonic-gate 			 * defined in the device table.
567*7c478bd9Sstevel@tonic-gate 			 */
568*7c478bd9Sstevel@tonic-gate 
569*7c478bd9Sstevel@tonic-gate 		    case ENODEV:
570*7c478bd9Sstevel@tonic-gate 			(void) snprintf(msg, sizeof(msg), E_NODEV, device);
571*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
572*7c478bd9Sstevel@tonic-gate 			exitcd = EX_EXISTS;
573*7c478bd9Sstevel@tonic-gate 			break;
574*7c478bd9Sstevel@tonic-gate 
575*7c478bd9Sstevel@tonic-gate 			/*
576*7c478bd9Sstevel@tonic-gate 			 * ENOENT indicates that the device table can't
577*7c478bd9Sstevel@tonic-gate 			 * be found.
578*7c478bd9Sstevel@tonic-gate 			 */
579*7c478bd9Sstevel@tonic-gate 
580*7c478bd9Sstevel@tonic-gate 		    case ENOENT:
581*7c478bd9Sstevel@tonic-gate 			(void) snprintf(msg, sizeof(msg), E_NODEVTAB, _devtabpath());
582*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
583*7c478bd9Sstevel@tonic-gate 			exitcd = EX_DEVTAB;
584*7c478bd9Sstevel@tonic-gate 			break;
585*7c478bd9Sstevel@tonic-gate 
586*7c478bd9Sstevel@tonic-gate 			/*
587*7c478bd9Sstevel@tonic-gate 			 * EACCES indicates that there was a problem reading the
588*7c478bd9Sstevel@tonic-gate 			 * old device table or creating the new table.  If the
589*7c478bd9Sstevel@tonic-gate 			 * old table is readable, assume that we can't create the
590*7c478bd9Sstevel@tonic-gate 			 * new table.  Otherwise, assume that the old table isn't
591*7c478bd9Sstevel@tonic-gate 			 * accessible.
592*7c478bd9Sstevel@tonic-gate 			 */
593*7c478bd9Sstevel@tonic-gate 
594*7c478bd9Sstevel@tonic-gate 		    case EACCES:
595*7c478bd9Sstevel@tonic-gate 			p = _devtabpath();
596*7c478bd9Sstevel@tonic-gate 			if (access(p, R_OK) == 0)
597*7c478bd9Sstevel@tonic-gate 			    (void) snprintf(msg, sizeof(msg), E_NOMKDTAB, p);
598*7c478bd9Sstevel@tonic-gate 			else
599*7c478bd9Sstevel@tonic-gate 			    (void) snprintf(msg, sizeof(msg), E_NODEVTAB, p);
600*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
601*7c478bd9Sstevel@tonic-gate 			exitcd = EX_DEVTAB;
602*7c478bd9Sstevel@tonic-gate 			break;
603*7c478bd9Sstevel@tonic-gate 
604*7c478bd9Sstevel@tonic-gate 			/*
605*7c478bd9Sstevel@tonic-gate 			 * Some strange problem...
606*7c478bd9Sstevel@tonic-gate 			 */
607*7c478bd9Sstevel@tonic-gate 
608*7c478bd9Sstevel@tonic-gate 		    default:
609*7c478bd9Sstevel@tonic-gate 			(void) sprintf(msg, E_INTERNAL, errno);
610*7c478bd9Sstevel@tonic-gate 			stdmsg(MM_NRECOV, lbl, MM_ERROR, msg);
611*7c478bd9Sstevel@tonic-gate 			exitcd = EX_ERROR;
612*7c478bd9Sstevel@tonic-gate 
613*7c478bd9Sstevel@tonic-gate 		    }  /* End switch */
614*7c478bd9Sstevel@tonic-gate 
615*7c478bd9Sstevel@tonic-gate 		}   /* End "putdev -d device attr [...]" case */
616*7c478bd9Sstevel@tonic-gate 
617*7c478bd9Sstevel@tonic-gate 	    }   /* End passes usage-check case */
618*7c478bd9Sstevel@tonic-gate 
619*7c478bd9Sstevel@tonic-gate 	}   /* End -d case */
620*7c478bd9Sstevel@tonic-gate 
621*7c478bd9Sstevel@tonic-gate 
622*7c478bd9Sstevel@tonic-gate 	/* Done.  Return exit code (determined above) */
623*7c478bd9Sstevel@tonic-gate 	return(exitcd);
624*7c478bd9Sstevel@tonic-gate }  /* main() */
625