xref: /titanic_54/usr/src/cmd/ndmpadm/ndmpadm_main.c (revision 2654012f83cec5dc15b61dfe3e4a4915f186e7a6)
1*2654012fSReza Sabdar /*
2*2654012fSReza Sabdar  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3*2654012fSReza Sabdar  * Use is subject to license terms.
4*2654012fSReza Sabdar  */
5*2654012fSReza Sabdar 
6*2654012fSReza Sabdar /*
7*2654012fSReza Sabdar  * BSD 3 Clause License
8*2654012fSReza Sabdar  *
9*2654012fSReza Sabdar  * Copyright (c) 2007, The Storage Networking Industry Association.
10*2654012fSReza Sabdar  *
11*2654012fSReza Sabdar  * Redistribution and use in source and binary forms, with or without
12*2654012fSReza Sabdar  * modification, are permitted provided that the following conditions
13*2654012fSReza Sabdar  * are met:
14*2654012fSReza Sabdar  * 	- Redistributions of source code must retain the above copyright
15*2654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer.
16*2654012fSReza Sabdar  *
17*2654012fSReza Sabdar  * 	- Redistributions in binary form must reproduce the above copyright
18*2654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer in
19*2654012fSReza Sabdar  *	  the documentation and/or other materials provided with the
20*2654012fSReza Sabdar  *	  distribution.
21*2654012fSReza Sabdar  *
22*2654012fSReza Sabdar  *	- Neither the name of The Storage Networking Industry Association (SNIA)
23*2654012fSReza Sabdar  *	  nor the names of its contributors may be used to endorse or promote
24*2654012fSReza Sabdar  *	  products derived from this software without specific prior written
25*2654012fSReza Sabdar  *	  permission.
26*2654012fSReza Sabdar  *
27*2654012fSReza Sabdar  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28*2654012fSReza Sabdar  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*2654012fSReza Sabdar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*2654012fSReza Sabdar  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31*2654012fSReza Sabdar  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*2654012fSReza Sabdar  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*2654012fSReza Sabdar  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34*2654012fSReza Sabdar  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35*2654012fSReza Sabdar  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36*2654012fSReza Sabdar  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37*2654012fSReza Sabdar  * POSSIBILITY OF SUCH DAMAGE.
38*2654012fSReza Sabdar  */
39*2654012fSReza Sabdar #include <assert.h>
40*2654012fSReza Sabdar #include <ctype.h>
41*2654012fSReza Sabdar #include <libgen.h>
42*2654012fSReza Sabdar #include <libintl.h>
43*2654012fSReza Sabdar #include <locale.h>
44*2654012fSReza Sabdar #include <stddef.h>
45*2654012fSReza Sabdar #include <stdio.h>
46*2654012fSReza Sabdar #include <stdlib.h>
47*2654012fSReza Sabdar #include <strings.h>
48*2654012fSReza Sabdar #include <unistd.h>
49*2654012fSReza Sabdar #include <fcntl.h>
50*2654012fSReza Sabdar #include <sys/stat.h>
51*2654012fSReza Sabdar #include <door.h>
52*2654012fSReza Sabdar #include <sys/mman.h>
53*2654012fSReza Sabdar #include <libndmp.h>
54*2654012fSReza Sabdar #include "ndmpadm.h"
55*2654012fSReza Sabdar 
56*2654012fSReza Sabdar typedef enum {
57*2654012fSReza Sabdar 	HELP_GET_CONFIG,
58*2654012fSReza Sabdar 	HELP_SET_CONFIG,
59*2654012fSReza Sabdar 	HELP_SHOW_DEVICES,
60*2654012fSReza Sabdar 	HELP_SHOW_SESSIONS,
61*2654012fSReza Sabdar 	HELP_KILL_SESSIONS,
62*2654012fSReza Sabdar 	HELP_ENABLE_AUTH,
63*2654012fSReza Sabdar 	HELP_DISABLE_AUTH
64*2654012fSReza Sabdar } ndmp_help_t;
65*2654012fSReza Sabdar 
66*2654012fSReza Sabdar typedef struct ndmp_command {
67*2654012fSReza Sabdar 	const char	*nc_name;
68*2654012fSReza Sabdar 	int		(*func)(int argc, char **argv,
69*2654012fSReza Sabdar 			    struct ndmp_command *cur_cmd);
70*2654012fSReza Sabdar 	ndmp_help_t	nc_usage;
71*2654012fSReza Sabdar } ndmp_command_t;
72*2654012fSReza Sabdar 
73*2654012fSReza Sabdar static int ndmp_get_config(int, char **, ndmp_command_t *);
74*2654012fSReza Sabdar static int ndmp_set_config(int, char **, ndmp_command_t *);
75*2654012fSReza Sabdar static int ndmp_show_devices(int, char **, ndmp_command_t *);
76*2654012fSReza Sabdar static int ndmp_show_sessions(int, char **, ndmp_command_t *);
77*2654012fSReza Sabdar static int ndmp_kill_sessions(int, char **, ndmp_command_t *);
78*2654012fSReza Sabdar static int ndmp_enable_auth(int, char **, ndmp_command_t *);
79*2654012fSReza Sabdar static int ndmp_disable_auth(int, char **, ndmp_command_t *);
80*2654012fSReza Sabdar static void ndmp_get_config_process(char *);
81*2654012fSReza Sabdar static void ndmp_set_config_process(char *arg);
82*2654012fSReza Sabdar static int ndmp_get_password(char **);
83*2654012fSReza Sabdar 
84*2654012fSReza Sabdar static ndmp_command_t command_table[] = {
85*2654012fSReza Sabdar 	{ "get",		ndmp_get_config,	HELP_GET_CONFIG	},
86*2654012fSReza Sabdar 	{ "set",		ndmp_set_config,	HELP_SET_CONFIG	},
87*2654012fSReza Sabdar 	{ "show-devices",	ndmp_show_devices,	HELP_SHOW_DEVICES },
88*2654012fSReza Sabdar 	{ "show-sessions",	ndmp_show_sessions,	HELP_SHOW_SESSIONS },
89*2654012fSReza Sabdar 	{ "kill-sessions",	ndmp_kill_sessions,	HELP_KILL_SESSIONS },
90*2654012fSReza Sabdar 	{ "enable",		ndmp_enable_auth,	HELP_ENABLE_AUTH },
91*2654012fSReza Sabdar 	{ "disable",		ndmp_disable_auth,	HELP_DISABLE_AUTH }
92*2654012fSReza Sabdar };
93*2654012fSReza Sabdar 
94*2654012fSReza Sabdar #define	NCOMMAND	(sizeof (command_table) / sizeof (command_table[0]))
95*2654012fSReza Sabdar 
96*2654012fSReza Sabdar static char *prop_table[] = {
97*2654012fSReza Sabdar 	"debug-path",
98*2654012fSReza Sabdar 	"dump-pathnode",
99*2654012fSReza Sabdar 	"tar-pathnode",
100*2654012fSReza Sabdar 	"ignore-ctime",
101*2654012fSReza Sabdar 	"token-maxseq",
102*2654012fSReza Sabdar 	"version",
103*2654012fSReza Sabdar 	"dar-support",
104*2654012fSReza Sabdar 	"tcp-port",
105*2654012fSReza Sabdar 	"backup-quarantine",
106*2654012fSReza Sabdar 	"restore-quarantine",
107*2654012fSReza Sabdar 	"overwrite-quarantine"
108*2654012fSReza Sabdar };
109*2654012fSReza Sabdar 
110*2654012fSReza Sabdar #define	NDMPADM_NPROP	(sizeof (prop_table) / sizeof (prop_table[0]))
111*2654012fSReza Sabdar 
112*2654012fSReza Sabdar typedef struct ndmp_auth {
113*2654012fSReza Sabdar 	const char *auth_type;
114*2654012fSReza Sabdar 	const char *username;
115*2654012fSReza Sabdar 	const char *password;
116*2654012fSReza Sabdar } ndmp_auth_t;
117*2654012fSReza Sabdar 
118*2654012fSReza Sabdar static ndmp_auth_t ndmp_auth_table[] = {
119*2654012fSReza Sabdar 	{ "cram-md5", "cram-md5-username", "cram-md5-password" },
120*2654012fSReza Sabdar 	{ "cleartext", "cleartext-username", "cleartext-password" }
121*2654012fSReza Sabdar };
122*2654012fSReza Sabdar #define	NAUTH	(sizeof (ndmp_auth_table) / sizeof (ndmp_auth_table[0]))
123*2654012fSReza Sabdar #define	NDMP_PASSWORD_RETRIES	3
124*2654012fSReza Sabdar 
125*2654012fSReza Sabdar #if !defined(TEXT_DOMAIN)
126*2654012fSReza Sabdar #define	TEXT_DOMAIN	"SYS_TEST"
127*2654012fSReza Sabdar #endif
128*2654012fSReza Sabdar 
129*2654012fSReza Sabdar static const char *
130*2654012fSReza Sabdar get_usage(ndmp_help_t idx)
131*2654012fSReza Sabdar {
132*2654012fSReza Sabdar 	switch (idx) {
133*2654012fSReza Sabdar 	case HELP_SET_CONFIG:
134*2654012fSReza Sabdar 		return ("\tset [-p] <property=value> [[-p] property=value] "
135*2654012fSReza Sabdar 		    "...\n");
136*2654012fSReza Sabdar 	case HELP_GET_CONFIG:
137*2654012fSReza Sabdar 		return ("\tget [-p] [property] [[-p] property] ...\n");
138*2654012fSReza Sabdar 	case HELP_SHOW_DEVICES:
139*2654012fSReza Sabdar 		return ("\tshow-devices\n");
140*2654012fSReza Sabdar 	case HELP_SHOW_SESSIONS:
141*2654012fSReza Sabdar 		return ("\tshow-sessions [-i tape,scsi,data,mover] [id] ...\n");
142*2654012fSReza Sabdar 	case HELP_KILL_SESSIONS:
143*2654012fSReza Sabdar 		return ("\tkill-sessions <id ...>\n");
144*2654012fSReza Sabdar 	case HELP_ENABLE_AUTH:
145*2654012fSReza Sabdar 		return ("\tenable <-a auth-type> <-u username>\n");
146*2654012fSReza Sabdar 	case HELP_DISABLE_AUTH:
147*2654012fSReza Sabdar 		return ("\tdisable <-a auth-type>\n");
148*2654012fSReza Sabdar 	}
149*2654012fSReza Sabdar 
150*2654012fSReza Sabdar 	return (NULL);
151*2654012fSReza Sabdar }
152*2654012fSReza Sabdar 
153*2654012fSReza Sabdar /*
154*2654012fSReza Sabdar  * Display usage message.  If we're inside a command, display only the usage for
155*2654012fSReza Sabdar  * that command.  Otherwise, iterate over the entire command table and display
156*2654012fSReza Sabdar  * a complete usage message.
157*2654012fSReza Sabdar  */
158*2654012fSReza Sabdar static void
159*2654012fSReza Sabdar usage(boolean_t requested, ndmp_command_t *current_command)
160*2654012fSReza Sabdar {
161*2654012fSReza Sabdar 	int i;
162*2654012fSReza Sabdar 	boolean_t show_properties = B_FALSE;
163*2654012fSReza Sabdar 	FILE *fp = requested ? stdout : stderr;
164*2654012fSReza Sabdar 
165*2654012fSReza Sabdar 	if (current_command == NULL) {
166*2654012fSReza Sabdar 		(void) fprintf(fp,
167*2654012fSReza Sabdar 		    gettext("Usage: ndmpadm subcommand args ...\n"));
168*2654012fSReza Sabdar 		(void) fprintf(fp,
169*2654012fSReza Sabdar 		    gettext("where 'command' is one of the following:\n\n"));
170*2654012fSReza Sabdar 
171*2654012fSReza Sabdar 		for (i = 0; i < NCOMMAND; i++) {
172*2654012fSReza Sabdar 			(void) fprintf(fp, "%s",
173*2654012fSReza Sabdar 			    get_usage(command_table[i].nc_usage));
174*2654012fSReza Sabdar 		}
175*2654012fSReza Sabdar 		(void) fprintf(fp, gettext("\t\twhere %s can be either "
176*2654012fSReza Sabdar 		    "%s or %s\n"), "'auth-type'", "'cram-md5'", "'cleartext'");
177*2654012fSReza Sabdar 	} else {
178*2654012fSReza Sabdar 		(void) fprintf(fp, gettext("Usage:\n"));
179*2654012fSReza Sabdar 		(void) fprintf(fp, "%s", get_usage(current_command->nc_usage));
180*2654012fSReza Sabdar 		if ((current_command->nc_usage == HELP_ENABLE_AUTH) ||
181*2654012fSReza Sabdar 		    (current_command->nc_usage == HELP_DISABLE_AUTH))
182*2654012fSReza Sabdar 			(void) fprintf(fp, gettext("\t\twhere %s can be either "
183*2654012fSReza Sabdar 			    "%s or %s\n"),
184*2654012fSReza Sabdar 			    "'auth-type'", "'cram-md5'", "'cleartext'");
185*2654012fSReza Sabdar 	}
186*2654012fSReza Sabdar 
187*2654012fSReza Sabdar 	if (current_command != NULL &&
188*2654012fSReza Sabdar 	    (strcmp(current_command->nc_name, "set") == 0))
189*2654012fSReza Sabdar 		show_properties = B_TRUE;
190*2654012fSReza Sabdar 
191*2654012fSReza Sabdar 	if (show_properties) {
192*2654012fSReza Sabdar 		(void) fprintf(fp,
193*2654012fSReza Sabdar 		    gettext("\nThe following properties are supported:\n"));
194*2654012fSReza Sabdar 
195*2654012fSReza Sabdar 		(void) fprintf(fp, gettext("\n\tPROPERTY"));
196*2654012fSReza Sabdar 		(void) fprintf(fp, "\n\t%s", "-------------");
197*2654012fSReza Sabdar 		for (i = 0; i < NDMPADM_NPROP; i++)
198*2654012fSReza Sabdar 			(void) fprintf(fp, "\n\t%s", prop_table[i]);
199*2654012fSReza Sabdar 		(void) fprintf(fp, "\n");
200*2654012fSReza Sabdar 	}
201*2654012fSReza Sabdar 
202*2654012fSReza Sabdar 	exit(requested ? 0 : 2);
203*2654012fSReza Sabdar }
204*2654012fSReza Sabdar 
205*2654012fSReza Sabdar /*ARGSUSED*/
206*2654012fSReza Sabdar static int
207*2654012fSReza Sabdar ndmp_get_config(int argc, char **argv, ndmp_command_t *cur_cmd)
208*2654012fSReza Sabdar {
209*2654012fSReza Sabdar 	char *propval;
210*2654012fSReza Sabdar 	int i, c;
211*2654012fSReza Sabdar 
212*2654012fSReza Sabdar 	if (argc == 1) {
213*2654012fSReza Sabdar 		/*
214*2654012fSReza Sabdar 		 * Get all the properties and variables ndmpadm is allowed
215*2654012fSReza Sabdar 		 * to see.
216*2654012fSReza Sabdar 		 */
217*2654012fSReza Sabdar 		for (i = 0; i < NDMPADM_NPROP; i++) {
218*2654012fSReza Sabdar 			if (ndmp_get_prop(prop_table[i], &propval)) {
219*2654012fSReza Sabdar 				(void) fprintf(stdout, "\t%s=\n",
220*2654012fSReza Sabdar 				    prop_table[i]);
221*2654012fSReza Sabdar 			} else {
222*2654012fSReza Sabdar 				(void) fprintf(stdout, "\t%s=%s\n",
223*2654012fSReza Sabdar 				    prop_table[i], propval);
224*2654012fSReza Sabdar 				free(propval);
225*2654012fSReza Sabdar 			}
226*2654012fSReza Sabdar 		}
227*2654012fSReza Sabdar 	} else if (argc > 1) {
228*2654012fSReza Sabdar 		while ((c = getopt(argc, argv, ":p:")) != -1) {
229*2654012fSReza Sabdar 			switch (c) {
230*2654012fSReza Sabdar 			case 'p':
231*2654012fSReza Sabdar 				ndmp_get_config_process(optarg);
232*2654012fSReza Sabdar 				break;
233*2654012fSReza Sabdar 			case ':':
234*2654012fSReza Sabdar 				(void) fprintf(stderr, gettext("Option -%c "
235*2654012fSReza Sabdar 				    "requires an operand\n"), optopt);
236*2654012fSReza Sabdar 				break;
237*2654012fSReza Sabdar 			case '?':
238*2654012fSReza Sabdar 				(void) fprintf(stderr, gettext("Unrecognized "
239*2654012fSReza Sabdar 				    "option: -%c\n"), optopt);
240*2654012fSReza Sabdar 			}
241*2654012fSReza Sabdar 		}
242*2654012fSReza Sabdar 		/*
243*2654012fSReza Sabdar 		 * optind is initialized to 1 if the -p option is not used,
244*2654012fSReza Sabdar 		 * otherwise index to argv.
245*2654012fSReza Sabdar 		 */
246*2654012fSReza Sabdar 		argc -= optind;
247*2654012fSReza Sabdar 		argv += optind;
248*2654012fSReza Sabdar 
249*2654012fSReza Sabdar 		for (i = 0; i < argc; i++) {
250*2654012fSReza Sabdar 			if (strncmp(argv[i], "-p", 2) == 0)
251*2654012fSReza Sabdar 				continue;
252*2654012fSReza Sabdar 
253*2654012fSReza Sabdar 			ndmp_get_config_process(argv[i]);
254*2654012fSReza Sabdar 		}
255*2654012fSReza Sabdar 	}
256*2654012fSReza Sabdar 	return (0);
257*2654012fSReza Sabdar }
258*2654012fSReza Sabdar 
259*2654012fSReza Sabdar static void
260*2654012fSReza Sabdar ndmp_get_config_process(char *arg)
261*2654012fSReza Sabdar {
262*2654012fSReza Sabdar 	int j;
263*2654012fSReza Sabdar 	char *propval;
264*2654012fSReza Sabdar 
265*2654012fSReza Sabdar 	for (j = 0; j < NDMPADM_NPROP; j++) {
266*2654012fSReza Sabdar 		if (strcmp(arg, prop_table[j]) == 0) {
267*2654012fSReza Sabdar 			if (ndmp_get_prop(arg, &propval)) {
268*2654012fSReza Sabdar 				(void) fprintf(stdout, "\t%s=\n", arg);
269*2654012fSReza Sabdar 			} else {
270*2654012fSReza Sabdar 				(void) fprintf(stdout, "\t%s=%s\n",
271*2654012fSReza Sabdar 				    arg, propval);
272*2654012fSReza Sabdar 				free(propval);
273*2654012fSReza Sabdar 			}
274*2654012fSReza Sabdar 			break;
275*2654012fSReza Sabdar 		}
276*2654012fSReza Sabdar 	}
277*2654012fSReza Sabdar 	if (j == NDMPADM_NPROP) {
278*2654012fSReza Sabdar 		(void) fprintf(stdout, gettext("\t%s is invalid property "
279*2654012fSReza Sabdar 		    "or variable\n"), arg);
280*2654012fSReza Sabdar 	}
281*2654012fSReza Sabdar }
282*2654012fSReza Sabdar 
283*2654012fSReza Sabdar /*ARGSUSED*/
284*2654012fSReza Sabdar static int
285*2654012fSReza Sabdar ndmp_set_config(int argc, char **argv, ndmp_command_t *cur_cmd)
286*2654012fSReza Sabdar {
287*2654012fSReza Sabdar 	int c, i;
288*2654012fSReza Sabdar 
289*2654012fSReza Sabdar 	if (argc < 2) {
290*2654012fSReza Sabdar 		(void) fprintf(stderr, gettext("Missing property=value "
291*2654012fSReza Sabdar 		    "argument\n"));
292*2654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
293*2654012fSReza Sabdar 	}
294*2654012fSReza Sabdar 	while ((c = getopt(argc, argv, ":p:")) != -1) {
295*2654012fSReza Sabdar 		switch (c) {
296*2654012fSReza Sabdar 		case 'p':
297*2654012fSReza Sabdar 			ndmp_set_config_process(optarg);
298*2654012fSReza Sabdar 			break;
299*2654012fSReza Sabdar 		case ':':
300*2654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Option -%c "
301*2654012fSReza Sabdar 			    "requires an operand\n"), optopt);
302*2654012fSReza Sabdar 			break;
303*2654012fSReza Sabdar 		case '?':
304*2654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Unrecognized "
305*2654012fSReza Sabdar 			    "option: -%c\n"), optopt);
306*2654012fSReza Sabdar 		}
307*2654012fSReza Sabdar 	}
308*2654012fSReza Sabdar 	/*
309*2654012fSReza Sabdar 	 * optind is initialized to 1 if the -p option is not used,
310*2654012fSReza Sabdar 	 * otherwise index to argv.
311*2654012fSReza Sabdar 	 */
312*2654012fSReza Sabdar 	argc -= optind;
313*2654012fSReza Sabdar 	argv += optind;
314*2654012fSReza Sabdar 
315*2654012fSReza Sabdar 	for (i = 0; i < argc; i++) {
316*2654012fSReza Sabdar 		if (strncmp(argv[i], "-p", 2) == 0)
317*2654012fSReza Sabdar 			continue;
318*2654012fSReza Sabdar 
319*2654012fSReza Sabdar 		ndmp_set_config_process(argv[i]);
320*2654012fSReza Sabdar 	}
321*2654012fSReza Sabdar 	return (0);
322*2654012fSReza Sabdar }
323*2654012fSReza Sabdar 
324*2654012fSReza Sabdar static void
325*2654012fSReza Sabdar ndmp_set_config_process(char *propname)
326*2654012fSReza Sabdar {
327*2654012fSReza Sabdar 	char *propvalue;
328*2654012fSReza Sabdar 	int ret, j;
329*2654012fSReza Sabdar 
330*2654012fSReza Sabdar 	if ((propvalue = strchr(propname, '=')) == NULL) {
331*2654012fSReza Sabdar 		(void) fprintf(stderr, gettext("Missing value in "
332*2654012fSReza Sabdar 		    "property=value argument for %s\n"), propname);
333*2654012fSReza Sabdar 			return;
334*2654012fSReza Sabdar 	}
335*2654012fSReza Sabdar 	*propvalue = '\0';
336*2654012fSReza Sabdar 	propvalue++;
337*2654012fSReza Sabdar 
338*2654012fSReza Sabdar 	if (*propname == '\0') {
339*2654012fSReza Sabdar 		(void) fprintf(stderr, gettext("Missing property in "
340*2654012fSReza Sabdar 		    "property=value argument for %s\n"), propname);
341*2654012fSReza Sabdar 			return;
342*2654012fSReza Sabdar 	}
343*2654012fSReza Sabdar 	for (j = 0; j < NDMPADM_NPROP; j++) {
344*2654012fSReza Sabdar 		if (strcmp(propname, prop_table[j]) == 0)
345*2654012fSReza Sabdar 			break;
346*2654012fSReza Sabdar 	}
347*2654012fSReza Sabdar 	if (j == NDMPADM_NPROP) {
348*2654012fSReza Sabdar 		(void) fprintf(stdout, gettext("%s is invalid property or "
349*2654012fSReza Sabdar 		    "variable\n"), propname);
350*2654012fSReza Sabdar 		return;
351*2654012fSReza Sabdar 	}
352*2654012fSReza Sabdar 	ret = ndmp_set_prop(propname, propvalue);
353*2654012fSReza Sabdar 	if (ret != -1) {
354*2654012fSReza Sabdar 		if (!ndmp_door_status()) {
355*2654012fSReza Sabdar 			if (ndmp_service_refresh() == -1)
356*2654012fSReza Sabdar 				(void) fprintf(stdout, gettext("Could not "
357*2654012fSReza Sabdar 				    "refesh property of service ndmpd\n"));
358*2654012fSReza Sabdar 		}
359*2654012fSReza Sabdar 	} else {
360*2654012fSReza Sabdar 		(void) fprintf(stdout, gettext("Could not set property for "
361*2654012fSReza Sabdar 		    "%s - %s\n"), propname, ndmp_strerror(ndmp_errno));
362*2654012fSReza Sabdar 	}
363*2654012fSReza Sabdar }
364*2654012fSReza Sabdar 
365*2654012fSReza Sabdar /*ARGSUSED*/
366*2654012fSReza Sabdar static int
367*2654012fSReza Sabdar ndmp_show_devices(int argc, char **argv, ndmp_command_t *cur_cmd)
368*2654012fSReza Sabdar {
369*2654012fSReza Sabdar 	int ret;
370*2654012fSReza Sabdar 	ndmp_devinfo_t *dip = NULL;
371*2654012fSReza Sabdar 	size_t size;
372*2654012fSReza Sabdar 
373*2654012fSReza Sabdar 	if (ndmp_door_status()) {
374*2654012fSReza Sabdar 		(void) fprintf(stdout,
375*2654012fSReza Sabdar 		    gettext("Service ndmpd not running\n"));
376*2654012fSReza Sabdar 		return (-1);
377*2654012fSReza Sabdar 	}
378*2654012fSReza Sabdar 
379*2654012fSReza Sabdar 	ret = ndmp_get_devinfo(&dip, &size);
380*2654012fSReza Sabdar 
381*2654012fSReza Sabdar 	if (ret == -1)
382*2654012fSReza Sabdar 		(void) fprintf(stdout,
383*2654012fSReza Sabdar 		    gettext("Could not get device information\n"));
384*2654012fSReza Sabdar 	else
385*2654012fSReza Sabdar 		ndmp_devinfo_print(dip, size);
386*2654012fSReza Sabdar 
387*2654012fSReza Sabdar 	ndmp_get_devinfo_free(dip, size);
388*2654012fSReza Sabdar 	return (0);
389*2654012fSReza Sabdar }
390*2654012fSReza Sabdar 
391*2654012fSReza Sabdar static int
392*2654012fSReza Sabdar ndmp_show_sessions(int argc, char **argv, ndmp_command_t *cur_cmd)
393*2654012fSReza Sabdar {
394*2654012fSReza Sabdar 	ndmp_session_info_t *sinfo = NULL;
395*2654012fSReza Sabdar 	ndmp_session_info_t *sp = NULL;
396*2654012fSReza Sabdar 	uint_t num;
397*2654012fSReza Sabdar 	int c, ret, i, j;
398*2654012fSReza Sabdar 	int statarg = 0;
399*2654012fSReza Sabdar 	char *value;
400*2654012fSReza Sabdar 	char *type_subopts[] = { "tape", "scsi", "data", "mover", NULL };
401*2654012fSReza Sabdar 
402*2654012fSReza Sabdar 	if (ndmp_door_status()) {
403*2654012fSReza Sabdar 		(void) fprintf(stdout,
404*2654012fSReza Sabdar 		    gettext("Service ndmpd not running\n"));
405*2654012fSReza Sabdar 		return (-1);
406*2654012fSReza Sabdar 	}
407*2654012fSReza Sabdar 
408*2654012fSReza Sabdar 	/* Detail output if no option is specified */
409*2654012fSReza Sabdar 	if (argc == 1) {
410*2654012fSReza Sabdar 		statarg = NDMP_CAT_ALL;
411*2654012fSReza Sabdar 	} else {
412*2654012fSReza Sabdar 		statarg = 0;
413*2654012fSReza Sabdar 		while ((c = getopt(argc, argv, ":i:")) != -1) {
414*2654012fSReza Sabdar 			switch (c) {
415*2654012fSReza Sabdar 			case 'i':
416*2654012fSReza Sabdar 				while (*optarg != '\0') {
417*2654012fSReza Sabdar 					switch (getsubopt(&optarg, type_subopts,
418*2654012fSReza Sabdar 					    &value)) {
419*2654012fSReza Sabdar 					case 0:
420*2654012fSReza Sabdar 						statarg |= NDMP_CAT_TAPE;
421*2654012fSReza Sabdar 						break;
422*2654012fSReza Sabdar 					case 1:
423*2654012fSReza Sabdar 						statarg |= NDMP_CAT_SCSI;
424*2654012fSReza Sabdar 						break;
425*2654012fSReza Sabdar 					case 2:
426*2654012fSReza Sabdar 						statarg |= NDMP_CAT_DATA;
427*2654012fSReza Sabdar 						break;
428*2654012fSReza Sabdar 					case 3:
429*2654012fSReza Sabdar 						statarg |= NDMP_CAT_MOVER;
430*2654012fSReza Sabdar 						break;
431*2654012fSReza Sabdar 					default:
432*2654012fSReza Sabdar 						(void) fprintf(stderr,
433*2654012fSReza Sabdar 						    gettext("Invalid object "
434*2654012fSReza Sabdar 						    "type '%s'\n"), value);
435*2654012fSReza Sabdar 						usage(B_FALSE, cur_cmd);
436*2654012fSReza Sabdar 					}
437*2654012fSReza Sabdar 				}
438*2654012fSReza Sabdar 				break;
439*2654012fSReza Sabdar 			case ':':
440*2654012fSReza Sabdar 				(void) fprintf(stderr,
441*2654012fSReza Sabdar 				    gettext("Missing argument for "
442*2654012fSReza Sabdar 				    "'%c' option\n"), optopt);
443*2654012fSReza Sabdar 				usage(B_FALSE, cur_cmd);
444*2654012fSReza Sabdar 				break;
445*2654012fSReza Sabdar 			case '?':
446*2654012fSReza Sabdar 				(void) fprintf(stderr,
447*2654012fSReza Sabdar 				    gettext("Invalid option '%c'\n"), optopt);
448*2654012fSReza Sabdar 				usage(B_FALSE, cur_cmd);
449*2654012fSReza Sabdar 			}
450*2654012fSReza Sabdar 		}
451*2654012fSReza Sabdar 		/* if -i and its argument are not specified, display all */
452*2654012fSReza Sabdar 		if (statarg == 0)
453*2654012fSReza Sabdar 			statarg = NDMP_CAT_ALL;
454*2654012fSReza Sabdar 	}
455*2654012fSReza Sabdar 	/*
456*2654012fSReza Sabdar 	 * optind is initialized to 1 if the -i option is not used, otherwise
457*2654012fSReza Sabdar 	 * index to argv.
458*2654012fSReza Sabdar 	 */
459*2654012fSReza Sabdar 	argc -= optind;
460*2654012fSReza Sabdar 	argv += optind;
461*2654012fSReza Sabdar 
462*2654012fSReza Sabdar 	ret = ndmp_get_session_info(&sinfo, &num);
463*2654012fSReza Sabdar 	if (ret == -1) {
464*2654012fSReza Sabdar 		(void) fprintf(stdout,
465*2654012fSReza Sabdar 		    gettext("Could not get session information\n"));
466*2654012fSReza Sabdar 	} else {
467*2654012fSReza Sabdar 		if (argc == 0) {
468*2654012fSReza Sabdar 			ndmp_session_all_print(statarg, sinfo, num);
469*2654012fSReza Sabdar 		} else {
470*2654012fSReza Sabdar 			for (i = 0; i < argc; i++) {
471*2654012fSReza Sabdar 				sp = sinfo;
472*2654012fSReza Sabdar 				for (j = 0; j < num; j++, sp++) {
473*2654012fSReza Sabdar 					if (sp->nsi_sid == atoi(argv[i])) {
474*2654012fSReza Sabdar 						ndmp_session_print(statarg, sp);
475*2654012fSReza Sabdar 						(void) fprintf(stdout, "\n");
476*2654012fSReza Sabdar 						break;
477*2654012fSReza Sabdar 					}
478*2654012fSReza Sabdar 				}
479*2654012fSReza Sabdar 				if (j == num) {
480*2654012fSReza Sabdar 					(void) fprintf(stdout,
481*2654012fSReza Sabdar 					    gettext("Session %d not "
482*2654012fSReza Sabdar 					    "found\n"), atoi(argv[i]));
483*2654012fSReza Sabdar 				}
484*2654012fSReza Sabdar 			}
485*2654012fSReza Sabdar 		}
486*2654012fSReza Sabdar 		ndmp_get_session_info_free(sinfo, num);
487*2654012fSReza Sabdar 	}
488*2654012fSReza Sabdar 	return (0);
489*2654012fSReza Sabdar }
490*2654012fSReza Sabdar 
491*2654012fSReza Sabdar /*ARGSUSED*/
492*2654012fSReza Sabdar static int
493*2654012fSReza Sabdar ndmp_kill_sessions(int argc, char **argv, ndmp_command_t *cur_cmd)
494*2654012fSReza Sabdar {
495*2654012fSReza Sabdar 	int ret, i;
496*2654012fSReza Sabdar 
497*2654012fSReza Sabdar 	if (ndmp_door_status()) {
498*2654012fSReza Sabdar 		(void) fprintf(stdout,
499*2654012fSReza Sabdar 		    gettext("Service ndmpd not running.\n"));
500*2654012fSReza Sabdar 		return (-1);
501*2654012fSReza Sabdar 	}
502*2654012fSReza Sabdar 
503*2654012fSReza Sabdar 	/* If no arg is specified, print the usage and exit */
504*2654012fSReza Sabdar 	if (argc == 1)
505*2654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
506*2654012fSReza Sabdar 
507*2654012fSReza Sabdar 	for (i = 1; i < argc; i++) {
508*2654012fSReza Sabdar 		if (atoi(argv[i]) > 0) {
509*2654012fSReza Sabdar 			ret = ndmp_terminate_session(atoi(argv[i]));
510*2654012fSReza Sabdar 		} else {
511*2654012fSReza Sabdar 			(void) fprintf(stderr,
512*2654012fSReza Sabdar 			    gettext("Invalid argument %s\n"), argv[i]);
513*2654012fSReza Sabdar 				continue;
514*2654012fSReza Sabdar 		}
515*2654012fSReza Sabdar 		if (ret == -1)
516*2654012fSReza Sabdar 			(void) fprintf(stdout,
517*2654012fSReza Sabdar 			    gettext("Session id %d not found.\n"),
518*2654012fSReza Sabdar 			    atoi(argv[i]));
519*2654012fSReza Sabdar 	}
520*2654012fSReza Sabdar 	return (0);
521*2654012fSReza Sabdar }
522*2654012fSReza Sabdar 
523*2654012fSReza Sabdar static int
524*2654012fSReza Sabdar ndmp_get_password(char **password)
525*2654012fSReza Sabdar {
526*2654012fSReza Sabdar 	char *pw1, pw2[257];
527*2654012fSReza Sabdar 	int i;
528*2654012fSReza Sabdar 
529*2654012fSReza Sabdar 	for (i = 0; i < NDMP_PASSWORD_RETRIES; i++) {
530*2654012fSReza Sabdar 		/*
531*2654012fSReza Sabdar 		 * getpassphrase use the same buffer to return password, so
532*2654012fSReza Sabdar 		 * copy the result in different buffer, before calling the
533*2654012fSReza Sabdar 		 * getpassphrase again.
534*2654012fSReza Sabdar 		 */
535*2654012fSReza Sabdar 		if ((pw1 =
536*2654012fSReza Sabdar 		    getpassphrase(gettext("Enter new password: "))) != NULL) {
537*2654012fSReza Sabdar 			(void) strlcpy(pw2, pw1, sizeof (pw2));
538*2654012fSReza Sabdar 			if ((pw1 =
539*2654012fSReza Sabdar 			    getpassphrase(gettext("Re-enter  password: ")))
540*2654012fSReza Sabdar 			    != NULL) {
541*2654012fSReza Sabdar 				if (strncmp(pw1, pw2, strlen(pw1)) == 0) {
542*2654012fSReza Sabdar 					*password = pw1;
543*2654012fSReza Sabdar 					return (0);
544*2654012fSReza Sabdar 				} else {
545*2654012fSReza Sabdar 					(void) fprintf(stderr,
546*2654012fSReza Sabdar 					    gettext("Both password did not "
547*2654012fSReza Sabdar 					    "match.\n"));
548*2654012fSReza Sabdar 				}
549*2654012fSReza Sabdar 			}
550*2654012fSReza Sabdar 		}
551*2654012fSReza Sabdar 	}
552*2654012fSReza Sabdar 	return (-1);
553*2654012fSReza Sabdar }
554*2654012fSReza Sabdar 
555*2654012fSReza Sabdar static int
556*2654012fSReza Sabdar ndmp_enable_auth(int argc, char **argv, ndmp_command_t *cur_cmd)
557*2654012fSReza Sabdar {
558*2654012fSReza Sabdar 	char *auth_type, *username, *password;
559*2654012fSReza Sabdar 	int c, i, auth_type_flag = 0;
560*2654012fSReza Sabdar 	char *enc_password;
561*2654012fSReza Sabdar 
562*2654012fSReza Sabdar 	/* enable <-a auth-type> <-u username> */
563*2654012fSReza Sabdar 	if (argc != 5) {
564*2654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
565*2654012fSReza Sabdar 	}
566*2654012fSReza Sabdar 
567*2654012fSReza Sabdar 	while ((c = getopt(argc, argv, ":a:u:")) != -1) {
568*2654012fSReza Sabdar 		switch (c) {
569*2654012fSReza Sabdar 		case 'a':
570*2654012fSReza Sabdar 			auth_type = strdup(optarg);
571*2654012fSReza Sabdar 			break;
572*2654012fSReza Sabdar 		case 'u':
573*2654012fSReza Sabdar 			username = strdup(optarg);
574*2654012fSReza Sabdar 			break;
575*2654012fSReza Sabdar 		case ':':
576*2654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Option -%c "
577*2654012fSReza Sabdar 			    "requires an operand\n"), optopt);
578*2654012fSReza Sabdar 			usage(B_FALSE, cur_cmd);
579*2654012fSReza Sabdar 			break;
580*2654012fSReza Sabdar 		case '?':
581*2654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Unrecognized "
582*2654012fSReza Sabdar 			    "option: -%c\n"), optopt);
583*2654012fSReza Sabdar 			usage(B_FALSE, cur_cmd);
584*2654012fSReza Sabdar 		}
585*2654012fSReza Sabdar 	}
586*2654012fSReza Sabdar 
587*2654012fSReza Sabdar 	if ((auth_type) && (username)) {
588*2654012fSReza Sabdar 		if (ndmp_get_password(&password)) {
589*2654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Could not get correct "
590*2654012fSReza Sabdar 			    "password, exiting..."));
591*2654012fSReza Sabdar 			free(auth_type);
592*2654012fSReza Sabdar 			free(username);
593*2654012fSReza Sabdar 			exit(-1);
594*2654012fSReza Sabdar 		}
595*2654012fSReza Sabdar 	} else {
596*2654012fSReza Sabdar 		(void) fprintf(stderr, gettext("%s or %s can not be blank"),
597*2654012fSReza Sabdar 		    "'auth-type'", "'username'");
598*2654012fSReza Sabdar 		free(auth_type);
599*2654012fSReza Sabdar 		free(username);
600*2654012fSReza Sabdar 		exit(-1);
601*2654012fSReza Sabdar 	}
602*2654012fSReza Sabdar 
603*2654012fSReza Sabdar 	if ((enc_password = ndmp_base64_encode(password)) == NULL) {
604*2654012fSReza Sabdar 		(void) fprintf(stdout,
605*2654012fSReza Sabdar 		    gettext("Could not encode password - %s\n"),
606*2654012fSReza Sabdar 		    ndmp_strerror(ndmp_errno));
607*2654012fSReza Sabdar 		free(auth_type);
608*2654012fSReza Sabdar 		free(username);
609*2654012fSReza Sabdar 		exit(-1);
610*2654012fSReza Sabdar 	}
611*2654012fSReza Sabdar 
612*2654012fSReza Sabdar 	for (i = 0; i < NAUTH; i++) {
613*2654012fSReza Sabdar 		if (strncmp(auth_type, ndmp_auth_table[i].auth_type,
614*2654012fSReza Sabdar 		    strlen(ndmp_auth_table[i].auth_type)) == 0) {
615*2654012fSReza Sabdar 			auth_type_flag = 1;
616*2654012fSReza Sabdar 			if ((ndmp_set_prop((char *)ndmp_auth_table[i].username,
617*2654012fSReza Sabdar 			    username)) == -1) {
618*2654012fSReza Sabdar 				(void) fprintf(stdout,
619*2654012fSReza Sabdar 				    gettext("Could not set username - %s\n"),
620*2654012fSReza Sabdar 				    ndmp_strerror(ndmp_errno));
621*2654012fSReza Sabdar 				continue;
622*2654012fSReza Sabdar 			}
623*2654012fSReza Sabdar 			if ((ndmp_set_prop((char *)ndmp_auth_table[i].password,
624*2654012fSReza Sabdar 			    enc_password)) == -1) {
625*2654012fSReza Sabdar 				(void) fprintf(stdout,
626*2654012fSReza Sabdar 				    gettext("Could not set password - %s\n"),
627*2654012fSReza Sabdar 				    ndmp_strerror(ndmp_errno));
628*2654012fSReza Sabdar 				continue;
629*2654012fSReza Sabdar 			}
630*2654012fSReza Sabdar 			if (!ndmp_door_status() &&
631*2654012fSReza Sabdar 			    (ndmp_service_refresh()) == -1) {
632*2654012fSReza Sabdar 				(void) fprintf(stdout,
633*2654012fSReza Sabdar 				    gettext("Could not refesh ndmpd service "
634*2654012fSReza Sabdar 				    "properties\n"));
635*2654012fSReza Sabdar 			}
636*2654012fSReza Sabdar 		}
637*2654012fSReza Sabdar 	}
638*2654012fSReza Sabdar 	free(auth_type);
639*2654012fSReza Sabdar 	free(username);
640*2654012fSReza Sabdar 	free(enc_password);
641*2654012fSReza Sabdar 
642*2654012fSReza Sabdar 	if (!auth_type_flag)
643*2654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
644*2654012fSReza Sabdar 
645*2654012fSReza Sabdar 	return (0);
646*2654012fSReza Sabdar }
647*2654012fSReza Sabdar 
648*2654012fSReza Sabdar static int
649*2654012fSReza Sabdar ndmp_disable_auth(int argc, char **argv, ndmp_command_t *cur_cmd)
650*2654012fSReza Sabdar {
651*2654012fSReza Sabdar 	char *auth_type;
652*2654012fSReza Sabdar 	int c, i, auth_type_flag = 0;
653*2654012fSReza Sabdar 
654*2654012fSReza Sabdar 	/* disable <-a auth-type> */
655*2654012fSReza Sabdar 	if (argc != 3) {
656*2654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
657*2654012fSReza Sabdar 	}
658*2654012fSReza Sabdar 
659*2654012fSReza Sabdar 	while ((c = getopt(argc, argv, ":a:")) != -1) {
660*2654012fSReza Sabdar 		switch (c) {
661*2654012fSReza Sabdar 		case 'a':
662*2654012fSReza Sabdar 			auth_type = strdup(optarg);
663*2654012fSReza Sabdar 			break;
664*2654012fSReza Sabdar 		case ':':
665*2654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Option -%c "
666*2654012fSReza Sabdar 			    "requires an operand\n"), optopt);
667*2654012fSReza Sabdar 			break;
668*2654012fSReza Sabdar 		case '?':
669*2654012fSReza Sabdar 			(void) fprintf(stderr, gettext("Unrecognized "
670*2654012fSReza Sabdar 			    "option: -%c\n"), optopt);
671*2654012fSReza Sabdar 		}
672*2654012fSReza Sabdar 	}
673*2654012fSReza Sabdar 	for (i = 0; i < NAUTH; i++) {
674*2654012fSReza Sabdar 		if (strncmp(auth_type, ndmp_auth_table[i].auth_type,
675*2654012fSReza Sabdar 		    strlen(ndmp_auth_table[i].auth_type)) == 0) {
676*2654012fSReza Sabdar 			auth_type_flag = 1;
677*2654012fSReza Sabdar 			if ((ndmp_set_prop((char *)ndmp_auth_table[i].username,
678*2654012fSReza Sabdar 			    "")) == -1) {
679*2654012fSReza Sabdar 				(void) fprintf(stdout,
680*2654012fSReza Sabdar 				    gettext("Could not clear username - %s\n"),
681*2654012fSReza Sabdar 				    ndmp_strerror(ndmp_errno));
682*2654012fSReza Sabdar 				continue;
683*2654012fSReza Sabdar 			}
684*2654012fSReza Sabdar 			if ((ndmp_set_prop((char *)ndmp_auth_table[i].password,
685*2654012fSReza Sabdar 			    "")) == -1) {
686*2654012fSReza Sabdar 				(void) fprintf(stdout,
687*2654012fSReza Sabdar 				    gettext("Could not clear password - %s\n"),
688*2654012fSReza Sabdar 				    ndmp_strerror(ndmp_errno));
689*2654012fSReza Sabdar 				continue;
690*2654012fSReza Sabdar 			}
691*2654012fSReza Sabdar 			if (!ndmp_door_status() &&
692*2654012fSReza Sabdar 			    (ndmp_service_refresh()) == -1) {
693*2654012fSReza Sabdar 				(void) fprintf(stdout, gettext("Could not "
694*2654012fSReza Sabdar 				    "refesh ndmpd service properties\n"));
695*2654012fSReza Sabdar 			}
696*2654012fSReza Sabdar 		}
697*2654012fSReza Sabdar 	}
698*2654012fSReza Sabdar 	free(auth_type);
699*2654012fSReza Sabdar 
700*2654012fSReza Sabdar 	if (!auth_type_flag)
701*2654012fSReza Sabdar 		usage(B_FALSE, cur_cmd);
702*2654012fSReza Sabdar 
703*2654012fSReza Sabdar 	return (0);
704*2654012fSReza Sabdar }
705*2654012fSReza Sabdar 
706*2654012fSReza Sabdar int
707*2654012fSReza Sabdar main(int argc, char **argv)
708*2654012fSReza Sabdar {
709*2654012fSReza Sabdar 	int ret;
710*2654012fSReza Sabdar 	int i;
711*2654012fSReza Sabdar 	char *cmdname;
712*2654012fSReza Sabdar 	ndmp_command_t	*current_command = NULL;
713*2654012fSReza Sabdar 
714*2654012fSReza Sabdar 	(void) setlocale(LC_ALL, "");
715*2654012fSReza Sabdar 	(void) textdomain(TEXT_DOMAIN);
716*2654012fSReza Sabdar 
717*2654012fSReza Sabdar 	opterr = 0;
718*2654012fSReza Sabdar 
719*2654012fSReza Sabdar 	/* Make sure the user has specified some command. */
720*2654012fSReza Sabdar 	if (argc < 2) {
721*2654012fSReza Sabdar 		(void) fprintf(stderr, gettext("Missing command.\n"));
722*2654012fSReza Sabdar 		usage(B_FALSE, current_command);
723*2654012fSReza Sabdar 	}
724*2654012fSReza Sabdar 
725*2654012fSReza Sabdar 	cmdname = argv[1];
726*2654012fSReza Sabdar 
727*2654012fSReza Sabdar 	/*
728*2654012fSReza Sabdar 	 * Special case '-?'
729*2654012fSReza Sabdar 	 */
730*2654012fSReza Sabdar 	if (strcmp(cmdname, "-?") == 0)
731*2654012fSReza Sabdar 		usage(B_TRUE, current_command);
732*2654012fSReza Sabdar 
733*2654012fSReza Sabdar 	/*
734*2654012fSReza Sabdar 	 * Run the appropriate sub-command.
735*2654012fSReza Sabdar 	 */
736*2654012fSReza Sabdar 	for (i = 0; i < NCOMMAND; i++) {
737*2654012fSReza Sabdar 		if (strcmp(cmdname, command_table[i].nc_name) == 0) {
738*2654012fSReza Sabdar 			current_command = &command_table[i];
739*2654012fSReza Sabdar 			ret = command_table[i].func(argc - 1, argv + 1,
740*2654012fSReza Sabdar 			    current_command);
741*2654012fSReza Sabdar 			break;
742*2654012fSReza Sabdar 		}
743*2654012fSReza Sabdar 	}
744*2654012fSReza Sabdar 
745*2654012fSReza Sabdar 	if (i == NCOMMAND) {
746*2654012fSReza Sabdar 		(void) fprintf(stderr, gettext("Unrecognized "
747*2654012fSReza Sabdar 		    "command '%s'\n"), cmdname);
748*2654012fSReza Sabdar 		usage(B_FALSE, current_command);
749*2654012fSReza Sabdar 	}
750*2654012fSReza Sabdar 
751*2654012fSReza Sabdar 	return (ret);
752*2654012fSReza Sabdar }
753