xref: /titanic_53/usr/src/cmd/allocate/allocate.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 1992-2002 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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <errno.h>
30*7c478bd9Sstevel@tonic-gate #include <locale.h>
31*7c478bd9Sstevel@tonic-gate #include <pwd.h>
32*7c478bd9Sstevel@tonic-gate #include <unistd.h>
33*7c478bd9Sstevel@tonic-gate #include <stdio.h>
34*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
35*7c478bd9Sstevel@tonic-gate #include <string.h>
36*7c478bd9Sstevel@tonic-gate 
37*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate #include "allocate.h"
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
42*7c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SUNW_OST_OSCMD"
43*7c478bd9Sstevel@tonic-gate #endif
44*7c478bd9Sstevel@tonic-gate 
45*7c478bd9Sstevel@tonic-gate extern void audit_allocate_argv(int, int, char *[]);
46*7c478bd9Sstevel@tonic-gate extern int audit_allocate_record(int);
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate static void
49*7c478bd9Sstevel@tonic-gate usage(int func)
50*7c478bd9Sstevel@tonic-gate {
51*7c478bd9Sstevel@tonic-gate 	char *use[5];
52*7c478bd9Sstevel@tonic-gate 
53*7c478bd9Sstevel@tonic-gate 	use[0] = gettext("allocate [-s] [-U uname] [-F] device");
54*7c478bd9Sstevel@tonic-gate 	use[1] = gettext("allocate [-s] [-U uname] -g dev_type");
55*7c478bd9Sstevel@tonic-gate 	use[2] = gettext("deallocate [-s] [-F] device");
56*7c478bd9Sstevel@tonic-gate 	use[3] = gettext("deallocate [-s] [-I]");
57*7c478bd9Sstevel@tonic-gate 	use[4] = gettext("list_devices [-s] [-U uname] {-l|-n|-u} [device]");
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate 	switch (func) {
60*7c478bd9Sstevel@tonic-gate 		case 0:
61*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n%s\n", use[0], use[1]);
62*7c478bd9Sstevel@tonic-gate 			break;
63*7c478bd9Sstevel@tonic-gate 		case 1:
64*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n%s\n", use[2], use[3]);
65*7c478bd9Sstevel@tonic-gate 			break;
66*7c478bd9Sstevel@tonic-gate 		case 2:
67*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n", use[4]);
68*7c478bd9Sstevel@tonic-gate 			break;
69*7c478bd9Sstevel@tonic-gate 		default:
70*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
71*7c478bd9Sstevel@tonic-gate 				use[0], use[1], use[2], use[3], use[4]);
72*7c478bd9Sstevel@tonic-gate 	}
73*7c478bd9Sstevel@tonic-gate }
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate static void
76*7c478bd9Sstevel@tonic-gate print_error(int error, char *name)
77*7c478bd9Sstevel@tonic-gate {
78*7c478bd9Sstevel@tonic-gate 	char *msg;
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate 	switch (error) {
81*7c478bd9Sstevel@tonic-gate 	case SYSERROR:
82*7c478bd9Sstevel@tonic-gate 		msg = gettext("Unknown System error.");
83*7c478bd9Sstevel@tonic-gate 		break;
84*7c478bd9Sstevel@tonic-gate 	case IMPORT_ERR:
85*7c478bd9Sstevel@tonic-gate 		msg = gettext(
86*7c478bd9Sstevel@tonic-gate 		    "User lacks authorization required for this operation.");
87*7c478bd9Sstevel@tonic-gate 		break;
88*7c478bd9Sstevel@tonic-gate 	case NODAENT:
89*7c478bd9Sstevel@tonic-gate 		msg = gettext(
90*7c478bd9Sstevel@tonic-gate 		    "No device allocate file entry for specified device.");
91*7c478bd9Sstevel@tonic-gate 		break;
92*7c478bd9Sstevel@tonic-gate 	case NODMAPENT:
93*7c478bd9Sstevel@tonic-gate 		msg = gettext(
94*7c478bd9Sstevel@tonic-gate 		    "No device maps file entry for specified device.");
95*7c478bd9Sstevel@tonic-gate 		break;
96*7c478bd9Sstevel@tonic-gate 	case DACLCK:
97*7c478bd9Sstevel@tonic-gate 		msg = gettext("Concurrent operations for specified device, "
98*7c478bd9Sstevel@tonic-gate 		    "try later.");
99*7c478bd9Sstevel@tonic-gate 		break;
100*7c478bd9Sstevel@tonic-gate 	case DACACC:
101*7c478bd9Sstevel@tonic-gate 		msg = gettext(
102*7c478bd9Sstevel@tonic-gate 		    "Can't access DAC file for the device specified.");
103*7c478bd9Sstevel@tonic-gate 		break;
104*7c478bd9Sstevel@tonic-gate 	case DEVLST:
105*7c478bd9Sstevel@tonic-gate 		msg = gettext(
106*7c478bd9Sstevel@tonic-gate 		    "Could not use device list for the device specified.");
107*7c478bd9Sstevel@tonic-gate 		break;
108*7c478bd9Sstevel@tonic-gate 	case NALLOCU:
109*7c478bd9Sstevel@tonic-gate 		msg = gettext("Specified device is allocated to another user.");
110*7c478bd9Sstevel@tonic-gate 		break;
111*7c478bd9Sstevel@tonic-gate 	case NOTAUTH:
112*7c478bd9Sstevel@tonic-gate 		msg = gettext("Not authorized for specified operation.");
113*7c478bd9Sstevel@tonic-gate 		break;
114*7c478bd9Sstevel@tonic-gate 	case CNTFRC:
115*7c478bd9Sstevel@tonic-gate 		msg = gettext("Can't force deallocate specified device.");
116*7c478bd9Sstevel@tonic-gate 		break;
117*7c478bd9Sstevel@tonic-gate 	case CNTDEXEC:
118*7c478bd9Sstevel@tonic-gate 		msg = gettext(
119*7c478bd9Sstevel@tonic-gate 		    "Can't exec device-clean program for specified device.");
120*7c478bd9Sstevel@tonic-gate 		break;
121*7c478bd9Sstevel@tonic-gate 	case NO_DEVICE:
122*7c478bd9Sstevel@tonic-gate 		msg = gettext(
123*7c478bd9Sstevel@tonic-gate 		    "Can't find a device of type requested to allocate.");
124*7c478bd9Sstevel@tonic-gate 		break;
125*7c478bd9Sstevel@tonic-gate 	case DSPMISS:
126*7c478bd9Sstevel@tonic-gate 		msg = gettext(
127*7c478bd9Sstevel@tonic-gate 		    "Device special file(s) missing for specified device.");
128*7c478bd9Sstevel@tonic-gate 		break;
129*7c478bd9Sstevel@tonic-gate 	case ALLOCERR:
130*7c478bd9Sstevel@tonic-gate 		msg = gettext("Device specified is in allocate error state.");
131*7c478bd9Sstevel@tonic-gate 		break;
132*7c478bd9Sstevel@tonic-gate 	case CHOWN_PERR:
133*7c478bd9Sstevel@tonic-gate 		msg = gettext("Process lacks privilege required to chown().");
134*7c478bd9Sstevel@tonic-gate 		break;
135*7c478bd9Sstevel@tonic-gate 	case ALLOC:
136*7c478bd9Sstevel@tonic-gate 		msg = gettext("Device already allocated.");
137*7c478bd9Sstevel@tonic-gate 		break;
138*7c478bd9Sstevel@tonic-gate 	case ALLOC_OTHER:
139*7c478bd9Sstevel@tonic-gate 		msg = gettext("Device allocated to another user.");
140*7c478bd9Sstevel@tonic-gate 		break;
141*7c478bd9Sstevel@tonic-gate 	case NALLOC:
142*7c478bd9Sstevel@tonic-gate 		msg = gettext("Device not allocated.");
143*7c478bd9Sstevel@tonic-gate 		break;
144*7c478bd9Sstevel@tonic-gate 	case AUTHERR:
145*7c478bd9Sstevel@tonic-gate 		msg = gettext("Device not allocatable.");
146*7c478bd9Sstevel@tonic-gate 		break;
147*7c478bd9Sstevel@tonic-gate 	case CLEAN_ERR:
148*7c478bd9Sstevel@tonic-gate 		msg = gettext("Unable to clean up the device.");
149*7c478bd9Sstevel@tonic-gate 		break;
150*7c478bd9Sstevel@tonic-gate 	case SETACL_PERR:
151*7c478bd9Sstevel@tonic-gate 		msg = gettext("Process lacks privilege required to set ACL.");
152*7c478bd9Sstevel@tonic-gate 		break;
153*7c478bd9Sstevel@tonic-gate 	case DEVNAME_ERR:
154*7c478bd9Sstevel@tonic-gate 		msg = gettext("Error forming device name.");
155*7c478bd9Sstevel@tonic-gate 		break;
156*7c478bd9Sstevel@tonic-gate 	case DEVNAME_TOOLONG:
157*7c478bd9Sstevel@tonic-gate 		msg = gettext("Device name is too long.");
158*7c478bd9Sstevel@tonic-gate 		break;
159*7c478bd9Sstevel@tonic-gate 	default:
160*7c478bd9Sstevel@tonic-gate 		msg = gettext("Unknown error code.");
161*7c478bd9Sstevel@tonic-gate 		break;
162*7c478bd9Sstevel@tonic-gate 	}
163*7c478bd9Sstevel@tonic-gate 
164*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: %s\n", name, msg);
165*7c478bd9Sstevel@tonic-gate 	(void) fflush(stderr);
166*7c478bd9Sstevel@tonic-gate }
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate char *newenv[] = {"PATH=/usr/bin:/usr/sbin",
169*7c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_ALL		*/
170*7c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_COLLATE	*/
171*7c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_CTYPE		*/
172*7c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_MESSAGES	*/
173*7c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_NUMERIC	*/
174*7c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_TIME		*/
175*7c478bd9Sstevel@tonic-gate 			NULL,			/* for LANG		*/
176*7c478bd9Sstevel@tonic-gate 			NULL
177*7c478bd9Sstevel@tonic-gate };
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate static char *
180*7c478bd9Sstevel@tonic-gate getenvent(char *name, char *env[])
181*7c478bd9Sstevel@tonic-gate {
182*7c478bd9Sstevel@tonic-gate 	for (; *env != NULL; env++) {
183*7c478bd9Sstevel@tonic-gate 		if (strncmp(*env, name, strlen(name)) == 0)
184*7c478bd9Sstevel@tonic-gate 			return (*env);
185*7c478bd9Sstevel@tonic-gate 	}
186*7c478bd9Sstevel@tonic-gate 	return (NULL);
187*7c478bd9Sstevel@tonic-gate }
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate int
190*7c478bd9Sstevel@tonic-gate main(int argc, char *argv[], char *envp[])
191*7c478bd9Sstevel@tonic-gate {
192*7c478bd9Sstevel@tonic-gate 	char	*name, *env;
193*7c478bd9Sstevel@tonic-gate 	int	func = -1, optflg = 0, errflg = 0, error = 0, c;
194*7c478bd9Sstevel@tonic-gate 	uid_t	uid = getuid();
195*7c478bd9Sstevel@tonic-gate 	char	*uname = NULL, *device = NULL;
196*7c478bd9Sstevel@tonic-gate 	struct passwd *pw_ent;
197*7c478bd9Sstevel@tonic-gate 	int env_num = 1;	/* PATH= is 0 entry */
198*7c478bd9Sstevel@tonic-gate 
199*7c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
200*7c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate 	/*
203*7c478bd9Sstevel@tonic-gate 	 * get all enviroment variables
204*7c478bd9Sstevel@tonic-gate 	 * which affect on internationalization.
205*7c478bd9Sstevel@tonic-gate 	 */
206*7c478bd9Sstevel@tonic-gate 	env = getenvent("LC_ALL=", envp);
207*7c478bd9Sstevel@tonic-gate 	if (env != NULL)
208*7c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
209*7c478bd9Sstevel@tonic-gate 	env = getenvent("LC_COLLATE=", envp);
210*7c478bd9Sstevel@tonic-gate 	if (env != NULL)
211*7c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
212*7c478bd9Sstevel@tonic-gate 	env = getenvent("LC_CTYPE=", envp);
213*7c478bd9Sstevel@tonic-gate 	if (env != NULL)
214*7c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
215*7c478bd9Sstevel@tonic-gate 	env = getenvent("LC_MESSAGES=", envp);
216*7c478bd9Sstevel@tonic-gate 	if (env != NULL)
217*7c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
218*7c478bd9Sstevel@tonic-gate 	env = getenvent("LC_NUMERIC=", envp);
219*7c478bd9Sstevel@tonic-gate 	if (env != NULL)
220*7c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
221*7c478bd9Sstevel@tonic-gate 	env = getenvent("LC_TIME=", envp);
222*7c478bd9Sstevel@tonic-gate 	if (env != NULL)
223*7c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
224*7c478bd9Sstevel@tonic-gate 	env = getenvent("LANG=", envp);
225*7c478bd9Sstevel@tonic-gate 	if (env != NULL)
226*7c478bd9Sstevel@tonic-gate 		newenv[env_num] = env;
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 	if ((name = strrchr(argv[0], '/')) == NULL)
229*7c478bd9Sstevel@tonic-gate 		name = argv[0];
230*7c478bd9Sstevel@tonic-gate 	else
231*7c478bd9Sstevel@tonic-gate 		name++;
232*7c478bd9Sstevel@tonic-gate 
233*7c478bd9Sstevel@tonic-gate 	if (strcmp(name, "allocate") == 0)
234*7c478bd9Sstevel@tonic-gate 		func = 0;
235*7c478bd9Sstevel@tonic-gate 	else if (strcmp(name, "deallocate") == 0)
236*7c478bd9Sstevel@tonic-gate 		func = 1;
237*7c478bd9Sstevel@tonic-gate 	else if (strcmp(name, "list_devices") == 0)
238*7c478bd9Sstevel@tonic-gate 		func = 2;
239*7c478bd9Sstevel@tonic-gate 	else {
240*7c478bd9Sstevel@tonic-gate 		usage(ALL);
241*7c478bd9Sstevel@tonic-gate 		exit(1);
242*7c478bd9Sstevel@tonic-gate 	}
243*7c478bd9Sstevel@tonic-gate 
244*7c478bd9Sstevel@tonic-gate 	audit_allocate_argv(func, argc, argv);
245*7c478bd9Sstevel@tonic-gate 
246*7c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "slnugIU:F")) != -1)
247*7c478bd9Sstevel@tonic-gate 		switch (c) {
248*7c478bd9Sstevel@tonic-gate 		case 's':
249*7c478bd9Sstevel@tonic-gate 			optflg |= SILENT;
250*7c478bd9Sstevel@tonic-gate 			break;
251*7c478bd9Sstevel@tonic-gate 		case 'U':
252*7c478bd9Sstevel@tonic-gate 			optflg |= USERID;
253*7c478bd9Sstevel@tonic-gate 			uname = optarg;
254*7c478bd9Sstevel@tonic-gate 			break;
255*7c478bd9Sstevel@tonic-gate 		case 'g':
256*7c478bd9Sstevel@tonic-gate 			optflg |= TYPE;
257*7c478bd9Sstevel@tonic-gate 			break;
258*7c478bd9Sstevel@tonic-gate 		case 'l':
259*7c478bd9Sstevel@tonic-gate 			optflg |= LIST;
260*7c478bd9Sstevel@tonic-gate 			break;
261*7c478bd9Sstevel@tonic-gate 		case 'n':
262*7c478bd9Sstevel@tonic-gate 			optflg |= FREE;
263*7c478bd9Sstevel@tonic-gate 			break;
264*7c478bd9Sstevel@tonic-gate 		case 'u':
265*7c478bd9Sstevel@tonic-gate 			optflg |= CURRENT;
266*7c478bd9Sstevel@tonic-gate 			break;
267*7c478bd9Sstevel@tonic-gate 		case 'F':
268*7c478bd9Sstevel@tonic-gate 			optflg |= FORCE;
269*7c478bd9Sstevel@tonic-gate 			break;
270*7c478bd9Sstevel@tonic-gate 		case 'I':
271*7c478bd9Sstevel@tonic-gate 			optflg |= FORCE_ALL;
272*7c478bd9Sstevel@tonic-gate 			break;
273*7c478bd9Sstevel@tonic-gate 		case '?':
274*7c478bd9Sstevel@tonic-gate 			errflg++;
275*7c478bd9Sstevel@tonic-gate 			break;
276*7c478bd9Sstevel@tonic-gate 		default :
277*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("Bad option '%c'\n"), c);
278*7c478bd9Sstevel@tonic-gate 		}
279*7c478bd9Sstevel@tonic-gate 
280*7c478bd9Sstevel@tonic-gate 	if (optind < argc) {
281*7c478bd9Sstevel@tonic-gate 		device = argv[optind];
282*7c478bd9Sstevel@tonic-gate 	}
283*7c478bd9Sstevel@tonic-gate 
284*7c478bd9Sstevel@tonic-gate 	if (device == NULL && !(optflg & (LIST | FREE | CURRENT | FORCE_ALL)))
285*7c478bd9Sstevel@tonic-gate 		errflg++;
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate 	if (errflg) {
288*7c478bd9Sstevel@tonic-gate 		usage(func);
289*7c478bd9Sstevel@tonic-gate 		exit(2);
290*7c478bd9Sstevel@tonic-gate 	}
291*7c478bd9Sstevel@tonic-gate 
292*7c478bd9Sstevel@tonic-gate 	if (optflg & USERID) {
293*7c478bd9Sstevel@tonic-gate 		if ((pw_ent = getpwnam(uname)) == NULL) {
294*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext(
295*7c478bd9Sstevel@tonic-gate 			    "Invalid user name -- %s -- \n"), uname);
296*7c478bd9Sstevel@tonic-gate 			exit(4);
297*7c478bd9Sstevel@tonic-gate 		}
298*7c478bd9Sstevel@tonic-gate 		uid = pw_ent->pw_uid;
299*7c478bd9Sstevel@tonic-gate 	}
300*7c478bd9Sstevel@tonic-gate 
301*7c478bd9Sstevel@tonic-gate 	if (func == 0) {
302*7c478bd9Sstevel@tonic-gate 		if (optflg & ~ALLOC_OPTS) {
303*7c478bd9Sstevel@tonic-gate 			usage(func);
304*7c478bd9Sstevel@tonic-gate 			exit(3);
305*7c478bd9Sstevel@tonic-gate 		} else {
306*7c478bd9Sstevel@tonic-gate 			error = allocate(optflg, uid, device);
307*7c478bd9Sstevel@tonic-gate 		}
308*7c478bd9Sstevel@tonic-gate 	} else if (func == 1) {
309*7c478bd9Sstevel@tonic-gate 		if (optflg & ~DEALLOC_OPTS) {
310*7c478bd9Sstevel@tonic-gate 			usage(func);
311*7c478bd9Sstevel@tonic-gate 			exit(3);
312*7c478bd9Sstevel@tonic-gate 		} else {
313*7c478bd9Sstevel@tonic-gate 			error = deallocate(optflg, uid, device);
314*7c478bd9Sstevel@tonic-gate 		}
315*7c478bd9Sstevel@tonic-gate 	} else if (func == 2) {
316*7c478bd9Sstevel@tonic-gate 		if (optflg & ~LIST_OPTS) {
317*7c478bd9Sstevel@tonic-gate 			usage(func);
318*7c478bd9Sstevel@tonic-gate 			exit(3);
319*7c478bd9Sstevel@tonic-gate 		} else {
320*7c478bd9Sstevel@tonic-gate 			error = list_devices(optflg, uid, device);
321*7c478bd9Sstevel@tonic-gate 		}
322*7c478bd9Sstevel@tonic-gate 	}
323*7c478bd9Sstevel@tonic-gate 	(void) audit_allocate_record(error);
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 	if (error) {
326*7c478bd9Sstevel@tonic-gate 		if (!(optflg & SILENT))
327*7c478bd9Sstevel@tonic-gate 			print_error(error, name);
328*7c478bd9Sstevel@tonic-gate 		exit(error);
329*7c478bd9Sstevel@tonic-gate 	}
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate 	return (0);
332*7c478bd9Sstevel@tonic-gate }
333