xref: /titanic_54/usr/src/cmd/vscan/vscanadm/vscanadm.c (revision 911106dfb16696472af8c1b7b4c554a829354fa8)
1*911106dfSjm199354 /*
2*911106dfSjm199354  * CDDL HEADER START
3*911106dfSjm199354  *
4*911106dfSjm199354  * The contents of this file are subject to the terms of the
5*911106dfSjm199354  * Common Development and Distribution License (the "License").
6*911106dfSjm199354  * You may not use this file except in compliance with the License.
7*911106dfSjm199354  *
8*911106dfSjm199354  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*911106dfSjm199354  * or http://www.opensolaris.org/os/licensing.
10*911106dfSjm199354  * See the License for the specific language governing permissions
11*911106dfSjm199354  * and limitations under the License.
12*911106dfSjm199354  *
13*911106dfSjm199354  * When distributing Covered Code, include this CDDL HEADER in each
14*911106dfSjm199354  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*911106dfSjm199354  * If applicable, add the following below this CDDL HEADER, with the
16*911106dfSjm199354  * fields enclosed by brackets "[]" replaced with your own identifying
17*911106dfSjm199354  * information: Portions Copyright [yyyy] [name of copyright owner]
18*911106dfSjm199354  *
19*911106dfSjm199354  * CDDL HEADER END
20*911106dfSjm199354  */
21*911106dfSjm199354 /*
22*911106dfSjm199354  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23*911106dfSjm199354  * Use is subject to license terms.
24*911106dfSjm199354  */
25*911106dfSjm199354 #pragma ident	"%Z%%M%	%I%	%E% SMI"
26*911106dfSjm199354 
27*911106dfSjm199354 
28*911106dfSjm199354 #include <stdio.h>
29*911106dfSjm199354 #include <strings.h>
30*911106dfSjm199354 #include <limits.h>
31*911106dfSjm199354 #include <stdlib.h>
32*911106dfSjm199354 #include <stdarg.h>
33*911106dfSjm199354 #include <errno.h>
34*911106dfSjm199354 #include <ctype.h>
35*911106dfSjm199354 #include <arpa/inet.h>
36*911106dfSjm199354 #include <unistd.h>
37*911106dfSjm199354 #include <sys/types.h>
38*911106dfSjm199354 #include <sys/stat.h>
39*911106dfSjm199354 #include <fcntl.h>
40*911106dfSjm199354 #include <libintl.h>
41*911106dfSjm199354 #include <libvscan.h>
42*911106dfSjm199354 
43*911106dfSjm199354 
44*911106dfSjm199354 /* Property Names */
45*911106dfSjm199354 #define	VS_ADM_MAXSIZE		"max-size"
46*911106dfSjm199354 #define	VS_ADM_MAXSIZE_ACTION	"max-size-action"
47*911106dfSjm199354 #define	VS_ADM_TYPES		"types"
48*911106dfSjm199354 
49*911106dfSjm199354 /* Scan Engine Property Names */
50*911106dfSjm199354 #define	VS_ADM_SE_ENABLE	"enable"
51*911106dfSjm199354 #define	VS_ADM_SE_HOST		"host"
52*911106dfSjm199354 #define	VS_ADM_SE_PORT		"port"
53*911106dfSjm199354 #define	VS_ADM_SE_MAXCONN	"max-connection"
54*911106dfSjm199354 
55*911106dfSjm199354 /* Property Values */
56*911106dfSjm199354 #define	VS_ADM_ON		"on"
57*911106dfSjm199354 #define	VS_ADM_OFF		"off"
58*911106dfSjm199354 #define	VS_ADM_ALLOW		"allow"
59*911106dfSjm199354 #define	VS_ADM_DENY		"deny"
60*911106dfSjm199354 
61*911106dfSjm199354 
62*911106dfSjm199354 /*
63*911106dfSjm199354  * Print buffer length: used for sizing buffers that are filled with
64*911106dfSjm199354  * user-readable strings for property values. Define a number that
65*911106dfSjm199354  * accounts for some pre-value information, and won't (likely)
66*911106dfSjm199354  * wrap an 80-column display
67*911106dfSjm199354  */
68*911106dfSjm199354 #define	VS_ADM_PRINT_BUF_LEN	4096
69*911106dfSjm199354 
70*911106dfSjm199354 /* Program exit codes */
71*911106dfSjm199354 #define	VS_ADM_EXIT_SUCCESS	0
72*911106dfSjm199354 #define	VS_ADM_EXIT_ERROR	1
73*911106dfSjm199354 #define	VS_ADM_EXIT_USAGE	2
74*911106dfSjm199354 
75*911106dfSjm199354 
76*911106dfSjm199354 /*
77*911106dfSjm199354  * vscanadm property definition. Maps the property ids to a
78*911106dfSjm199354  * property name, and includes functions to convert to and from
79*911106dfSjm199354  * input strings and native data.
80*911106dfSjm199354  */
81*911106dfSjm199354 typedef struct vs_adm_property {
82*911106dfSjm199354 	const char *vap_name;
83*911106dfSjm199354 	uint64_t vap_id;
84*911106dfSjm199354 	int (*vap_parse)(const char *, void *);
85*911106dfSjm199354 	int (*vap_unparse)(const void *, char *, size_t);
86*911106dfSjm199354 } vs_adm_property_t;
87*911106dfSjm199354 
88*911106dfSjm199354 
89*911106dfSjm199354 /* usage/help information for subcommnds */
90*911106dfSjm199354 #define	VS_ADM_HELP_GET		("[-p property]...\n" \
91*911106dfSjm199354 	"\tdisplay vscan properties")
92*911106dfSjm199354 #define	VS_ADM_HELP_SET		("-p property=value [-p property=value]...\n" \
93*911106dfSjm199354 	"\tset values of vscan properties")
94*911106dfSjm199354 #define	VS_ADM_HELP_GET_ENG	("[-p property] [engine_id]\n" \
95*911106dfSjm199354 	"\tdisplay values of scan engine properties")
96*911106dfSjm199354 #define	VS_ADM_HELP_ADD_ENG	("[-p property=value]... engine_id\n" \
97*911106dfSjm199354 	"\tadd scan engine")
98*911106dfSjm199354 #define	VS_ADM_HELP_SET_ENG	("-p property=value [-p property=value]" \
99*911106dfSjm199354 	"... engine_id\n\tset values of scan engine properties")
100*911106dfSjm199354 #define	VS_ADM_HELP_REM_ENG	("engine_id\n" \
101*911106dfSjm199354 	"\tremove scan engine")
102*911106dfSjm199354 #define	VS_ADM_HELP_SHOW	("\n\tdisplay the values of all vscan " \
103*911106dfSjm199354 	"service and scan engine properties")
104*911106dfSjm199354 #define	VS_ADM_HELP_STATS	("[-z]\n\tdisplay vscan service statistics")
105*911106dfSjm199354 #define	VS_ADM_HELP_IMPORT	("-p property filename\n" \
106*911106dfSjm199354 	"\timport property from file")
107*911106dfSjm199354 #define	VS_ADM_HELP_EXPORT	("-p property filename\n" \
108*911106dfSjm199354 	"\texport property to file")
109*911106dfSjm199354 #define	VS_ADM_HELP_VALIDATE	("-p property filename\n" \
110*911106dfSjm199354 	"\tvalidate property in file")
111*911106dfSjm199354 
112*911106dfSjm199354 
113*911106dfSjm199354 /*
114*911106dfSjm199354  * vscanadm command structure. Encapsulates the vscanadm
115*911106dfSjm199354  * subcommand name, pointer to the subcommand implementation
116*911106dfSjm199354  * function, and a help id to get usage/help information.
117*911106dfSjm199354  */
118*911106dfSjm199354 typedef struct vs_adm_cmd {
119*911106dfSjm199354 	int (*vac_func)(int, char *[]);
120*911106dfSjm199354 	const char *vac_name;
121*911106dfSjm199354 	char *vac_helpid;
122*911106dfSjm199354 }
123*911106dfSjm199354 vs_adm_cmd_t;
124*911106dfSjm199354 
125*911106dfSjm199354 
126*911106dfSjm199354 /* Subcommand implementation functions */
127*911106dfSjm199354 static int vs_adm_set(int, char **);
128*911106dfSjm199354 static int vs_adm_get(int, char **);
129*911106dfSjm199354 static int vs_adm_set_engine(int, char **);
130*911106dfSjm199354 static int vs_adm_get_engine(int, char **);
131*911106dfSjm199354 static int vs_adm_rem_engine(int, char **);
132*911106dfSjm199354 static int vs_adm_show(int, char **);
133*911106dfSjm199354 static int vs_adm_stats(int, char **);
134*911106dfSjm199354 static int vs_adm_import(int, char **);
135*911106dfSjm199354 static int vs_adm_export(int, char **);
136*911106dfSjm199354 static int vs_adm_validate(int, char **);
137*911106dfSjm199354 
138*911106dfSjm199354 
139*911106dfSjm199354 /*
140*911106dfSjm199354  * Parse routines to transform libvscan API data into user-readable strings
141*911106dfSjm199354  */
142*911106dfSjm199354 static int vs_adm_parse_maxsize(const char *, void *);
143*911106dfSjm199354 static int vs_adm_parse_maxsize_action(const char *, void *);
144*911106dfSjm199354 static int vs_adm_parse_types(const char *, void *);
145*911106dfSjm199354 static int vs_adm_parse_enable(const char *, void *);
146*911106dfSjm199354 static int vs_adm_parse_host(const char *, void *);
147*911106dfSjm199354 static int vs_adm_parse_port(const char *, void *);
148*911106dfSjm199354 static int vs_adm_parse_maxconn(const char *, void *);
149*911106dfSjm199354 
150*911106dfSjm199354 
151*911106dfSjm199354 /*
152*911106dfSjm199354  * Unparse routines to transform strings from the user input into
153*911106dfSjm199354  * API native data.
154*911106dfSjm199354  *
155*911106dfSjm199354  * While some value validation is performed in the course of unparsing
156*911106dfSjm199354  * string data, complete value validation is left to libvscan.
157*911106dfSjm199354  * Values that are in unacceptable form, out of range, or otherwise
158*911106dfSjm199354  * violate rules for a given property will be rejected
159*911106dfSjm199354  */
160*911106dfSjm199354 static int vs_adm_unparse_maxsize(const void *, char *, size_t);
161*911106dfSjm199354 static int vs_adm_unparse_maxsize_action(const void *, char *, size_t);
162*911106dfSjm199354 static int vs_adm_unparse_types(const void *, char *, size_t);
163*911106dfSjm199354 static int vs_adm_unparse_enable(const void *, char *, size_t);
164*911106dfSjm199354 static int vs_adm_unparse_host(const void *, char *, size_t);
165*911106dfSjm199354 static int vs_adm_unparse_port(const void *, char *, size_t);
166*911106dfSjm199354 static int vs_adm_unparse_maxconn(const void *, char *, size_t);
167*911106dfSjm199354 
168*911106dfSjm199354 
169*911106dfSjm199354 /*
170*911106dfSjm199354  * The properties table includes a vscanadm property entry, specifying
171*911106dfSjm199354  * the property nane, property id, parse amd inparse methods,
172*911106dfSjm199354  * for each vscanadm property.
173*911106dfSjm199354  */
174*911106dfSjm199354 static const vs_adm_property_t vs_adm_props_all[] = {
175*911106dfSjm199354 	{ VS_ADM_MAXSIZE, VS_PROPID_MAXSIZE,
176*911106dfSjm199354 		vs_adm_parse_maxsize, vs_adm_unparse_maxsize },
177*911106dfSjm199354 	{ VS_ADM_MAXSIZE_ACTION, VS_PROPID_MAXSIZE_ACTION,
178*911106dfSjm199354 		vs_adm_parse_maxsize_action, vs_adm_unparse_maxsize_action },
179*911106dfSjm199354 	{ VS_ADM_TYPES, VS_PROPID_TYPES,
180*911106dfSjm199354 		vs_adm_parse_types, vs_adm_unparse_types },
181*911106dfSjm199354 	{ VS_ADM_SE_ENABLE, VS_PROPID_SE_ENABLE,
182*911106dfSjm199354 		vs_adm_parse_enable, vs_adm_unparse_enable },
183*911106dfSjm199354 	{ VS_ADM_SE_HOST, VS_PROPID_SE_HOST,
184*911106dfSjm199354 		vs_adm_parse_host, vs_adm_unparse_host },
185*911106dfSjm199354 	{ VS_ADM_SE_PORT, VS_PROPID_SE_PORT,
186*911106dfSjm199354 		vs_adm_parse_port, vs_adm_unparse_port },
187*911106dfSjm199354 	{ VS_ADM_SE_MAXCONN, VS_PROPID_SE_MAXCONN,
188*911106dfSjm199354 		vs_adm_parse_maxconn, vs_adm_unparse_maxconn },
189*911106dfSjm199354 	{ NULL, 0, NULL, NULL }
190*911106dfSjm199354 };
191*911106dfSjm199354 
192*911106dfSjm199354 
193*911106dfSjm199354 /*
194*911106dfSjm199354  * The subcommand table.  Used to find the subcommand specified
195*911106dfSjm199354  * by the user and dispatch the processing for the subcommand.
196*911106dfSjm199354  * Also used to display usage information for each subcommand.
197*911106dfSjm199354  */
198*911106dfSjm199354 static const vs_adm_cmd_t vs_adm_cmds[] =
199*911106dfSjm199354 {
200*911106dfSjm199354 	{ vs_adm_get, "get", VS_ADM_HELP_GET },
201*911106dfSjm199354 	{ vs_adm_set, "set", VS_ADM_HELP_SET },
202*911106dfSjm199354 	{ vs_adm_get_engine, "get-engine", VS_ADM_HELP_GET_ENG },
203*911106dfSjm199354 	{ vs_adm_set_engine, "set-engine", VS_ADM_HELP_SET_ENG },
204*911106dfSjm199354 	{ vs_adm_set_engine, "add-engine", VS_ADM_HELP_ADD_ENG },
205*911106dfSjm199354 	{ vs_adm_rem_engine, "remove-engine", VS_ADM_HELP_REM_ENG },
206*911106dfSjm199354 	{ vs_adm_import, "import", VS_ADM_HELP_IMPORT },
207*911106dfSjm199354 	{ vs_adm_export, "export", VS_ADM_HELP_EXPORT },
208*911106dfSjm199354 	{ vs_adm_validate, "validate", VS_ADM_HELP_VALIDATE },
209*911106dfSjm199354 	{ vs_adm_show, "show", VS_ADM_HELP_SHOW },
210*911106dfSjm199354 	{ vs_adm_stats, "stats", VS_ADM_HELP_STATS },
211*911106dfSjm199354 	{ NULL, NULL, NULL }
212*911106dfSjm199354 };
213*911106dfSjm199354 
214*911106dfSjm199354 
215*911106dfSjm199354 static const char *vs_adm_cmd;
216*911106dfSjm199354 static const char *vs_adm_subcmd;
217*911106dfSjm199354 
218*911106dfSjm199354 static int vs_adm_usage(FILE *);
219*911106dfSjm199354 static int vs_adm_props_from_input(int, char **, vs_props_t *, uint64_t *);
220*911106dfSjm199354 static void vs_adm_output_getcmd(uint64_t, const void *);
221*911106dfSjm199354 static void vs_adm_output_stats(vs_stats_t *);
222*911106dfSjm199354 static const vs_adm_property_t *vs_adm_prop_by_name(const char *);
223*911106dfSjm199354 static const vs_adm_property_t *vs_adm_prop_by_id(const uint64_t);
224*911106dfSjm199354 static int vs_adm_parse(const vs_adm_property_t *, const char *, void *);
225*911106dfSjm199354 static void vs_adm_unparse(const vs_adm_property_t *, const void *,
226*911106dfSjm199354     char *, size_t);
227*911106dfSjm199354 
228*911106dfSjm199354 static int vs_adm_file_read(char *, char *, int);
229*911106dfSjm199354 static int vs_adm_file_write(char *, char *);
230*911106dfSjm199354 static int vs_adm_file_usage(int argc, char **argv);
231*911106dfSjm199354 
232*911106dfSjm199354 /*
233*911106dfSjm199354  * main
234*911106dfSjm199354  */
235*911106dfSjm199354 int
236*911106dfSjm199354 main(int argc, char **argv)
237*911106dfSjm199354 {
238*911106dfSjm199354 	const vs_adm_cmd_t *cp;
239*911106dfSjm199354 	const char *p;
240*911106dfSjm199354 	int i, err;
241*911106dfSjm199354 
242*911106dfSjm199354 	/* executable and subcommand names */
243*911106dfSjm199354 	if ((p = strrchr(argv[0], '/')) == NULL)
244*911106dfSjm199354 		vs_adm_cmd = argv[0];
245*911106dfSjm199354 	else
246*911106dfSjm199354 		vs_adm_cmd = p + 1;
247*911106dfSjm199354 
248*911106dfSjm199354 	vs_adm_subcmd = argv[1];
249*911106dfSjm199354 
250*911106dfSjm199354 	/* require at least command and sub-command */
251*911106dfSjm199354 	if (argc < 2)
252*911106dfSjm199354 		return (vs_adm_usage(stdout));
253*911106dfSjm199354 
254*911106dfSjm199354 	/* Check for the "-?" help switch */
255*911106dfSjm199354 	for (i = 1; i < argc; i++) {
256*911106dfSjm199354 		if (strcmp(argv[i], "-?") == 0)
257*911106dfSjm199354 			return (vs_adm_usage(stdout));
258*911106dfSjm199354 	}
259*911106dfSjm199354 
260*911106dfSjm199354 	/* Locate the specified subcommand */
261*911106dfSjm199354 	for (cp = vs_adm_cmds; cp->vac_name != NULL; cp++) {
262*911106dfSjm199354 		if (strcmp(cp->vac_name, vs_adm_subcmd) == 0)
263*911106dfSjm199354 			break;
264*911106dfSjm199354 	}
265*911106dfSjm199354 
266*911106dfSjm199354 	if (cp->vac_name == NULL) {
267*911106dfSjm199354 		(void) fprintf(stderr, "%s: %s -- %s\n",
268*911106dfSjm199354 		    gettext("invalid subcommand"),
269*911106dfSjm199354 		    vs_adm_cmd, vs_adm_subcmd);
270*911106dfSjm199354 		return (vs_adm_usage(stderr));
271*911106dfSjm199354 	}
272*911106dfSjm199354 
273*911106dfSjm199354 	/* invoke sub-command handler */
274*911106dfSjm199354 	err = cp->vac_func(argc, argv);
275*911106dfSjm199354 
276*911106dfSjm199354 	return (err == VS_ADM_EXIT_USAGE ? vs_adm_usage(stderr) : err);
277*911106dfSjm199354 }
278*911106dfSjm199354 
279*911106dfSjm199354 
280*911106dfSjm199354 /*
281*911106dfSjm199354  * vs_adm_usage
282*911106dfSjm199354  */
283*911106dfSjm199354 static int
284*911106dfSjm199354 vs_adm_usage(FILE *fp)
285*911106dfSjm199354 {
286*911106dfSjm199354 	const vs_adm_cmd_t *cp;
287*911106dfSjm199354 
288*911106dfSjm199354 	for (cp = vs_adm_cmds; cp->vac_name != NULL; cp++) {
289*911106dfSjm199354 		(void) fprintf(fp, "%s %s", vs_adm_cmd, cp->vac_name);
290*911106dfSjm199354 		if (cp->vac_helpid != NULL)
291*911106dfSjm199354 			(void) fprintf(fp, " %s\n", cp->vac_helpid);
292*911106dfSjm199354 	}
293*911106dfSjm199354 
294*911106dfSjm199354 	return (VS_ADM_EXIT_USAGE);
295*911106dfSjm199354 }
296*911106dfSjm199354 
297*911106dfSjm199354 
298*911106dfSjm199354 /*
299*911106dfSjm199354  * vs_adm_get
300*911106dfSjm199354  *
301*911106dfSjm199354  * Gets and displays general vscan service configuration properties.
302*911106dfSjm199354  */
303*911106dfSjm199354 static int
304*911106dfSjm199354 vs_adm_get(int argc, char **argv)
305*911106dfSjm199354 {
306*911106dfSjm199354 	uint64_t propids;
307*911106dfSjm199354 	int i, rc;
308*911106dfSjm199354 	vs_props_t vp;
309*911106dfSjm199354 	const vs_adm_property_t *vap;
310*911106dfSjm199354 
311*911106dfSjm199354 	(void) memset(&vp, 0, sizeof (vp));
312*911106dfSjm199354 
313*911106dfSjm199354 	if (argc <= 2) {
314*911106dfSjm199354 		propids = VS_PROPID_GEN_ALL;
315*911106dfSjm199354 	} else {
316*911106dfSjm199354 		propids = 0LL;
317*911106dfSjm199354 		for (i = 2; i < argc; i++) {
318*911106dfSjm199354 			/* the "-p" specifier is optional */
319*911106dfSjm199354 			if (strcmp(argv[i], "-p") == 0) {
320*911106dfSjm199354 				if (++i >= argc)
321*911106dfSjm199354 					return (VS_ADM_EXIT_USAGE);
322*911106dfSjm199354 			}
323*911106dfSjm199354 
324*911106dfSjm199354 			if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
325*911106dfSjm199354 				(void) fprintf(stderr, "%s '%s'\n",
326*911106dfSjm199354 				    gettext("invalid property"), argv[i]);
327*911106dfSjm199354 				return (VS_ADM_EXIT_ERROR);
328*911106dfSjm199354 			}
329*911106dfSjm199354 
330*911106dfSjm199354 			propids |= vap->vap_id;
331*911106dfSjm199354 		}
332*911106dfSjm199354 	}
333*911106dfSjm199354 
334*911106dfSjm199354 	rc = vs_props_get(&vp, propids);
335*911106dfSjm199354 	if (rc != VS_ERR_NONE) {
336*911106dfSjm199354 		(void) fprintf(stderr, "%s\n", vs_strerror(rc));
337*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
338*911106dfSjm199354 	}
339*911106dfSjm199354 
340*911106dfSjm199354 	vs_adm_output_getcmd(propids, &vp);
341*911106dfSjm199354 
342*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
343*911106dfSjm199354 }
344*911106dfSjm199354 
345*911106dfSjm199354 
346*911106dfSjm199354 /*
347*911106dfSjm199354  * vs_adm_set
348*911106dfSjm199354  *
349*911106dfSjm199354  * Sets values for general vscan service configuration properties
350*911106dfSjm199354  *
351*911106dfSjm199354  * Calls a common function used by the set, add, and remove
352*911106dfSjm199354  * subcommands to modify general property values.
353*911106dfSjm199354  */
354*911106dfSjm199354 static int
355*911106dfSjm199354 vs_adm_set(int argc, char **argv)
356*911106dfSjm199354 {
357*911106dfSjm199354 	vs_props_t vp;
358*911106dfSjm199354 	uint64_t propids;
359*911106dfSjm199354 	int rc;
360*911106dfSjm199354 
361*911106dfSjm199354 	if (argc < 3)
362*911106dfSjm199354 		return (VS_ADM_EXIT_USAGE);
363*911106dfSjm199354 
364*911106dfSjm199354 	rc = vs_adm_props_from_input(argc, argv, &vp, &propids);
365*911106dfSjm199354 	if (rc != VS_ADM_EXIT_SUCCESS)
366*911106dfSjm199354 		return (rc);
367*911106dfSjm199354 
368*911106dfSjm199354 	rc = vs_props_set(&vp, propids);
369*911106dfSjm199354 	if (rc != VS_ERR_NONE) {
370*911106dfSjm199354 		(void) fprintf(stderr, "%s\n", vs_strerror(rc));
371*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
372*911106dfSjm199354 	}
373*911106dfSjm199354 
374*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
375*911106dfSjm199354 }
376*911106dfSjm199354 
377*911106dfSjm199354 
378*911106dfSjm199354 /*
379*911106dfSjm199354  * vs_adm_get_engine
380*911106dfSjm199354  *
381*911106dfSjm199354  * Gets and displays scan engine configuration properties for
382*911106dfSjm199354  * one or more scan engines.
383*911106dfSjm199354  */
384*911106dfSjm199354 static int
385*911106dfSjm199354 vs_adm_get_engine(int argc, char **argv)
386*911106dfSjm199354 {
387*911106dfSjm199354 	int i, rc;
388*911106dfSjm199354 	uint64_t propids;
389*911106dfSjm199354 	char *engid = NULL;
390*911106dfSjm199354 	const vs_adm_property_t *vap;
391*911106dfSjm199354 	vs_props_all_t va;
392*911106dfSjm199354 
393*911106dfSjm199354 	propids = 0LL;
394*911106dfSjm199354 	for (i = 2; i < argc; i++) {
395*911106dfSjm199354 		/* if not preceded by -p, must be engine id and must be last */
396*911106dfSjm199354 		if (strcmp(argv[i], "-p") != 0) {
397*911106dfSjm199354 			if (i != (argc - 1))
398*911106dfSjm199354 				return (VS_ADM_EXIT_USAGE);
399*911106dfSjm199354 
400*911106dfSjm199354 			engid = argv[i];
401*911106dfSjm199354 			if (strlen(engid) > VS_SE_NAME_LEN) {
402*911106dfSjm199354 				(void) fprintf(stderr, "%s\n",
403*911106dfSjm199354 				    gettext("invalid scan engine"));
404*911106dfSjm199354 				return (VS_ADM_EXIT_ERROR);
405*911106dfSjm199354 			}
406*911106dfSjm199354 		} else {
407*911106dfSjm199354 			/* property should follow the -p */
408*911106dfSjm199354 			if (++i >= argc)
409*911106dfSjm199354 				return (VS_ADM_EXIT_USAGE);
410*911106dfSjm199354 
411*911106dfSjm199354 			if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
412*911106dfSjm199354 				(void) fprintf(stderr, "%s '%s'\n",
413*911106dfSjm199354 				    gettext("invalid property"), argv[i]);
414*911106dfSjm199354 				return (VS_ADM_EXIT_ERROR);
415*911106dfSjm199354 			}
416*911106dfSjm199354 
417*911106dfSjm199354 			propids |= vap->vap_id;
418*911106dfSjm199354 		}
419*911106dfSjm199354 	}
420*911106dfSjm199354 
421*911106dfSjm199354 	if (propids == 0LL)
422*911106dfSjm199354 		propids = VS_PROPID_SE_ALL;
423*911106dfSjm199354 
424*911106dfSjm199354 	/* get properties for specified engine */
425*911106dfSjm199354 	if (engid) {
426*911106dfSjm199354 		rc = vs_props_se_get(engid, &va.va_se[0], propids);
427*911106dfSjm199354 		if (rc != VS_ERR_NONE) {
428*911106dfSjm199354 			(void) fprintf(stderr, "%s\n", vs_strerror(rc));
429*911106dfSjm199354 			return (VS_ADM_EXIT_ERROR);
430*911106dfSjm199354 		}
431*911106dfSjm199354 		vs_adm_output_getcmd(propids, &va.va_se[0]);
432*911106dfSjm199354 		return (VS_ADM_EXIT_SUCCESS);
433*911106dfSjm199354 	}
434*911106dfSjm199354 
435*911106dfSjm199354 	/* get properties for all engines */
436*911106dfSjm199354 	if ((rc = vs_props_get_all(&va)) != VS_ERR_NONE) {
437*911106dfSjm199354 		(void) fprintf(stderr, "%s\n", vs_strerror(rc));
438*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
439*911106dfSjm199354 	}
440*911106dfSjm199354 
441*911106dfSjm199354 	for (i = 0; i < VS_SE_MAX; i++) {
442*911106dfSjm199354 		if (*(va.va_se[i].vep_engid) == 0)
443*911106dfSjm199354 			break;
444*911106dfSjm199354 		vs_adm_output_getcmd(propids, &va.va_se[i]);
445*911106dfSjm199354 	}
446*911106dfSjm199354 	if (i == 0) {
447*911106dfSjm199354 		(void) fprintf(stdout, "%s\n",
448*911106dfSjm199354 		    gettext("no scan engines configured"));
449*911106dfSjm199354 	}
450*911106dfSjm199354 
451*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
452*911106dfSjm199354 }
453*911106dfSjm199354 
454*911106dfSjm199354 
455*911106dfSjm199354 /*
456*911106dfSjm199354  * vs_adm_set_engine
457*911106dfSjm199354  *
458*911106dfSjm199354  * Sets one or more scan engine configuration properties for a
459*911106dfSjm199354  * single scan engine.
460*911106dfSjm199354  */
461*911106dfSjm199354 static int
462*911106dfSjm199354 vs_adm_set_engine(int argc, char **argv)
463*911106dfSjm199354 {
464*911106dfSjm199354 	const vs_adm_property_t *vap;
465*911106dfSjm199354 	vs_props_se_t sep;
466*911106dfSjm199354 	char *val;
467*911106dfSjm199354 	uint64_t propids;
468*911106dfSjm199354 	int i, rc;
469*911106dfSjm199354 	char *engid;
470*911106dfSjm199354 	int add = (strcmp(vs_adm_subcmd, "add-engine") == 0) ? 1 : 0;
471*911106dfSjm199354 
472*911106dfSjm199354 
473*911106dfSjm199354 	if ((argc < 3) || ((!add) && (argc < 4)))
474*911106dfSjm199354 		return (VS_ADM_EXIT_USAGE);
475*911106dfSjm199354 
476*911106dfSjm199354 	/* Get the engine id */
477*911106dfSjm199354 	engid = argv[argc - 1];
478*911106dfSjm199354 	if (strchr(engid, '=') || strcmp(argv[argc - 2], "-p") == 0) {
479*911106dfSjm199354 		return (VS_ADM_EXIT_USAGE);
480*911106dfSjm199354 	}
481*911106dfSjm199354 
482*911106dfSjm199354 	if (strlen(engid) > VS_SE_NAME_LEN) {
483*911106dfSjm199354 		(void) fprintf(stderr, "%s\n",
484*911106dfSjm199354 		    gettext("invalid scan engine"));
485*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
486*911106dfSjm199354 	}
487*911106dfSjm199354 
488*911106dfSjm199354 	propids = 0LL;
489*911106dfSjm199354 
490*911106dfSjm199354 	for (i = 2; i < (argc - 1); i++) {
491*911106dfSjm199354 		/* The "-p" is optional */
492*911106dfSjm199354 		if (strcmp(argv[i], "-p") == 0) {
493*911106dfSjm199354 			if (++i >= argc)
494*911106dfSjm199354 				return (VS_ADM_EXIT_USAGE);
495*911106dfSjm199354 		}
496*911106dfSjm199354 
497*911106dfSjm199354 		if ((val = strchr(argv[i], '=')) == NULL)
498*911106dfSjm199354 			return (VS_ADM_EXIT_USAGE);
499*911106dfSjm199354 
500*911106dfSjm199354 		*val = 0;
501*911106dfSjm199354 		val++;
502*911106dfSjm199354 
503*911106dfSjm199354 		/* Find the SE property pointer from the SE property name */
504*911106dfSjm199354 		if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
505*911106dfSjm199354 			(void) fprintf(stderr, "%s '%s'\n",
506*911106dfSjm199354 			    gettext("invalid property"), argv[i]);
507*911106dfSjm199354 			return (VS_ADM_EXIT_ERROR);
508*911106dfSjm199354 		}
509*911106dfSjm199354 
510*911106dfSjm199354 		propids |= vap->vap_id;
511*911106dfSjm199354 
512*911106dfSjm199354 		if ((vs_adm_parse(vap, val, &sep)) != 0) {
513*911106dfSjm199354 			(void) fprintf(stderr, "%s '%s'\n",
514*911106dfSjm199354 			    gettext("invalid property value"), val);
515*911106dfSjm199354 			return (VS_ADM_EXIT_ERROR);
516*911106dfSjm199354 		}
517*911106dfSjm199354 	}
518*911106dfSjm199354 
519*911106dfSjm199354 	if (add)
520*911106dfSjm199354 		rc = vs_props_se_create(engid, &sep, propids);
521*911106dfSjm199354 	else
522*911106dfSjm199354 		rc = vs_props_se_set(engid, &sep, propids);
523*911106dfSjm199354 
524*911106dfSjm199354 	if (rc != VS_ERR_NONE) {
525*911106dfSjm199354 		(void) fprintf(stderr, "%s\n", vs_strerror(rc));
526*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
527*911106dfSjm199354 	}
528*911106dfSjm199354 
529*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
530*911106dfSjm199354 }
531*911106dfSjm199354 
532*911106dfSjm199354 
533*911106dfSjm199354 /*
534*911106dfSjm199354  * vs_adm_rem_engine
535*911106dfSjm199354  */
536*911106dfSjm199354 /* ARGSUSED */
537*911106dfSjm199354 static int
538*911106dfSjm199354 vs_adm_rem_engine(int argc, char **argv)
539*911106dfSjm199354 {
540*911106dfSjm199354 	int rc;
541*911106dfSjm199354 	char *engid;
542*911106dfSjm199354 
543*911106dfSjm199354 	if (argc != 3)
544*911106dfSjm199354 		return (VS_ADM_EXIT_USAGE);
545*911106dfSjm199354 
546*911106dfSjm199354 	engid = argv[2];
547*911106dfSjm199354 
548*911106dfSjm199354 	if (strlen(engid) > VS_SE_NAME_LEN) {
549*911106dfSjm199354 		(void) fprintf(stderr, "%s\n",
550*911106dfSjm199354 		    gettext("invalid scan engine"));
551*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
552*911106dfSjm199354 	}
553*911106dfSjm199354 
554*911106dfSjm199354 	if ((rc = vs_props_se_delete(engid)) != VS_ERR_NONE) {
555*911106dfSjm199354 		(void) fprintf(stderr, "%s\n", vs_strerror(rc));
556*911106dfSjm199354 		return (rc);
557*911106dfSjm199354 	}
558*911106dfSjm199354 
559*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
560*911106dfSjm199354 }
561*911106dfSjm199354 
562*911106dfSjm199354 
563*911106dfSjm199354 /*
564*911106dfSjm199354  * vs_adm_import
565*911106dfSjm199354  */
566*911106dfSjm199354 static int
567*911106dfSjm199354 vs_adm_import(int argc, char **argv)
568*911106dfSjm199354 {
569*911106dfSjm199354 	int rc;
570*911106dfSjm199354 	vs_props_t vp;
571*911106dfSjm199354 	uint64_t propids;
572*911106dfSjm199354 	char *filename;
573*911106dfSjm199354 
574*911106dfSjm199354 	if ((rc = vs_adm_file_usage(argc, argv)) != VS_ADM_EXIT_SUCCESS)
575*911106dfSjm199354 		return (rc);
576*911106dfSjm199354 
577*911106dfSjm199354 	filename = argv[argc - 1];
578*911106dfSjm199354 	rc = vs_adm_file_read(filename, vp.vp_types, sizeof (vp.vp_types));
579*911106dfSjm199354 	if (rc != VS_ADM_EXIT_SUCCESS)
580*911106dfSjm199354 		return (rc);
581*911106dfSjm199354 
582*911106dfSjm199354 	propids = VS_PROPID_TYPES;
583*911106dfSjm199354 	rc = vs_props_set(&vp, propids);
584*911106dfSjm199354 	if (rc != VS_ERR_NONE) {
585*911106dfSjm199354 		(void) fprintf(stderr, "%s\n", vs_strerror(rc));
586*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
587*911106dfSjm199354 	}
588*911106dfSjm199354 
589*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
590*911106dfSjm199354 }
591*911106dfSjm199354 
592*911106dfSjm199354 
593*911106dfSjm199354 /*
594*911106dfSjm199354  * vs_adm_validate
595*911106dfSjm199354  */
596*911106dfSjm199354 static int
597*911106dfSjm199354 vs_adm_validate(int argc, char **argv)
598*911106dfSjm199354 {
599*911106dfSjm199354 	int rc;
600*911106dfSjm199354 	vs_props_t vp;
601*911106dfSjm199354 	char *filename;
602*911106dfSjm199354 
603*911106dfSjm199354 	if ((rc = vs_adm_file_usage(argc, argv)) != VS_ADM_EXIT_SUCCESS)
604*911106dfSjm199354 		return (rc);
605*911106dfSjm199354 
606*911106dfSjm199354 	filename = argv[argc - 1];
607*911106dfSjm199354 	rc = vs_adm_file_read(filename, vp.vp_types, sizeof (vp.vp_types));
608*911106dfSjm199354 	if (rc != VS_ADM_EXIT_SUCCESS)
609*911106dfSjm199354 		return (rc);
610*911106dfSjm199354 
611*911106dfSjm199354 	if (vs_props_validate(&vp, VS_PROPID_TYPES) != VS_ERR_NONE) {
612*911106dfSjm199354 		(void) fprintf(stderr, "%s: %s\n", filename, vs_strerror(rc));
613*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
614*911106dfSjm199354 	}
615*911106dfSjm199354 
616*911106dfSjm199354 	(void) fprintf(stdout, "%s: valid\n", filename);
617*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
618*911106dfSjm199354 }
619*911106dfSjm199354 
620*911106dfSjm199354 
621*911106dfSjm199354 /*
622*911106dfSjm199354  * vs_adm_export
623*911106dfSjm199354  */
624*911106dfSjm199354 static int
625*911106dfSjm199354 vs_adm_export(int argc, char **argv)
626*911106dfSjm199354 {
627*911106dfSjm199354 	int rc;
628*911106dfSjm199354 	vs_props_t vp;
629*911106dfSjm199354 	uint64_t propids;
630*911106dfSjm199354 	char *filename;
631*911106dfSjm199354 
632*911106dfSjm199354 	if ((rc = vs_adm_file_usage(argc, argv)) != VS_ADM_EXIT_SUCCESS)
633*911106dfSjm199354 		return (rc);
634*911106dfSjm199354 
635*911106dfSjm199354 	filename = argv[argc - 1];
636*911106dfSjm199354 	(void) memset(&vp, 0, sizeof (vs_props_t));
637*911106dfSjm199354 	propids = VS_PROPID_TYPES;
638*911106dfSjm199354 	if ((rc = vs_props_get(&vp, propids)) != VS_ERR_NONE) {
639*911106dfSjm199354 		(void) fprintf(stderr, "%s: %s\n", filename, vs_strerror(rc));
640*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
641*911106dfSjm199354 	}
642*911106dfSjm199354 
643*911106dfSjm199354 	rc = vs_adm_file_write(filename, vp.vp_types);
644*911106dfSjm199354 	if (rc != VS_ADM_EXIT_SUCCESS)
645*911106dfSjm199354 		return (rc);
646*911106dfSjm199354 
647*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
648*911106dfSjm199354 }
649*911106dfSjm199354 
650*911106dfSjm199354 
651*911106dfSjm199354 /*
652*911106dfSjm199354  * vs_adm_file_usage
653*911106dfSjm199354  *
654*911106dfSjm199354  * import, export and validate - VS_PROPID_TYPES only
655*911106dfSjm199354  */
656*911106dfSjm199354 static int
657*911106dfSjm199354 vs_adm_file_usage(int argc, char **argv)
658*911106dfSjm199354 {
659*911106dfSjm199354 	const vs_adm_property_t *vap;
660*911106dfSjm199354 	char *prop;
661*911106dfSjm199354 
662*911106dfSjm199354 	if (argc < 4)
663*911106dfSjm199354 		return (VS_ADM_EXIT_USAGE);
664*911106dfSjm199354 
665*911106dfSjm199354 	/* -p optional */
666*911106dfSjm199354 	if (strcmp(argv[2], "-p") == 0) {
667*911106dfSjm199354 		if (argc != 5)
668*911106dfSjm199354 			return (VS_ADM_EXIT_USAGE);
669*911106dfSjm199354 	} else if (argc != 4)
670*911106dfSjm199354 		return (VS_ADM_EXIT_USAGE);
671*911106dfSjm199354 
672*911106dfSjm199354 	/* only VS_PROPID_TYPES supported */
673*911106dfSjm199354 	prop = argv[argc - 2];
674*911106dfSjm199354 	vap = vs_adm_prop_by_name(prop);
675*911106dfSjm199354 	if ((vap == NULL) || (vap->vap_id != VS_PROPID_TYPES)) {
676*911106dfSjm199354 		(void) fprintf(stderr, "%s '%s'\n",
677*911106dfSjm199354 		    gettext("invalid property"), prop);
678*911106dfSjm199354 		return (VS_ADM_EXIT_USAGE);
679*911106dfSjm199354 	}
680*911106dfSjm199354 
681*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
682*911106dfSjm199354 }
683*911106dfSjm199354 
684*911106dfSjm199354 
685*911106dfSjm199354 /*
686*911106dfSjm199354  * vs_adm_file_read
687*911106dfSjm199354  */
688*911106dfSjm199354 static int
689*911106dfSjm199354 vs_adm_file_read(char *filename, char *buf, int len)
690*911106dfSjm199354 {
691*911106dfSjm199354 	FILE *fp;
692*911106dfSjm199354 
693*911106dfSjm199354 	if ((fp = fopen(filename, "r")) == NULL) {
694*911106dfSjm199354 		(void) fprintf(stderr, "%s: %s\n", filename,
695*911106dfSjm199354 		    vs_strerror(VS_ERR_SYS));
696*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
697*911106dfSjm199354 	}
698*911106dfSjm199354 
699*911106dfSjm199354 	(void) memset(buf, 0, len);
700*911106dfSjm199354 	if (fgets(buf, len, fp) == NULL) {
701*911106dfSjm199354 		(void) fprintf(stderr, "%s: %s\n", filename,
702*911106dfSjm199354 		    gettext("invalid property value"));
703*911106dfSjm199354 		(void) fclose(fp);
704*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
705*911106dfSjm199354 	}
706*911106dfSjm199354 
707*911106dfSjm199354 	(void) fclose(fp);
708*911106dfSjm199354 
709*911106dfSjm199354 	/* remove newline */
710*911106dfSjm199354 	if (buf[strlen(buf) - 1] == '\n')
711*911106dfSjm199354 		buf[strlen(buf) - 1] = '\0';
712*911106dfSjm199354 
713*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
714*911106dfSjm199354 }
715*911106dfSjm199354 
716*911106dfSjm199354 
717*911106dfSjm199354 /*
718*911106dfSjm199354  * vs_adm_file_write
719*911106dfSjm199354  */
720*911106dfSjm199354 static int
721*911106dfSjm199354 vs_adm_file_write(char *filename, char *buf)
722*911106dfSjm199354 {
723*911106dfSjm199354 	FILE *fp;
724*911106dfSjm199354 	int bytes;
725*911106dfSjm199354 
726*911106dfSjm199354 	if ((fp = fopen(filename, "w")) == NULL) {
727*911106dfSjm199354 		(void) fprintf(stderr, "%s: %s\n", filename,
728*911106dfSjm199354 		    vs_strerror(VS_ERR_SYS));
729*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
730*911106dfSjm199354 	}
731*911106dfSjm199354 
732*911106dfSjm199354 	bytes = fprintf(fp, "%s\n", buf);
733*911106dfSjm199354 	if ((bytes < 0) || (bytes != strlen(buf) + 1)) {
734*911106dfSjm199354 		(void) fprintf(stderr, "%s: %s\n", filename,
735*911106dfSjm199354 		    vs_strerror(VS_ERR_SYS));
736*911106dfSjm199354 		(void) fclose(fp);
737*911106dfSjm199354 		return (VS_ADM_EXIT_ERROR);
738*911106dfSjm199354 	}
739*911106dfSjm199354 
740*911106dfSjm199354 	(void) fclose(fp);
741*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
742*911106dfSjm199354 }
743*911106dfSjm199354 
744*911106dfSjm199354 
745*911106dfSjm199354 /*
746*911106dfSjm199354  * vs_adm_show
747*911106dfSjm199354  *
748*911106dfSjm199354  * Gets and displays all general properties and all scan engine
749*911106dfSjm199354  * properties.
750*911106dfSjm199354  */
751*911106dfSjm199354 /* ARGSUSED */
752*911106dfSjm199354 static int
753*911106dfSjm199354 vs_adm_show(int argc, char **argv)
754*911106dfSjm199354 {
755*911106dfSjm199354 	if (argc > 2)
756*911106dfSjm199354 		return (VS_ADM_EXIT_USAGE);
757*911106dfSjm199354 
758*911106dfSjm199354 	(void) vs_adm_get(argc, argv);
759*911106dfSjm199354 	(void) vs_adm_get_engine(argc, argv);
760*911106dfSjm199354 
761*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
762*911106dfSjm199354 }
763*911106dfSjm199354 
764*911106dfSjm199354 
765*911106dfSjm199354 /*
766*911106dfSjm199354  * vs_adm_stats
767*911106dfSjm199354  *
768*911106dfSjm199354  * Gets and displays vscan service statistics.
769*911106dfSjm199354  */
770*911106dfSjm199354 /* ARGSUSED */
771*911106dfSjm199354 static int
772*911106dfSjm199354 vs_adm_stats(int argc, char **argv)
773*911106dfSjm199354 {
774*911106dfSjm199354 	int rc;
775*911106dfSjm199354 	vs_stats_t stats;
776*911106dfSjm199354 
777*911106dfSjm199354 	/* get statistics */
778*911106dfSjm199354 	if (argc == 2) {
779*911106dfSjm199354 		if ((rc = vs_statistics(&stats)) == VS_ERR_NONE) {
780*911106dfSjm199354 			vs_adm_output_stats(&stats);
781*911106dfSjm199354 			return (VS_ADM_EXIT_SUCCESS);
782*911106dfSjm199354 		} else {
783*911106dfSjm199354 			(void) fprintf(stdout, "%s\n", vs_strerror(rc));
784*911106dfSjm199354 			return (VS_ADM_EXIT_ERROR);
785*911106dfSjm199354 		}
786*911106dfSjm199354 	}
787*911106dfSjm199354 
788*911106dfSjm199354 	/* reset statistics */
789*911106dfSjm199354 	if (argc == 3 && strcmp(argv[2], "-z") == 0) {
790*911106dfSjm199354 		if ((rc = vs_statistics_reset()) == VS_ERR_NONE) {
791*911106dfSjm199354 			return (VS_ADM_EXIT_SUCCESS);
792*911106dfSjm199354 		} else {
793*911106dfSjm199354 			(void) fprintf(stdout, "%s\n", vs_strerror(rc));
794*911106dfSjm199354 			return (VS_ADM_EXIT_ERROR);
795*911106dfSjm199354 		}
796*911106dfSjm199354 	}
797*911106dfSjm199354 
798*911106dfSjm199354 	/* usage error */
799*911106dfSjm199354 	return (vs_adm_usage(stdout));
800*911106dfSjm199354 }
801*911106dfSjm199354 
802*911106dfSjm199354 
803*911106dfSjm199354 /*
804*911106dfSjm199354  * vs_adm_output_stats
805*911106dfSjm199354  */
806*911106dfSjm199354 static void
807*911106dfSjm199354 vs_adm_output_stats(vs_stats_t *stats)
808*911106dfSjm199354 {
809*911106dfSjm199354 	int i;
810*911106dfSjm199354 	char *engid;
811*911106dfSjm199354 
812*911106dfSjm199354 	if (stats == NULL)
813*911106dfSjm199354 		return;
814*911106dfSjm199354 
815*911106dfSjm199354 	(void) fprintf(stdout, "scanned=%lld\n", stats->vss_scanned);
816*911106dfSjm199354 	(void) fprintf(stdout, "infected=%lld\n", stats->vss_infected);
817*911106dfSjm199354 	if (stats->vss_cleaned > 0)
818*911106dfSjm199354 		(void) printf("cleaned=%lld\n", stats->vss_cleaned);
819*911106dfSjm199354 	(void) fprintf(stdout, "failed=%lld\n", stats->vss_failed);
820*911106dfSjm199354 
821*911106dfSjm199354 	for (i = 0; i < VS_SE_MAX; i++) {
822*911106dfSjm199354 		engid = stats->vss_eng[i].vss_engid;
823*911106dfSjm199354 		if (*engid == 0)
824*911106dfSjm199354 			break;
825*911106dfSjm199354 		(void) fprintf(stdout, "%s:errors=%lld\n", engid,
826*911106dfSjm199354 		    stats->vss_eng[i].vss_errors);
827*911106dfSjm199354 	}
828*911106dfSjm199354 }
829*911106dfSjm199354 
830*911106dfSjm199354 
831*911106dfSjm199354 /*
832*911106dfSjm199354  * vs_adm_props_from_input
833*911106dfSjm199354  */
834*911106dfSjm199354 static int
835*911106dfSjm199354 vs_adm_props_from_input(int argc, char **argv, vs_props_t *vsprops,
836*911106dfSjm199354     uint64_t *propids)
837*911106dfSjm199354 {
838*911106dfSjm199354 	const vs_adm_property_t *vap;
839*911106dfSjm199354 	char *val;
840*911106dfSjm199354 	int i;
841*911106dfSjm199354 
842*911106dfSjm199354 	(void) memset(vsprops, 0, sizeof (vs_props_t));
843*911106dfSjm199354 
844*911106dfSjm199354 	*propids = 0LL;
845*911106dfSjm199354 	for (i = 2; i < argc; i++) {
846*911106dfSjm199354 		/* The "-p" is optional */
847*911106dfSjm199354 		if (strcmp(argv[i], "-p") == 0) {
848*911106dfSjm199354 			if (++i >= argc)
849*911106dfSjm199354 				return (VS_ADM_EXIT_USAGE);
850*911106dfSjm199354 		}
851*911106dfSjm199354 
852*911106dfSjm199354 		if ((val = strchr(argv[i], '=')) == NULL)
853*911106dfSjm199354 			return (VS_ADM_EXIT_USAGE);
854*911106dfSjm199354 
855*911106dfSjm199354 		/* Find the vscanadm property pointer from the property name */
856*911106dfSjm199354 		*val = '\0';
857*911106dfSjm199354 		val++;
858*911106dfSjm199354 		if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
859*911106dfSjm199354 			(void) fprintf(stderr, "%s '%s'\n",
860*911106dfSjm199354 			    gettext("invalid property"), argv[i]);
861*911106dfSjm199354 			return (VS_ADM_EXIT_ERROR);
862*911106dfSjm199354 		}
863*911106dfSjm199354 
864*911106dfSjm199354 		/* Add in the property id and parse the property value */
865*911106dfSjm199354 		*propids |= vap->vap_id;
866*911106dfSjm199354 		if ((vs_adm_parse(vap, val, vsprops)) != 0) {
867*911106dfSjm199354 			(void) fprintf(stderr, "%s '%s'\n",
868*911106dfSjm199354 			    gettext("invalid property value"), val);
869*911106dfSjm199354 			return (VS_ADM_EXIT_ERROR);
870*911106dfSjm199354 		}
871*911106dfSjm199354 	}
872*911106dfSjm199354 
873*911106dfSjm199354 	return (VS_ADM_EXIT_SUCCESS);
874*911106dfSjm199354 }
875*911106dfSjm199354 
876*911106dfSjm199354 
877*911106dfSjm199354 /*
878*911106dfSjm199354  * vs_adm_output_getcmd
879*911106dfSjm199354  *
880*911106dfSjm199354  * Prints the results of a get command; both the get for general
881*911106dfSjm199354  * configuration properties as well as the get for an engine
882*911106dfSjm199354  * properties.
883*911106dfSjm199354  *
884*911106dfSjm199354  */
885*911106dfSjm199354 static void
886*911106dfSjm199354 vs_adm_output_getcmd(uint64_t propids, const void *props)
887*911106dfSjm199354 {
888*911106dfSjm199354 	char value[VS_ADM_PRINT_BUF_LEN];
889*911106dfSjm199354 	uint64_t propid;
890*911106dfSjm199354 	const vs_adm_property_t *vap;
891*911106dfSjm199354 	char *label = NULL;
892*911106dfSjm199354 
893*911106dfSjm199354 	if (VS_PROPID_IS_SE(propids))
894*911106dfSjm199354 		label = ((vs_props_se_t *)props)->vep_engid;
895*911106dfSjm199354 
896*911106dfSjm199354 	/*
897*911106dfSjm199354 	 * Unparse values from the property structure into readable strings
898*911106dfSjm199354 	 * and print them.
899*911106dfSjm199354 	 */
900*911106dfSjm199354 	for (propid = 1LL; propid <= VS_PROPID_MAX; propid <<= 1) {
901*911106dfSjm199354 		if ((propids & propid) == 0)
902*911106dfSjm199354 			continue;
903*911106dfSjm199354 
904*911106dfSjm199354 		if ((vap = vs_adm_prop_by_id(propid)) == NULL)
905*911106dfSjm199354 			continue;
906*911106dfSjm199354 
907*911106dfSjm199354 		*value = '\0';
908*911106dfSjm199354 		vs_adm_unparse(vap, props, value, sizeof (value));
909*911106dfSjm199354 
910*911106dfSjm199354 		if (label)
911*911106dfSjm199354 			(void) fprintf(stdout, "%s:", label);
912*911106dfSjm199354 		(void) fprintf(stdout, "%s=%s\n", vap->vap_name, value);
913*911106dfSjm199354 	}
914*911106dfSjm199354 
915*911106dfSjm199354 	(void) fprintf(stdout, "\n");
916*911106dfSjm199354 }
917*911106dfSjm199354 
918*911106dfSjm199354 
919*911106dfSjm199354 /*
920*911106dfSjm199354  * vs_adm_prop_by_name
921*911106dfSjm199354  *
922*911106dfSjm199354  * Finds and returns a pointer to a vscan property structure from the
923*911106dfSjm199354  * property table by property name.
924*911106dfSjm199354  */
925*911106dfSjm199354 static const vs_adm_property_t *
926*911106dfSjm199354 vs_adm_prop_by_name(const char *propname)
927*911106dfSjm199354 {
928*911106dfSjm199354 	const vs_adm_property_t *p;
929*911106dfSjm199354 
930*911106dfSjm199354 	for (p = vs_adm_props_all; p->vap_name != NULL; p++) {
931*911106dfSjm199354 		if (strcmp(propname, p->vap_name) == 0)
932*911106dfSjm199354 			return (p);
933*911106dfSjm199354 	}
934*911106dfSjm199354 
935*911106dfSjm199354 	return (NULL);
936*911106dfSjm199354 }
937*911106dfSjm199354 
938*911106dfSjm199354 
939*911106dfSjm199354 /*
940*911106dfSjm199354  * vs_adm_prop_by_id
941*911106dfSjm199354  *
942*911106dfSjm199354  * Finds and returns a pointer to a vscan property structure from the
943*911106dfSjm199354  * property table by property name.
944*911106dfSjm199354  */
945*911106dfSjm199354 static const vs_adm_property_t *
946*911106dfSjm199354 vs_adm_prop_by_id(const uint64_t propid)
947*911106dfSjm199354 {
948*911106dfSjm199354 	const vs_adm_property_t *p;
949*911106dfSjm199354 
950*911106dfSjm199354 	for (p = vs_adm_props_all; p->vap_id != 0; p++) {
951*911106dfSjm199354 		if (propid == p->vap_id)
952*911106dfSjm199354 			return (p);
953*911106dfSjm199354 	}
954*911106dfSjm199354 
955*911106dfSjm199354 	return (NULL);
956*911106dfSjm199354 }
957*911106dfSjm199354 
958*911106dfSjm199354 
959*911106dfSjm199354 /*
960*911106dfSjm199354  * vs_adm_parse
961*911106dfSjm199354  *
962*911106dfSjm199354  * Entry point for parsing the user input strings into a data structure
963*911106dfSjm199354  * used for setting values. Dispatches the actual parsing to the parse
964*911106dfSjm199354  * routine for the specified vscanadm property.
965*911106dfSjm199354  *
966*911106dfSjm199354  * This function is used to dispatch parsing for values supplied by the
967*911106dfSjm199354  * user for all subcommands; both the general configuration as well as
968*911106dfSjm199354  * scan engine configuration. The structure pointer is therefore typed
969*911106dfSjm199354  * as a void pointer, and cast appropriately in the parse routine for
970*911106dfSjm199354  * the vscanadm property.
971*911106dfSjm199354  */
972*911106dfSjm199354 static int
973*911106dfSjm199354 vs_adm_parse(const vs_adm_property_t *vap, const char *valvap_name,
974*911106dfSjm199354 	void *vp)
975*911106dfSjm199354 {
976*911106dfSjm199354 	return ((vap->vap_parse)(valvap_name, vp));
977*911106dfSjm199354 }
978*911106dfSjm199354 
979*911106dfSjm199354 
980*911106dfSjm199354 /*
981*911106dfSjm199354  * vs_adm_parse_maxsize
982*911106dfSjm199354  *
983*911106dfSjm199354  * Parses a user-supplied string into a maxsize (decimal) value for
984*911106dfSjm199354  * the general vscan configuration properties.
985*911106dfSjm199354  */
986*911106dfSjm199354 static int
987*911106dfSjm199354 vs_adm_parse_maxsize(const char *valstr, void *vp)
988*911106dfSjm199354 {
989*911106dfSjm199354 	vs_props_t *svcp = vp;
990*911106dfSjm199354 
991*911106dfSjm199354 	uint64_t maxsize;
992*911106dfSjm199354 	char *end;
993*911106dfSjm199354 
994*911106dfSjm199354 	errno = 0;
995*911106dfSjm199354 	maxsize = strtoll(valstr, &end, 10);
996*911106dfSjm199354 	if (errno != 0)
997*911106dfSjm199354 		return (-1);
998*911106dfSjm199354 	(void) snprintf(svcp->vp_maxsize, sizeof (svcp->vp_maxsize),
999*911106dfSjm199354 	    "%llu%s", maxsize, end);
1000*911106dfSjm199354 
1001*911106dfSjm199354 	return (0);
1002*911106dfSjm199354 }
1003*911106dfSjm199354 
1004*911106dfSjm199354 
1005*911106dfSjm199354 /*
1006*911106dfSjm199354  * vs_adm_parse_maxsize_action
1007*911106dfSjm199354  *
1008*911106dfSjm199354  * Parses a user-supplied string into a maxsize action value for the
1009*911106dfSjm199354  * general vscan configuration properties.
1010*911106dfSjm199354  *
1011*911106dfSjm199354  * Returns: 0 success
1012*911106dfSjm199354  *         -1 failure
1013*911106dfSjm199354  */
1014*911106dfSjm199354 static int
1015*911106dfSjm199354 vs_adm_parse_maxsize_action(const char *valstr, void *vp)
1016*911106dfSjm199354 {
1017*911106dfSjm199354 	vs_props_t *svcp = vp;
1018*911106dfSjm199354 
1019*911106dfSjm199354 	if (strcmp(valstr, VS_ADM_ALLOW) == 0) {
1020*911106dfSjm199354 		svcp->vp_maxsize_action = B_TRUE;
1021*911106dfSjm199354 		return (0);
1022*911106dfSjm199354 	}
1023*911106dfSjm199354 
1024*911106dfSjm199354 	if (strcmp(valstr, VS_ADM_DENY) == 0) {
1025*911106dfSjm199354 		svcp->vp_maxsize_action = B_FALSE;
1026*911106dfSjm199354 		return (0);
1027*911106dfSjm199354 	}
1028*911106dfSjm199354 
1029*911106dfSjm199354 	return (-1);
1030*911106dfSjm199354 }
1031*911106dfSjm199354 
1032*911106dfSjm199354 
1033*911106dfSjm199354 /*
1034*911106dfSjm199354  * vs_adm_parse_types
1035*911106dfSjm199354  *
1036*911106dfSjm199354  * Returns: 0 success
1037*911106dfSjm199354  *         -1 on failure.
1038*911106dfSjm199354  */
1039*911106dfSjm199354 static int
1040*911106dfSjm199354 vs_adm_parse_types(const char *valstr, void *vp)
1041*911106dfSjm199354 {
1042*911106dfSjm199354 	vs_props_t *svcp = vp;
1043*911106dfSjm199354 
1044*911106dfSjm199354 	if (strlen(valstr) >= sizeof (svcp->vp_types))
1045*911106dfSjm199354 		return (-1);
1046*911106dfSjm199354 
1047*911106dfSjm199354 	if (strlcpy(svcp->vp_types, valstr, sizeof (svcp->vp_types))
1048*911106dfSjm199354 	    >= sizeof (svcp->vp_types))
1049*911106dfSjm199354 		return (-1);
1050*911106dfSjm199354 
1051*911106dfSjm199354 	return (0);
1052*911106dfSjm199354 }
1053*911106dfSjm199354 
1054*911106dfSjm199354 
1055*911106dfSjm199354 /*
1056*911106dfSjm199354  * vs_adm_parse_enable
1057*911106dfSjm199354  *
1058*911106dfSjm199354  * Parses a user-supplied string into an enable value for the
1059*911106dfSjm199354  * properties of a scan engine.
1060*911106dfSjm199354  *
1061*911106dfSjm199354  * Returns: 0 success
1062*911106dfSjm199354  *         -1 on failure.
1063*911106dfSjm199354  */
1064*911106dfSjm199354 static int
1065*911106dfSjm199354 vs_adm_parse_enable(const char *valstr, void *vp)
1066*911106dfSjm199354 {
1067*911106dfSjm199354 	vs_props_se_t *sep = vp;
1068*911106dfSjm199354 
1069*911106dfSjm199354 	if (strcmp(valstr, VS_ADM_ON) == 0) {
1070*911106dfSjm199354 		sep->vep_enable = B_TRUE;
1071*911106dfSjm199354 		return (0);
1072*911106dfSjm199354 	}
1073*911106dfSjm199354 
1074*911106dfSjm199354 	if (strcmp(valstr, VS_ADM_OFF) == 0) {
1075*911106dfSjm199354 		sep->vep_enable = B_FALSE;
1076*911106dfSjm199354 		return (0);
1077*911106dfSjm199354 	}
1078*911106dfSjm199354 
1079*911106dfSjm199354 	return (-1);
1080*911106dfSjm199354 }
1081*911106dfSjm199354 
1082*911106dfSjm199354 
1083*911106dfSjm199354 /*
1084*911106dfSjm199354  * vs_adm_parse_host
1085*911106dfSjm199354  *
1086*911106dfSjm199354  * Parses a user-supplied string into an ip address value for the
1087*911106dfSjm199354  * properties of a scan engine.
1088*911106dfSjm199354  */
1089*911106dfSjm199354 static int
1090*911106dfSjm199354 vs_adm_parse_host(const char *valstr, void *vp)
1091*911106dfSjm199354 {
1092*911106dfSjm199354 	vs_props_se_t *sep = vp;
1093*911106dfSjm199354 
1094*911106dfSjm199354 	if (strlen(valstr) >= sizeof (sep->vep_host))
1095*911106dfSjm199354 		return (-1);
1096*911106dfSjm199354 
1097*911106dfSjm199354 	if (strlcpy(sep->vep_host, valstr, sizeof (sep->vep_host)) >=
1098*911106dfSjm199354 	    sizeof (sep->vep_host))
1099*911106dfSjm199354 		return (-1);
1100*911106dfSjm199354 
1101*911106dfSjm199354 	return (0);
1102*911106dfSjm199354 }
1103*911106dfSjm199354 
1104*911106dfSjm199354 
1105*911106dfSjm199354 /*
1106*911106dfSjm199354  * vs_adm_parse_port
1107*911106dfSjm199354  *
1108*911106dfSjm199354  * Parses a user-supplied string into a port value for the properties of
1109*911106dfSjm199354  * a scan engine. The port is an unsigned short int, but the conversion
1110*911106dfSjm199354  * must be done on a word-sized int. Casting the converted int into the
1111*911106dfSjm199354  * port member of the property structure can result in a valid but
1112*911106dfSjm199354  * unintended value, so the range is checked first for validity.
1113*911106dfSjm199354  *
1114*911106dfSjm199354  * Returns: 0 success
1115*911106dfSjm199354  *         -1 on failure.
1116*911106dfSjm199354  */
1117*911106dfSjm199354 static int
1118*911106dfSjm199354 vs_adm_parse_port(const char *valstr, void *vp)
1119*911106dfSjm199354 {
1120*911106dfSjm199354 	vs_props_se_t *sep = vp;
1121*911106dfSjm199354 	unsigned long port;
1122*911106dfSjm199354 	char *end;
1123*911106dfSjm199354 
1124*911106dfSjm199354 	end = 0;
1125*911106dfSjm199354 	port = strtoul(valstr, &end, 0);
1126*911106dfSjm199354 	if (port > UINT16_MAX || (end < (valstr + strlen(valstr))))
1127*911106dfSjm199354 		return (-1);
1128*911106dfSjm199354 
1129*911106dfSjm199354 	sep->vep_port = port;
1130*911106dfSjm199354 
1131*911106dfSjm199354 	return (0);
1132*911106dfSjm199354 }
1133*911106dfSjm199354 
1134*911106dfSjm199354 
1135*911106dfSjm199354 /*
1136*911106dfSjm199354  * vs_adm_parse_maxconn
1137*911106dfSjm199354  *
1138*911106dfSjm199354  * Parses a user-supplied string into a max connections (decimal) value
1139*911106dfSjm199354  * for the properties of a scan engine.
1140*911106dfSjm199354  *
1141*911106dfSjm199354  * Returns: 0 success
1142*911106dfSjm199354  *         -1 on failure.
1143*911106dfSjm199354  */
1144*911106dfSjm199354 static int
1145*911106dfSjm199354 vs_adm_parse_maxconn(const char *valstr, void *vp)
1146*911106dfSjm199354 {
1147*911106dfSjm199354 	vs_props_se_t *sep = vp;
1148*911106dfSjm199354 	char *end;
1149*911106dfSjm199354 
1150*911106dfSjm199354 	sep->vep_maxconn = strtoll(valstr, &end, 10);
1151*911106dfSjm199354 	if (end < valstr + strlen(valstr))
1152*911106dfSjm199354 		return (-1);
1153*911106dfSjm199354 
1154*911106dfSjm199354 	return (0);
1155*911106dfSjm199354 }
1156*911106dfSjm199354 
1157*911106dfSjm199354 
1158*911106dfSjm199354 /*
1159*911106dfSjm199354  * vs_adm_unparse
1160*911106dfSjm199354  *
1161*911106dfSjm199354  * Entry point for unparsing native data into a readable string
1162*911106dfSjm199354  * used for display to the user. Dispatches the actual unparsing to
1163*911106dfSjm199354  * the unparse routine for the specified vscanadm property.
1164*911106dfSjm199354  *
1165*911106dfSjm199354  * This function is used to dispatch unparsing for all subcommands.
1166*911106dfSjm199354  * The structure pointer is therefore typed as a void pointer, and
1167*911106dfSjm199354  * cast appropriately in the unparse routine for the vscanadm property.
1168*911106dfSjm199354  */
1169*911106dfSjm199354 static void
1170*911106dfSjm199354 vs_adm_unparse(const vs_adm_property_t *vap, const void *vp,
1171*911106dfSjm199354 	char *buf, size_t len)
1172*911106dfSjm199354 {
1173*911106dfSjm199354 	if ((vap->vap_unparse)(vp, buf, len) != 0)
1174*911106dfSjm199354 		(void) snprintf(buf, len, gettext(" (error) "));
1175*911106dfSjm199354 }
1176*911106dfSjm199354 
1177*911106dfSjm199354 
1178*911106dfSjm199354 /*
1179*911106dfSjm199354  *  vs_adm_unparse_maxsize
1180*911106dfSjm199354  *
1181*911106dfSjm199354  * Unparses a max fsize value in native data form into a
1182*911106dfSjm199354  * user-readable string.
1183*911106dfSjm199354  */
1184*911106dfSjm199354 /* ARGSUSED */
1185*911106dfSjm199354 static int
1186*911106dfSjm199354 vs_adm_unparse_maxsize(const void *vp, char *buf, size_t len)
1187*911106dfSjm199354 {
1188*911106dfSjm199354 	const vs_props_t *svcp = vp;
1189*911106dfSjm199354 
1190*911106dfSjm199354 	(void) snprintf(buf, len, "%s", svcp->vp_maxsize);
1191*911106dfSjm199354 
1192*911106dfSjm199354 	return (0);
1193*911106dfSjm199354 }
1194*911106dfSjm199354 
1195*911106dfSjm199354 
1196*911106dfSjm199354 /*
1197*911106dfSjm199354  * vs_adm_unparse_maxsize_action
1198*911106dfSjm199354  *
1199*911106dfSjm199354  * Unparses a max fsize action value in native data form into a
1200*911106dfSjm199354  * user-readable string.
1201*911106dfSjm199354  */
1202*911106dfSjm199354 /* ARGSUSED */
1203*911106dfSjm199354 static int
1204*911106dfSjm199354 vs_adm_unparse_maxsize_action(const void *vp, char *buf, size_t len)
1205*911106dfSjm199354 {
1206*911106dfSjm199354 	const vs_props_t *svcp = vp;
1207*911106dfSjm199354 
1208*911106dfSjm199354 	(void) snprintf(buf, len, "%s",
1209*911106dfSjm199354 	    svcp->vp_maxsize_action ?  VS_ADM_ALLOW : VS_ADM_DENY);
1210*911106dfSjm199354 
1211*911106dfSjm199354 	return (0);
1212*911106dfSjm199354 }
1213*911106dfSjm199354 
1214*911106dfSjm199354 
1215*911106dfSjm199354 /*
1216*911106dfSjm199354  * vs_adm_unparse_types
1217*911106dfSjm199354  *
1218*911106dfSjm199354  * Returns: 0 success
1219*911106dfSjm199354  *         -1 on failure.
1220*911106dfSjm199354  */
1221*911106dfSjm199354 static int
1222*911106dfSjm199354 vs_adm_unparse_types(const void *vp, char *buf, size_t len)
1223*911106dfSjm199354 {
1224*911106dfSjm199354 	const vs_props_t *svcp = vp;
1225*911106dfSjm199354 
1226*911106dfSjm199354 	(void) strlcpy(buf, svcp->vp_types, len);
1227*911106dfSjm199354 
1228*911106dfSjm199354 	return (0);
1229*911106dfSjm199354 }
1230*911106dfSjm199354 
1231*911106dfSjm199354 
1232*911106dfSjm199354 /*
1233*911106dfSjm199354  * vs_adm_unparse_enable
1234*911106dfSjm199354  *
1235*911106dfSjm199354  * Unparses the enable value for a scan engine in native data
1236*911106dfSjm199354  * form into a user-readable string.
1237*911106dfSjm199354  */
1238*911106dfSjm199354 /* ARGSUSED */
1239*911106dfSjm199354 static int
1240*911106dfSjm199354 vs_adm_unparse_enable(const void *vp, char *buf, size_t len)
1241*911106dfSjm199354 {
1242*911106dfSjm199354 	const vs_props_se_t *sep = vp;
1243*911106dfSjm199354 
1244*911106dfSjm199354 	(void) snprintf(buf, len, "%s",
1245*911106dfSjm199354 	    sep->vep_enable ?  VS_ADM_ON : VS_ADM_OFF);
1246*911106dfSjm199354 
1247*911106dfSjm199354 	return (0);
1248*911106dfSjm199354 }
1249*911106dfSjm199354 
1250*911106dfSjm199354 
1251*911106dfSjm199354 /*
1252*911106dfSjm199354  * vs_adm_unparse_host
1253*911106dfSjm199354  *
1254*911106dfSjm199354  * Unparses an ip address for a scan engine in native data
1255*911106dfSjm199354  * form into a user-readable string.
1256*911106dfSjm199354  *
1257*911106dfSjm199354  * Returns: 0 success
1258*911106dfSjm199354  *         -1 on failure.
1259*911106dfSjm199354  */
1260*911106dfSjm199354 /* ARGSUSED */
1261*911106dfSjm199354 static int
1262*911106dfSjm199354 vs_adm_unparse_host(const void *vp, char *buf, size_t len)
1263*911106dfSjm199354 {
1264*911106dfSjm199354 	const vs_props_se_t *sep = vp;
1265*911106dfSjm199354 
1266*911106dfSjm199354 	(void) strlcpy(buf, sep->vep_host, len);
1267*911106dfSjm199354 
1268*911106dfSjm199354 	return (0);
1269*911106dfSjm199354 }
1270*911106dfSjm199354 
1271*911106dfSjm199354 
1272*911106dfSjm199354 /*
1273*911106dfSjm199354  * vs_adm_unparse_port
1274*911106dfSjm199354  *
1275*911106dfSjm199354  * Unparses a port value for a scan engine in native data
1276*911106dfSjm199354  * form into a user-readable string.
1277*911106dfSjm199354  */
1278*911106dfSjm199354 /* ARGSUSED */
1279*911106dfSjm199354 static int
1280*911106dfSjm199354 vs_adm_unparse_port(const void *vp, char *buf, size_t len)
1281*911106dfSjm199354 {
1282*911106dfSjm199354 	const vs_props_se_t *sep = vp;
1283*911106dfSjm199354 
1284*911106dfSjm199354 	(void) snprintf(buf, len, "%hu", sep->vep_port);
1285*911106dfSjm199354 
1286*911106dfSjm199354 	return (0);
1287*911106dfSjm199354 }
1288*911106dfSjm199354 
1289*911106dfSjm199354 
1290*911106dfSjm199354 /*
1291*911106dfSjm199354  * vs_adm_unparse_maxconn
1292*911106dfSjm199354  *
1293*911106dfSjm199354  * Unparses a max connecctions for a scan engine in native data
1294*911106dfSjm199354  * form into a user-readable string.
1295*911106dfSjm199354  *
1296*911106dfSjm199354  */
1297*911106dfSjm199354 /* ARGSUSED */
1298*911106dfSjm199354 static int
1299*911106dfSjm199354 vs_adm_unparse_maxconn(const void *vp, char *buf, size_t len)
1300*911106dfSjm199354 {
1301*911106dfSjm199354 	const vs_props_se_t *sep = vp;
1302*911106dfSjm199354 
1303*911106dfSjm199354 	(void) snprintf(buf, len, "%lld", sep->vep_maxconn);
1304*911106dfSjm199354 
1305*911106dfSjm199354 	return (0);
1306*911106dfSjm199354 }
1307