xref: /titanic_53/usr/src/cmd/allocate/allocate.c (revision 40e2b7c9adf98f629a8a3463b605d4322963ef30)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate  * with the License.
87c478bd9Sstevel@tonic-gate  *
97c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate  * and limitations under the License.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate  *
207c478bd9Sstevel@tonic-gate  * CDDL HEADER END
217c478bd9Sstevel@tonic-gate  */
227c478bd9Sstevel@tonic-gate /*
23*40e2b7c9Spaulson  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
247c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #include <errno.h>
307c478bd9Sstevel@tonic-gate #include <locale.h>
317c478bd9Sstevel@tonic-gate #include <pwd.h>
327c478bd9Sstevel@tonic-gate #include <unistd.h>
337c478bd9Sstevel@tonic-gate #include <stdio.h>
347c478bd9Sstevel@tonic-gate #include <stdlib.h>
357c478bd9Sstevel@tonic-gate #include <string.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include <sys/types.h>
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #include "allocate.h"
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
427c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN "SUNW_OST_OSCMD"
437c478bd9Sstevel@tonic-gate #endif
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate extern void audit_allocate_argv(int, int, char *[]);
467c478bd9Sstevel@tonic-gate extern int audit_allocate_record(int);
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate static void
497c478bd9Sstevel@tonic-gate usage(int func)
507c478bd9Sstevel@tonic-gate {
51*40e2b7c9Spaulson 	char *use[7];
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate 	use[0] = gettext("allocate [-s] [-U uname] [-F] device");
547c478bd9Sstevel@tonic-gate 	use[1] = gettext("allocate [-s] [-U uname] -g dev_type");
557c478bd9Sstevel@tonic-gate 	use[2] = gettext("deallocate [-s] [-F] device");
56*40e2b7c9Spaulson 	use[3] = gettext("deallocate [-s] -I");
57*40e2b7c9Spaulson 	use[4] = gettext("list_devices [-s] [-U uid] -l [device]");
58*40e2b7c9Spaulson 	use[5] = gettext("list_devices [-s] [-U uid] -n [device]");
59*40e2b7c9Spaulson 	use[6] = gettext("list_devices [-s] [-U uid] -u [device]");
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate 	switch (func) {
627c478bd9Sstevel@tonic-gate 		case 0:
637c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n%s\n", use[0], use[1]);
647c478bd9Sstevel@tonic-gate 			break;
657c478bd9Sstevel@tonic-gate 		case 1:
667c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n%s\n", use[2], use[3]);
677c478bd9Sstevel@tonic-gate 			break;
687c478bd9Sstevel@tonic-gate 		case 2:
69*40e2b7c9Spaulson 			(void) fprintf(stderr, "%s\n%s\n%s\n", use[4], use[5],
70*40e2b7c9Spaulson 			    use[6]);
717c478bd9Sstevel@tonic-gate 			break;
727c478bd9Sstevel@tonic-gate 		default:
737c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s\n%s\n%s\n%s\n%s\n",
747c478bd9Sstevel@tonic-gate 				use[0], use[1], use[2], use[3], use[4]);
757c478bd9Sstevel@tonic-gate 	}
76*40e2b7c9Spaulson 	exit(1);
777c478bd9Sstevel@tonic-gate }
787c478bd9Sstevel@tonic-gate 
797c478bd9Sstevel@tonic-gate static void
807c478bd9Sstevel@tonic-gate print_error(int error, char *name)
817c478bd9Sstevel@tonic-gate {
827c478bd9Sstevel@tonic-gate 	char *msg;
837c478bd9Sstevel@tonic-gate 
847c478bd9Sstevel@tonic-gate 	switch (error) {
857c478bd9Sstevel@tonic-gate 	case SYSERROR:
867c478bd9Sstevel@tonic-gate 		msg = gettext("Unknown System error.");
877c478bd9Sstevel@tonic-gate 		break;
887c478bd9Sstevel@tonic-gate 	case IMPORT_ERR:
897c478bd9Sstevel@tonic-gate 		msg = gettext(
907c478bd9Sstevel@tonic-gate 		    "User lacks authorization required for this operation.");
917c478bd9Sstevel@tonic-gate 		break;
927c478bd9Sstevel@tonic-gate 	case NODAENT:
937c478bd9Sstevel@tonic-gate 		msg = gettext(
947c478bd9Sstevel@tonic-gate 		    "No device allocate file entry for specified device.");
957c478bd9Sstevel@tonic-gate 		break;
967c478bd9Sstevel@tonic-gate 	case NODMAPENT:
977c478bd9Sstevel@tonic-gate 		msg = gettext(
987c478bd9Sstevel@tonic-gate 		    "No device maps file entry for specified device.");
997c478bd9Sstevel@tonic-gate 		break;
1007c478bd9Sstevel@tonic-gate 	case DACLCK:
1017c478bd9Sstevel@tonic-gate 		msg = gettext("Concurrent operations for specified device, "
1027c478bd9Sstevel@tonic-gate 		    "try later.");
1037c478bd9Sstevel@tonic-gate 		break;
1047c478bd9Sstevel@tonic-gate 	case DACACC:
1057c478bd9Sstevel@tonic-gate 		msg = gettext(
1067c478bd9Sstevel@tonic-gate 		    "Can't access DAC file for the device specified.");
1077c478bd9Sstevel@tonic-gate 		break;
1087c478bd9Sstevel@tonic-gate 	case DEVLST:
1097c478bd9Sstevel@tonic-gate 		msg = gettext(
1107c478bd9Sstevel@tonic-gate 		    "Could not use device list for the device specified.");
1117c478bd9Sstevel@tonic-gate 		break;
1127c478bd9Sstevel@tonic-gate 	case NALLOCU:
1137c478bd9Sstevel@tonic-gate 		msg = gettext("Specified device is allocated to another user.");
1147c478bd9Sstevel@tonic-gate 		break;
1157c478bd9Sstevel@tonic-gate 	case NOTAUTH:
1167c478bd9Sstevel@tonic-gate 		msg = gettext("Not authorized for specified operation.");
1177c478bd9Sstevel@tonic-gate 		break;
1187c478bd9Sstevel@tonic-gate 	case CNTFRC:
1197c478bd9Sstevel@tonic-gate 		msg = gettext("Can't force deallocate specified device.");
1207c478bd9Sstevel@tonic-gate 		break;
1217c478bd9Sstevel@tonic-gate 	case CNTDEXEC:
1227c478bd9Sstevel@tonic-gate 		msg = gettext(
1237c478bd9Sstevel@tonic-gate 		    "Can't exec device-clean program for specified device.");
1247c478bd9Sstevel@tonic-gate 		break;
1257c478bd9Sstevel@tonic-gate 	case NO_DEVICE:
1267c478bd9Sstevel@tonic-gate 		msg = gettext(
1277c478bd9Sstevel@tonic-gate 		    "Can't find a device of type requested to allocate.");
1287c478bd9Sstevel@tonic-gate 		break;
1297c478bd9Sstevel@tonic-gate 	case DSPMISS:
1307c478bd9Sstevel@tonic-gate 		msg = gettext(
1317c478bd9Sstevel@tonic-gate 		    "Device special file(s) missing for specified device.");
1327c478bd9Sstevel@tonic-gate 		break;
1337c478bd9Sstevel@tonic-gate 	case ALLOCERR:
1347c478bd9Sstevel@tonic-gate 		msg = gettext("Device specified is in allocate error state.");
1357c478bd9Sstevel@tonic-gate 		break;
1367c478bd9Sstevel@tonic-gate 	case CHOWN_PERR:
1377c478bd9Sstevel@tonic-gate 		msg = gettext("Process lacks privilege required to chown().");
1387c478bd9Sstevel@tonic-gate 		break;
1397c478bd9Sstevel@tonic-gate 	case ALLOC:
1407c478bd9Sstevel@tonic-gate 		msg = gettext("Device already allocated.");
1417c478bd9Sstevel@tonic-gate 		break;
1427c478bd9Sstevel@tonic-gate 	case ALLOC_OTHER:
1437c478bd9Sstevel@tonic-gate 		msg = gettext("Device allocated to another user.");
1447c478bd9Sstevel@tonic-gate 		break;
1457c478bd9Sstevel@tonic-gate 	case NALLOC:
1467c478bd9Sstevel@tonic-gate 		msg = gettext("Device not allocated.");
1477c478bd9Sstevel@tonic-gate 		break;
1487c478bd9Sstevel@tonic-gate 	case AUTHERR:
1497c478bd9Sstevel@tonic-gate 		msg = gettext("Device not allocatable.");
1507c478bd9Sstevel@tonic-gate 		break;
1517c478bd9Sstevel@tonic-gate 	case CLEAN_ERR:
1527c478bd9Sstevel@tonic-gate 		msg = gettext("Unable to clean up the device.");
1537c478bd9Sstevel@tonic-gate 		break;
1547c478bd9Sstevel@tonic-gate 	case SETACL_PERR:
1557c478bd9Sstevel@tonic-gate 		msg = gettext("Process lacks privilege required to set ACL.");
1567c478bd9Sstevel@tonic-gate 		break;
1577c478bd9Sstevel@tonic-gate 	case DEVNAME_ERR:
1587c478bd9Sstevel@tonic-gate 		msg = gettext("Error forming device name.");
1597c478bd9Sstevel@tonic-gate 		break;
1607c478bd9Sstevel@tonic-gate 	case DEVNAME_TOOLONG:
1617c478bd9Sstevel@tonic-gate 		msg = gettext("Device name is too long.");
1627c478bd9Sstevel@tonic-gate 		break;
1637c478bd9Sstevel@tonic-gate 	default:
1647c478bd9Sstevel@tonic-gate 		msg = gettext("Unknown error code.");
1657c478bd9Sstevel@tonic-gate 		break;
1667c478bd9Sstevel@tonic-gate 	}
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "%s: %s\n", name, msg);
1697c478bd9Sstevel@tonic-gate 	(void) fflush(stderr);
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate char *newenv[] = {"PATH=/usr/bin:/usr/sbin",
1737c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_ALL		*/
1747c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_COLLATE	*/
1757c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_CTYPE		*/
1767c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_MESSAGES	*/
1777c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_NUMERIC	*/
1787c478bd9Sstevel@tonic-gate 			NULL,			/* for LC_TIME		*/
1797c478bd9Sstevel@tonic-gate 			NULL,			/* for LANG		*/
1807c478bd9Sstevel@tonic-gate 			NULL
1817c478bd9Sstevel@tonic-gate };
1827c478bd9Sstevel@tonic-gate 
1837c478bd9Sstevel@tonic-gate static char *
1847c478bd9Sstevel@tonic-gate getenvent(char *name, char *env[])
1857c478bd9Sstevel@tonic-gate {
1867c478bd9Sstevel@tonic-gate 	for (; *env != NULL; env++) {
1877c478bd9Sstevel@tonic-gate 		if (strncmp(*env, name, strlen(name)) == 0)
1887c478bd9Sstevel@tonic-gate 			return (*env);
1897c478bd9Sstevel@tonic-gate 	}
1907c478bd9Sstevel@tonic-gate 	return (NULL);
1917c478bd9Sstevel@tonic-gate }
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate int
1947c478bd9Sstevel@tonic-gate main(int argc, char *argv[], char *envp[])
1957c478bd9Sstevel@tonic-gate {
1967c478bd9Sstevel@tonic-gate 	char	*name, *env;
197*40e2b7c9Spaulson 	int	func = -1, optflg = 0, error = 0, c;
1987c478bd9Sstevel@tonic-gate 	uid_t	uid = getuid();
1997c478bd9Sstevel@tonic-gate 	char	*uname = NULL, *device = NULL;
2007c478bd9Sstevel@tonic-gate 	struct passwd *pw_ent;
2017c478bd9Sstevel@tonic-gate 	int env_num = 1;	/* PATH= is 0 entry */
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
2047c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	/*
2077c478bd9Sstevel@tonic-gate 	 * get all enviroment variables
2087c478bd9Sstevel@tonic-gate 	 * which affect on internationalization.
2097c478bd9Sstevel@tonic-gate 	 */
2107c478bd9Sstevel@tonic-gate 	env = getenvent("LC_ALL=", envp);
2117c478bd9Sstevel@tonic-gate 	if (env != NULL)
2127c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
2137c478bd9Sstevel@tonic-gate 	env = getenvent("LC_COLLATE=", envp);
2147c478bd9Sstevel@tonic-gate 	if (env != NULL)
2157c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
2167c478bd9Sstevel@tonic-gate 	env = getenvent("LC_CTYPE=", envp);
2177c478bd9Sstevel@tonic-gate 	if (env != NULL)
2187c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
2197c478bd9Sstevel@tonic-gate 	env = getenvent("LC_MESSAGES=", envp);
2207c478bd9Sstevel@tonic-gate 	if (env != NULL)
2217c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
2227c478bd9Sstevel@tonic-gate 	env = getenvent("LC_NUMERIC=", envp);
2237c478bd9Sstevel@tonic-gate 	if (env != NULL)
2247c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
2257c478bd9Sstevel@tonic-gate 	env = getenvent("LC_TIME=", envp);
2267c478bd9Sstevel@tonic-gate 	if (env != NULL)
2277c478bd9Sstevel@tonic-gate 		newenv[env_num++] = env;
2287c478bd9Sstevel@tonic-gate 	env = getenvent("LANG=", envp);
2297c478bd9Sstevel@tonic-gate 	if (env != NULL)
2307c478bd9Sstevel@tonic-gate 		newenv[env_num] = env;
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	if ((name = strrchr(argv[0], '/')) == NULL)
2337c478bd9Sstevel@tonic-gate 		name = argv[0];
2347c478bd9Sstevel@tonic-gate 	else
2357c478bd9Sstevel@tonic-gate 		name++;
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 	if (strcmp(name, "allocate") == 0)
2387c478bd9Sstevel@tonic-gate 		func = 0;
2397c478bd9Sstevel@tonic-gate 	else if (strcmp(name, "deallocate") == 0)
2407c478bd9Sstevel@tonic-gate 		func = 1;
2417c478bd9Sstevel@tonic-gate 	else if (strcmp(name, "list_devices") == 0)
2427c478bd9Sstevel@tonic-gate 		func = 2;
2437c478bd9Sstevel@tonic-gate 	else {
2447c478bd9Sstevel@tonic-gate 		usage(ALL);
2457c478bd9Sstevel@tonic-gate 	}
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 	audit_allocate_argv(func, argc, argv);
2487c478bd9Sstevel@tonic-gate 
249*40e2b7c9Spaulson 	if (func == 0) {	/* allocate */
250*40e2b7c9Spaulson 		while ((c = getopt(argc, argv, "sU:Fg")) != -1) {
251*40e2b7c9Spaulson 			switch (c) {
252*40e2b7c9Spaulson 			case 's':
253*40e2b7c9Spaulson 				optflg |= SILENT;
254*40e2b7c9Spaulson 				break;
255*40e2b7c9Spaulson 			case 'U':
256*40e2b7c9Spaulson 				optflg |= USERNAME;
257*40e2b7c9Spaulson 				uname = optarg;
258*40e2b7c9Spaulson 				break;
259*40e2b7c9Spaulson 			case 'g':
260*40e2b7c9Spaulson 				optflg |= TYPE;
261*40e2b7c9Spaulson 				break;
262*40e2b7c9Spaulson 			case 'F':
263*40e2b7c9Spaulson 				optflg |= FORCE;
264*40e2b7c9Spaulson 				break;
265*40e2b7c9Spaulson 			case '?':
266*40e2b7c9Spaulson 			default :
267*40e2b7c9Spaulson 				usage(func);
268*40e2b7c9Spaulson 			}
269*40e2b7c9Spaulson 		}
270*40e2b7c9Spaulson 
271*40e2b7c9Spaulson 		if ((optflg & TYPE) && (optflg & FORCE))
272*40e2b7c9Spaulson 			usage(func);
273*40e2b7c9Spaulson 
274*40e2b7c9Spaulson 		/*
275*40e2b7c9Spaulson 		 * allocate(1) must be supplied with one device argument
276*40e2b7c9Spaulson 		 */
277*40e2b7c9Spaulson 		if ((argc - optind) != 1) {
278*40e2b7c9Spaulson 			usage(func);
279*40e2b7c9Spaulson 		} else {
280*40e2b7c9Spaulson 			device = argv[optind];
281*40e2b7c9Spaulson 		}
282*40e2b7c9Spaulson 	}
283*40e2b7c9Spaulson 
284*40e2b7c9Spaulson 	else if (func == 1) {	/* deallocate */
285*40e2b7c9Spaulson 		while ((c = getopt(argc, argv, "sFI")) != -1) {
286*40e2b7c9Spaulson 			switch (c) {
287*40e2b7c9Spaulson 			case 's':
288*40e2b7c9Spaulson 				optflg |= SILENT;
289*40e2b7c9Spaulson 				break;
290*40e2b7c9Spaulson 			case 'F':
291*40e2b7c9Spaulson 				optflg |= FORCE;
292*40e2b7c9Spaulson 				break;
293*40e2b7c9Spaulson 			case 'I':
294*40e2b7c9Spaulson 				optflg |= FORCE_ALL;
295*40e2b7c9Spaulson 				break;
296*40e2b7c9Spaulson 			case '?':
297*40e2b7c9Spaulson 			default :
298*40e2b7c9Spaulson 				usage(func);
299*40e2b7c9Spaulson 			}
300*40e2b7c9Spaulson 		}
301*40e2b7c9Spaulson 
302*40e2b7c9Spaulson 		if ((optflg & FORCE) && (optflg & FORCE_ALL))
303*40e2b7c9Spaulson 			usage(func);
304*40e2b7c9Spaulson 
305*40e2b7c9Spaulson 		/*
306*40e2b7c9Spaulson 		 * deallocate(1) must be supplied with one device
307*40e2b7c9Spaulson 		 * argument unless the '-I' argument is supplied
308*40e2b7c9Spaulson 		 */
309*40e2b7c9Spaulson 		if (!(optflg & FORCE_ALL)) {
310*40e2b7c9Spaulson 			if ((argc - optind) != 1) {
311*40e2b7c9Spaulson 				usage(func);
312*40e2b7c9Spaulson 			} else {
313*40e2b7c9Spaulson 				device = argv[optind];
314*40e2b7c9Spaulson 			}
315*40e2b7c9Spaulson 		} else {
316*40e2b7c9Spaulson 			if ((argc - optind) >= 1) {
317*40e2b7c9Spaulson 				usage(func);
318*40e2b7c9Spaulson 			}
319*40e2b7c9Spaulson 		}
320*40e2b7c9Spaulson 	}
321*40e2b7c9Spaulson 
322*40e2b7c9Spaulson 	else if (func == 2) {	/* list_devices */
323*40e2b7c9Spaulson 		while ((c = getopt(argc, argv, "sU:lnu")) != -1) {
3247c478bd9Sstevel@tonic-gate 			switch (c) {
3257c478bd9Sstevel@tonic-gate 			case 's':
3267c478bd9Sstevel@tonic-gate 				optflg |= SILENT;
3277c478bd9Sstevel@tonic-gate 				break;
3287c478bd9Sstevel@tonic-gate 			case 'U':
3297c478bd9Sstevel@tonic-gate 				optflg |= USERID;
330*40e2b7c9Spaulson 				uid = atoi(optarg);
3317c478bd9Sstevel@tonic-gate 				break;
3327c478bd9Sstevel@tonic-gate 			case 'l':
3337c478bd9Sstevel@tonic-gate 				optflg |= LIST;
3347c478bd9Sstevel@tonic-gate 				break;
3357c478bd9Sstevel@tonic-gate 			case 'n':
3367c478bd9Sstevel@tonic-gate 				optflg |= FREE;
3377c478bd9Sstevel@tonic-gate 				break;
3387c478bd9Sstevel@tonic-gate 			case 'u':
3397c478bd9Sstevel@tonic-gate 				optflg |= CURRENT;
3407c478bd9Sstevel@tonic-gate 				break;
3417c478bd9Sstevel@tonic-gate 			case '?':
3427c478bd9Sstevel@tonic-gate 			default :
3437c478bd9Sstevel@tonic-gate 				usage(func);
344*40e2b7c9Spaulson 			}
3457c478bd9Sstevel@tonic-gate 		}
3467c478bd9Sstevel@tonic-gate 
347*40e2b7c9Spaulson 		if (((optflg & LIST) && (optflg & FREE)) ||
348*40e2b7c9Spaulson 		    ((optflg & LIST) && (optflg & CURRENT)) ||
349*40e2b7c9Spaulson 		    ((optflg & FREE) && (optflg & CURRENT)) ||
350*40e2b7c9Spaulson 		    (!(optflg & (LIST | FREE | CURRENT))))
351*40e2b7c9Spaulson 			usage(func);
352*40e2b7c9Spaulson 
353*40e2b7c9Spaulson 		/*
354*40e2b7c9Spaulson 		 * list_devices(1) takes an optional device argument
355*40e2b7c9Spaulson 		 */
356*40e2b7c9Spaulson 		if ((argc - optind) == 1) {
357*40e2b7c9Spaulson 			device = argv[optind];
358*40e2b7c9Spaulson 		} else {
359*40e2b7c9Spaulson 			if ((argc - optind) > 1) {
360*40e2b7c9Spaulson 				usage(func);
361*40e2b7c9Spaulson 			}
362*40e2b7c9Spaulson 		}
363*40e2b7c9Spaulson 	}
364*40e2b7c9Spaulson 
365*40e2b7c9Spaulson 	if (optflg & USERNAME) {
3667c478bd9Sstevel@tonic-gate 		if ((pw_ent = getpwnam(uname)) == NULL) {
3677c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext(
3687c478bd9Sstevel@tonic-gate 			    "Invalid user name -- %s -- \n"), uname);
369*40e2b7c9Spaulson 			exit(1);
370*40e2b7c9Spaulson 		}
371*40e2b7c9Spaulson 		uid = pw_ent->pw_uid;
372*40e2b7c9Spaulson 	}
373*40e2b7c9Spaulson 
374*40e2b7c9Spaulson 	if (optflg & USERID) {
375*40e2b7c9Spaulson 		if ((pw_ent = getpwuid(uid)) == NULL) {
376*40e2b7c9Spaulson 			(void) fprintf(stderr, gettext(
377*40e2b7c9Spaulson 			    "Invalid user ID -- %d -- \n"), uid);
378*40e2b7c9Spaulson 			exit(1);
3797c478bd9Sstevel@tonic-gate 		}
3807c478bd9Sstevel@tonic-gate 		uid = pw_ent->pw_uid;
3817c478bd9Sstevel@tonic-gate 	}
3827c478bd9Sstevel@tonic-gate 
3837c478bd9Sstevel@tonic-gate 	if (func == 0) {
3847c478bd9Sstevel@tonic-gate 		error = allocate(optflg, uid, device);
3857c478bd9Sstevel@tonic-gate 	} else if (func == 1) {
3867c478bd9Sstevel@tonic-gate 		error = deallocate(optflg, uid, device);
3877c478bd9Sstevel@tonic-gate 	} else if (func == 2) {
3887c478bd9Sstevel@tonic-gate 		error = list_devices(optflg, uid, device);
3897c478bd9Sstevel@tonic-gate 	}
390*40e2b7c9Spaulson 
3917c478bd9Sstevel@tonic-gate 	(void) audit_allocate_record(error);
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	if (error) {
3947c478bd9Sstevel@tonic-gate 		if (!(optflg & SILENT))
3957c478bd9Sstevel@tonic-gate 			print_error(error, name);
3967c478bd9Sstevel@tonic-gate 		exit(error);
3977c478bd9Sstevel@tonic-gate 	}
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate 	return (0);
4007c478bd9Sstevel@tonic-gate }
401