1911106dfSjm199354 /*
2911106dfSjm199354 * CDDL HEADER START
3911106dfSjm199354 *
4911106dfSjm199354 * The contents of this file are subject to the terms of the
5911106dfSjm199354 * Common Development and Distribution License (the "License").
6911106dfSjm199354 * You may not use this file except in compliance with the License.
7911106dfSjm199354 *
8911106dfSjm199354 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9911106dfSjm199354 * or http://www.opensolaris.org/os/licensing.
10911106dfSjm199354 * See the License for the specific language governing permissions
11911106dfSjm199354 * and limitations under the License.
12911106dfSjm199354 *
13911106dfSjm199354 * When distributing Covered Code, include this CDDL HEADER in each
14911106dfSjm199354 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15911106dfSjm199354 * If applicable, add the following below this CDDL HEADER, with the
16911106dfSjm199354 * fields enclosed by brackets "[]" replaced with your own identifying
17911106dfSjm199354 * information: Portions Copyright [yyyy] [name of copyright owner]
18911106dfSjm199354 *
19911106dfSjm199354 * CDDL HEADER END
20911106dfSjm199354 */
21911106dfSjm199354 /*
22*96a62adaSjoyce mcintosh * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23911106dfSjm199354 * Use is subject to license terms.
24911106dfSjm199354 */
25911106dfSjm199354
26911106dfSjm199354
27911106dfSjm199354 #include <stdio.h>
28911106dfSjm199354 #include <strings.h>
29911106dfSjm199354 #include <limits.h>
30911106dfSjm199354 #include <stdlib.h>
31911106dfSjm199354 #include <stdarg.h>
32911106dfSjm199354 #include <errno.h>
33911106dfSjm199354 #include <ctype.h>
34911106dfSjm199354 #include <arpa/inet.h>
35911106dfSjm199354 #include <unistd.h>
36911106dfSjm199354 #include <sys/types.h>
37911106dfSjm199354 #include <sys/stat.h>
38911106dfSjm199354 #include <fcntl.h>
39911106dfSjm199354 #include <libintl.h>
40*96a62adaSjoyce mcintosh #include <locale.h>
41911106dfSjm199354 #include <libvscan.h>
42911106dfSjm199354
43*96a62adaSjoyce mcintosh #if !defined(TEXT_DOMAIN)
44*96a62adaSjoyce mcintosh #define TEXT_DOMAIN "SYS_TEST"
45*96a62adaSjoyce mcintosh #endif
46*96a62adaSjoyce mcintosh
47911106dfSjm199354
48911106dfSjm199354 /* Property Names */
49911106dfSjm199354 #define VS_ADM_MAXSIZE "max-size"
50911106dfSjm199354 #define VS_ADM_MAXSIZE_ACTION "max-size-action"
51911106dfSjm199354 #define VS_ADM_TYPES "types"
52911106dfSjm199354
53911106dfSjm199354 /* Scan Engine Property Names */
54911106dfSjm199354 #define VS_ADM_SE_ENABLE "enable"
55911106dfSjm199354 #define VS_ADM_SE_HOST "host"
56911106dfSjm199354 #define VS_ADM_SE_PORT "port"
57911106dfSjm199354 #define VS_ADM_SE_MAXCONN "max-connection"
58911106dfSjm199354
59911106dfSjm199354 /* Property Values */
60911106dfSjm199354 #define VS_ADM_ON "on"
61911106dfSjm199354 #define VS_ADM_OFF "off"
62911106dfSjm199354 #define VS_ADM_ALLOW "allow"
63911106dfSjm199354 #define VS_ADM_DENY "deny"
64911106dfSjm199354
65911106dfSjm199354
66911106dfSjm199354 /*
67911106dfSjm199354 * Print buffer length: used for sizing buffers that are filled with
68911106dfSjm199354 * user-readable strings for property values. Define a number that
69911106dfSjm199354 * accounts for some pre-value information, and won't (likely)
70911106dfSjm199354 * wrap an 80-column display
71911106dfSjm199354 */
72911106dfSjm199354 #define VS_ADM_PRINT_BUF_LEN 4096
73911106dfSjm199354
74911106dfSjm199354 /* Program exit codes */
75911106dfSjm199354 #define VS_ADM_EXIT_SUCCESS 0
76911106dfSjm199354 #define VS_ADM_EXIT_ERROR 1
77911106dfSjm199354 #define VS_ADM_EXIT_USAGE 2
78911106dfSjm199354
79911106dfSjm199354
80911106dfSjm199354 /*
81911106dfSjm199354 * vscanadm property definition. Maps the property ids to a
82911106dfSjm199354 * property name, and includes functions to convert to and from
83911106dfSjm199354 * input strings and native data.
84911106dfSjm199354 */
85911106dfSjm199354 typedef struct vs_adm_property {
86911106dfSjm199354 const char *vap_name;
87911106dfSjm199354 uint64_t vap_id;
88911106dfSjm199354 int (*vap_parse)(const char *, void *);
89911106dfSjm199354 int (*vap_unparse)(const void *, char *, size_t);
90911106dfSjm199354 } vs_adm_property_t;
91911106dfSjm199354
92911106dfSjm199354
93911106dfSjm199354 /* usage/help information for subcommnds */
94911106dfSjm199354 #define VS_ADM_HELP_GET ("[-p property]...\n" \
95911106dfSjm199354 "\tdisplay vscan properties")
96911106dfSjm199354 #define VS_ADM_HELP_SET ("-p property=value [-p property=value]...\n" \
97911106dfSjm199354 "\tset values of vscan properties")
98911106dfSjm199354 #define VS_ADM_HELP_GET_ENG ("[-p property] [engine_id]\n" \
99911106dfSjm199354 "\tdisplay values of scan engine properties")
100911106dfSjm199354 #define VS_ADM_HELP_ADD_ENG ("[-p property=value]... engine_id\n" \
101911106dfSjm199354 "\tadd scan engine")
102911106dfSjm199354 #define VS_ADM_HELP_SET_ENG ("-p property=value [-p property=value]" \
103911106dfSjm199354 "... engine_id\n\tset values of scan engine properties")
104911106dfSjm199354 #define VS_ADM_HELP_REM_ENG ("engine_id\n" \
105911106dfSjm199354 "\tremove scan engine")
106911106dfSjm199354 #define VS_ADM_HELP_SHOW ("\n\tdisplay the values of all vscan " \
107911106dfSjm199354 "service and scan engine properties")
108911106dfSjm199354 #define VS_ADM_HELP_STATS ("[-z]\n\tdisplay vscan service statistics")
109911106dfSjm199354 #define VS_ADM_HELP_IMPORT ("-p property filename\n" \
110911106dfSjm199354 "\timport property from file")
111911106dfSjm199354 #define VS_ADM_HELP_EXPORT ("-p property filename\n" \
112911106dfSjm199354 "\texport property to file")
113911106dfSjm199354 #define VS_ADM_HELP_VALIDATE ("-p property filename\n" \
114911106dfSjm199354 "\tvalidate property in file")
115911106dfSjm199354
116911106dfSjm199354
117911106dfSjm199354 /*
118911106dfSjm199354 * vscanadm command structure. Encapsulates the vscanadm
119911106dfSjm199354 * subcommand name, pointer to the subcommand implementation
120911106dfSjm199354 * function, and a help id to get usage/help information.
121911106dfSjm199354 */
122911106dfSjm199354 typedef struct vs_adm_cmd {
123911106dfSjm199354 int (*vac_func)(int, char *[]);
124911106dfSjm199354 const char *vac_name;
125911106dfSjm199354 char *vac_helpid;
126911106dfSjm199354 }
127911106dfSjm199354 vs_adm_cmd_t;
128911106dfSjm199354
129911106dfSjm199354
130911106dfSjm199354 /* Subcommand implementation functions */
131911106dfSjm199354 static int vs_adm_set(int, char **);
132911106dfSjm199354 static int vs_adm_get(int, char **);
133911106dfSjm199354 static int vs_adm_set_engine(int, char **);
134911106dfSjm199354 static int vs_adm_get_engine(int, char **);
135911106dfSjm199354 static int vs_adm_rem_engine(int, char **);
136911106dfSjm199354 static int vs_adm_show(int, char **);
137911106dfSjm199354 static int vs_adm_stats(int, char **);
138911106dfSjm199354 static int vs_adm_import(int, char **);
139911106dfSjm199354 static int vs_adm_export(int, char **);
140911106dfSjm199354 static int vs_adm_validate(int, char **);
141911106dfSjm199354
142911106dfSjm199354
143911106dfSjm199354 /*
144911106dfSjm199354 * Parse routines to transform libvscan API data into user-readable strings
145911106dfSjm199354 */
146911106dfSjm199354 static int vs_adm_parse_maxsize(const char *, void *);
147911106dfSjm199354 static int vs_adm_parse_maxsize_action(const char *, void *);
148911106dfSjm199354 static int vs_adm_parse_types(const char *, void *);
149911106dfSjm199354 static int vs_adm_parse_enable(const char *, void *);
150911106dfSjm199354 static int vs_adm_parse_host(const char *, void *);
151911106dfSjm199354 static int vs_adm_parse_port(const char *, void *);
152911106dfSjm199354 static int vs_adm_parse_maxconn(const char *, void *);
153911106dfSjm199354
154911106dfSjm199354
155911106dfSjm199354 /*
156911106dfSjm199354 * Unparse routines to transform strings from the user input into
157911106dfSjm199354 * API native data.
158911106dfSjm199354 *
159911106dfSjm199354 * While some value validation is performed in the course of unparsing
160911106dfSjm199354 * string data, complete value validation is left to libvscan.
161911106dfSjm199354 * Values that are in unacceptable form, out of range, or otherwise
162911106dfSjm199354 * violate rules for a given property will be rejected
163911106dfSjm199354 */
164911106dfSjm199354 static int vs_adm_unparse_maxsize(const void *, char *, size_t);
165911106dfSjm199354 static int vs_adm_unparse_maxsize_action(const void *, char *, size_t);
166911106dfSjm199354 static int vs_adm_unparse_types(const void *, char *, size_t);
167911106dfSjm199354 static int vs_adm_unparse_enable(const void *, char *, size_t);
168911106dfSjm199354 static int vs_adm_unparse_host(const void *, char *, size_t);
169911106dfSjm199354 static int vs_adm_unparse_port(const void *, char *, size_t);
170911106dfSjm199354 static int vs_adm_unparse_maxconn(const void *, char *, size_t);
171911106dfSjm199354
172911106dfSjm199354
173911106dfSjm199354 /*
174911106dfSjm199354 * The properties table includes a vscanadm property entry, specifying
175911106dfSjm199354 * the property nane, property id, parse amd inparse methods,
176911106dfSjm199354 * for each vscanadm property.
177911106dfSjm199354 */
178911106dfSjm199354 static const vs_adm_property_t vs_adm_props_all[] = {
179911106dfSjm199354 { VS_ADM_MAXSIZE, VS_PROPID_MAXSIZE,
180911106dfSjm199354 vs_adm_parse_maxsize, vs_adm_unparse_maxsize },
181911106dfSjm199354 { VS_ADM_MAXSIZE_ACTION, VS_PROPID_MAXSIZE_ACTION,
182911106dfSjm199354 vs_adm_parse_maxsize_action, vs_adm_unparse_maxsize_action },
183911106dfSjm199354 { VS_ADM_TYPES, VS_PROPID_TYPES,
184911106dfSjm199354 vs_adm_parse_types, vs_adm_unparse_types },
185911106dfSjm199354 { VS_ADM_SE_ENABLE, VS_PROPID_SE_ENABLE,
186911106dfSjm199354 vs_adm_parse_enable, vs_adm_unparse_enable },
187911106dfSjm199354 { VS_ADM_SE_HOST, VS_PROPID_SE_HOST,
188911106dfSjm199354 vs_adm_parse_host, vs_adm_unparse_host },
189911106dfSjm199354 { VS_ADM_SE_PORT, VS_PROPID_SE_PORT,
190911106dfSjm199354 vs_adm_parse_port, vs_adm_unparse_port },
191911106dfSjm199354 { VS_ADM_SE_MAXCONN, VS_PROPID_SE_MAXCONN,
192911106dfSjm199354 vs_adm_parse_maxconn, vs_adm_unparse_maxconn },
193911106dfSjm199354 { NULL, 0, NULL, NULL }
194911106dfSjm199354 };
195911106dfSjm199354
196911106dfSjm199354
197911106dfSjm199354 /*
198911106dfSjm199354 * The subcommand table. Used to find the subcommand specified
199911106dfSjm199354 * by the user and dispatch the processing for the subcommand.
200911106dfSjm199354 * Also used to display usage information for each subcommand.
201911106dfSjm199354 */
202911106dfSjm199354 static const vs_adm_cmd_t vs_adm_cmds[] =
203911106dfSjm199354 {
204911106dfSjm199354 { vs_adm_get, "get", VS_ADM_HELP_GET },
205911106dfSjm199354 { vs_adm_set, "set", VS_ADM_HELP_SET },
206911106dfSjm199354 { vs_adm_get_engine, "get-engine", VS_ADM_HELP_GET_ENG },
207911106dfSjm199354 { vs_adm_set_engine, "set-engine", VS_ADM_HELP_SET_ENG },
208911106dfSjm199354 { vs_adm_set_engine, "add-engine", VS_ADM_HELP_ADD_ENG },
209911106dfSjm199354 { vs_adm_rem_engine, "remove-engine", VS_ADM_HELP_REM_ENG },
210911106dfSjm199354 { vs_adm_import, "import", VS_ADM_HELP_IMPORT },
211911106dfSjm199354 { vs_adm_export, "export", VS_ADM_HELP_EXPORT },
212911106dfSjm199354 { vs_adm_validate, "validate", VS_ADM_HELP_VALIDATE },
213911106dfSjm199354 { vs_adm_show, "show", VS_ADM_HELP_SHOW },
214911106dfSjm199354 { vs_adm_stats, "stats", VS_ADM_HELP_STATS },
215911106dfSjm199354 { NULL, NULL, NULL }
216911106dfSjm199354 };
217911106dfSjm199354
218911106dfSjm199354
219911106dfSjm199354 static const char *vs_adm_cmd;
220911106dfSjm199354 static const char *vs_adm_subcmd;
221911106dfSjm199354
222911106dfSjm199354 static int vs_adm_usage(FILE *);
223911106dfSjm199354 static int vs_adm_props_from_input(int, char **, vs_props_t *, uint64_t *);
224911106dfSjm199354 static void vs_adm_output_getcmd(uint64_t, const void *);
225911106dfSjm199354 static void vs_adm_output_stats(vs_stats_t *);
226911106dfSjm199354 static const vs_adm_property_t *vs_adm_prop_by_name(const char *);
227911106dfSjm199354 static const vs_adm_property_t *vs_adm_prop_by_id(const uint64_t);
228911106dfSjm199354 static int vs_adm_parse(const vs_adm_property_t *, const char *, void *);
229911106dfSjm199354 static void vs_adm_unparse(const vs_adm_property_t *, const void *,
230911106dfSjm199354 char *, size_t);
231911106dfSjm199354
232911106dfSjm199354 static int vs_adm_file_read(char *, char *, int);
233911106dfSjm199354 static int vs_adm_file_write(char *, char *);
234911106dfSjm199354 static int vs_adm_file_usage(int argc, char **argv);
235911106dfSjm199354
236911106dfSjm199354 /*
237911106dfSjm199354 * main
238911106dfSjm199354 */
239911106dfSjm199354 int
main(int argc,char ** argv)240911106dfSjm199354 main(int argc, char **argv)
241911106dfSjm199354 {
242911106dfSjm199354 const vs_adm_cmd_t *cp;
243911106dfSjm199354 const char *p;
244911106dfSjm199354 int i, err;
245911106dfSjm199354
246*96a62adaSjoyce mcintosh (void) setlocale(LC_ALL, "");
247*96a62adaSjoyce mcintosh (void) textdomain(TEXT_DOMAIN);
248*96a62adaSjoyce mcintosh
249911106dfSjm199354 /* executable and subcommand names */
250911106dfSjm199354 if ((p = strrchr(argv[0], '/')) == NULL)
251911106dfSjm199354 vs_adm_cmd = argv[0];
252911106dfSjm199354 else
253911106dfSjm199354 vs_adm_cmd = p + 1;
254911106dfSjm199354
255911106dfSjm199354 vs_adm_subcmd = argv[1];
256911106dfSjm199354
257911106dfSjm199354 /* require at least command and sub-command */
258911106dfSjm199354 if (argc < 2)
259911106dfSjm199354 return (vs_adm_usage(stdout));
260911106dfSjm199354
261911106dfSjm199354 /* Check for the "-?" help switch */
262911106dfSjm199354 for (i = 1; i < argc; i++) {
263911106dfSjm199354 if (strcmp(argv[i], "-?") == 0)
264911106dfSjm199354 return (vs_adm_usage(stdout));
265911106dfSjm199354 }
266911106dfSjm199354
267911106dfSjm199354 /* Locate the specified subcommand */
268911106dfSjm199354 for (cp = vs_adm_cmds; cp->vac_name != NULL; cp++) {
269911106dfSjm199354 if (strcmp(cp->vac_name, vs_adm_subcmd) == 0)
270911106dfSjm199354 break;
271911106dfSjm199354 }
272911106dfSjm199354
273911106dfSjm199354 if (cp->vac_name == NULL) {
274911106dfSjm199354 (void) fprintf(stderr, "%s: %s -- %s\n",
275911106dfSjm199354 gettext("invalid subcommand"),
276911106dfSjm199354 vs_adm_cmd, vs_adm_subcmd);
277911106dfSjm199354 return (vs_adm_usage(stderr));
278911106dfSjm199354 }
279911106dfSjm199354
280911106dfSjm199354 /* invoke sub-command handler */
281911106dfSjm199354 err = cp->vac_func(argc, argv);
282911106dfSjm199354
283911106dfSjm199354 return (err == VS_ADM_EXIT_USAGE ? vs_adm_usage(stderr) : err);
284911106dfSjm199354 }
285911106dfSjm199354
286911106dfSjm199354
287911106dfSjm199354 /*
288911106dfSjm199354 * vs_adm_usage
289911106dfSjm199354 */
290911106dfSjm199354 static int
vs_adm_usage(FILE * fp)291911106dfSjm199354 vs_adm_usage(FILE *fp)
292911106dfSjm199354 {
293911106dfSjm199354 const vs_adm_cmd_t *cp;
294911106dfSjm199354
295911106dfSjm199354 for (cp = vs_adm_cmds; cp->vac_name != NULL; cp++) {
296911106dfSjm199354 (void) fprintf(fp, "%s %s", vs_adm_cmd, cp->vac_name);
297911106dfSjm199354 if (cp->vac_helpid != NULL)
298911106dfSjm199354 (void) fprintf(fp, " %s\n", cp->vac_helpid);
299911106dfSjm199354 }
300911106dfSjm199354
301911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
302911106dfSjm199354 }
303911106dfSjm199354
304911106dfSjm199354
305911106dfSjm199354 /*
306911106dfSjm199354 * vs_adm_get
307911106dfSjm199354 *
308911106dfSjm199354 * Gets and displays general vscan service configuration properties.
309911106dfSjm199354 */
310911106dfSjm199354 static int
vs_adm_get(int argc,char ** argv)311911106dfSjm199354 vs_adm_get(int argc, char **argv)
312911106dfSjm199354 {
313911106dfSjm199354 uint64_t propids;
314911106dfSjm199354 int i, rc;
315911106dfSjm199354 vs_props_t vp;
316911106dfSjm199354 const vs_adm_property_t *vap;
317911106dfSjm199354
318911106dfSjm199354 (void) memset(&vp, 0, sizeof (vp));
319911106dfSjm199354
320911106dfSjm199354 if (argc <= 2) {
321911106dfSjm199354 propids = VS_PROPID_GEN_ALL;
322911106dfSjm199354 } else {
323911106dfSjm199354 propids = 0LL;
324911106dfSjm199354 for (i = 2; i < argc; i++) {
325911106dfSjm199354 /* the "-p" specifier is optional */
326911106dfSjm199354 if (strcmp(argv[i], "-p") == 0) {
327911106dfSjm199354 if (++i >= argc)
328911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
329911106dfSjm199354 }
330911106dfSjm199354
331911106dfSjm199354 if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
332911106dfSjm199354 (void) fprintf(stderr, "%s '%s'\n",
333911106dfSjm199354 gettext("invalid property"), argv[i]);
334911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
335911106dfSjm199354 }
336911106dfSjm199354
337911106dfSjm199354 propids |= vap->vap_id;
338911106dfSjm199354 }
339911106dfSjm199354 }
340911106dfSjm199354
341911106dfSjm199354 rc = vs_props_get(&vp, propids);
342911106dfSjm199354 if (rc != VS_ERR_NONE) {
343911106dfSjm199354 (void) fprintf(stderr, "%s\n", vs_strerror(rc));
344911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
345911106dfSjm199354 }
346911106dfSjm199354
347911106dfSjm199354 vs_adm_output_getcmd(propids, &vp);
348911106dfSjm199354
349911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
350911106dfSjm199354 }
351911106dfSjm199354
352911106dfSjm199354
353911106dfSjm199354 /*
354911106dfSjm199354 * vs_adm_set
355911106dfSjm199354 *
356911106dfSjm199354 * Sets values for general vscan service configuration properties
357911106dfSjm199354 *
358911106dfSjm199354 * Calls a common function used by the set, add, and remove
359911106dfSjm199354 * subcommands to modify general property values.
360911106dfSjm199354 */
361911106dfSjm199354 static int
vs_adm_set(int argc,char ** argv)362911106dfSjm199354 vs_adm_set(int argc, char **argv)
363911106dfSjm199354 {
364911106dfSjm199354 vs_props_t vp;
365911106dfSjm199354 uint64_t propids;
366911106dfSjm199354 int rc;
367911106dfSjm199354
368911106dfSjm199354 if (argc < 3)
369911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
370911106dfSjm199354
371911106dfSjm199354 rc = vs_adm_props_from_input(argc, argv, &vp, &propids);
372911106dfSjm199354 if (rc != VS_ADM_EXIT_SUCCESS)
373911106dfSjm199354 return (rc);
374911106dfSjm199354
375911106dfSjm199354 rc = vs_props_set(&vp, propids);
376911106dfSjm199354 if (rc != VS_ERR_NONE) {
377911106dfSjm199354 (void) fprintf(stderr, "%s\n", vs_strerror(rc));
378911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
379911106dfSjm199354 }
380911106dfSjm199354
381911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
382911106dfSjm199354 }
383911106dfSjm199354
384911106dfSjm199354
385911106dfSjm199354 /*
386911106dfSjm199354 * vs_adm_get_engine
387911106dfSjm199354 *
388911106dfSjm199354 * Gets and displays scan engine configuration properties for
389911106dfSjm199354 * one or more scan engines.
390911106dfSjm199354 */
391911106dfSjm199354 static int
vs_adm_get_engine(int argc,char ** argv)392911106dfSjm199354 vs_adm_get_engine(int argc, char **argv)
393911106dfSjm199354 {
394911106dfSjm199354 int i, rc;
395911106dfSjm199354 uint64_t propids;
396911106dfSjm199354 char *engid = NULL;
397911106dfSjm199354 const vs_adm_property_t *vap;
398911106dfSjm199354 vs_props_all_t va;
399911106dfSjm199354
400911106dfSjm199354 propids = 0LL;
401911106dfSjm199354 for (i = 2; i < argc; i++) {
402911106dfSjm199354 /* if not preceded by -p, must be engine id and must be last */
403911106dfSjm199354 if (strcmp(argv[i], "-p") != 0) {
404911106dfSjm199354 if (i != (argc - 1))
405911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
406911106dfSjm199354
407911106dfSjm199354 engid = argv[i];
408911106dfSjm199354 if (strlen(engid) > VS_SE_NAME_LEN) {
409911106dfSjm199354 (void) fprintf(stderr, "%s\n",
410911106dfSjm199354 gettext("invalid scan engine"));
411911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
412911106dfSjm199354 }
413911106dfSjm199354 } else {
414911106dfSjm199354 /* property should follow the -p */
415911106dfSjm199354 if (++i >= argc)
416911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
417911106dfSjm199354
418911106dfSjm199354 if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
419911106dfSjm199354 (void) fprintf(stderr, "%s '%s'\n",
420911106dfSjm199354 gettext("invalid property"), argv[i]);
421911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
422911106dfSjm199354 }
423911106dfSjm199354
424911106dfSjm199354 propids |= vap->vap_id;
425911106dfSjm199354 }
426911106dfSjm199354 }
427911106dfSjm199354
428911106dfSjm199354 if (propids == 0LL)
429911106dfSjm199354 propids = VS_PROPID_SE_ALL;
430911106dfSjm199354
431911106dfSjm199354 /* get properties for specified engine */
432911106dfSjm199354 if (engid) {
433911106dfSjm199354 rc = vs_props_se_get(engid, &va.va_se[0], propids);
434911106dfSjm199354 if (rc != VS_ERR_NONE) {
435911106dfSjm199354 (void) fprintf(stderr, "%s\n", vs_strerror(rc));
436911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
437911106dfSjm199354 }
438911106dfSjm199354 vs_adm_output_getcmd(propids, &va.va_se[0]);
439911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
440911106dfSjm199354 }
441911106dfSjm199354
442911106dfSjm199354 /* get properties for all engines */
443911106dfSjm199354 if ((rc = vs_props_get_all(&va)) != VS_ERR_NONE) {
444911106dfSjm199354 (void) fprintf(stderr, "%s\n", vs_strerror(rc));
445911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
446911106dfSjm199354 }
447911106dfSjm199354
448911106dfSjm199354 for (i = 0; i < VS_SE_MAX; i++) {
449911106dfSjm199354 if (*(va.va_se[i].vep_engid) == 0)
450911106dfSjm199354 break;
451911106dfSjm199354 vs_adm_output_getcmd(propids, &va.va_se[i]);
452911106dfSjm199354 }
453911106dfSjm199354 if (i == 0) {
454911106dfSjm199354 (void) fprintf(stdout, "%s\n",
455911106dfSjm199354 gettext("no scan engines configured"));
456911106dfSjm199354 }
457911106dfSjm199354
458911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
459911106dfSjm199354 }
460911106dfSjm199354
461911106dfSjm199354
462911106dfSjm199354 /*
463911106dfSjm199354 * vs_adm_set_engine
464911106dfSjm199354 *
465911106dfSjm199354 * Sets one or more scan engine configuration properties for a
466911106dfSjm199354 * single scan engine.
467911106dfSjm199354 */
468911106dfSjm199354 static int
vs_adm_set_engine(int argc,char ** argv)469911106dfSjm199354 vs_adm_set_engine(int argc, char **argv)
470911106dfSjm199354 {
471911106dfSjm199354 const vs_adm_property_t *vap;
472911106dfSjm199354 vs_props_se_t sep;
473911106dfSjm199354 char *val;
474911106dfSjm199354 uint64_t propids;
475911106dfSjm199354 int i, rc;
476911106dfSjm199354 char *engid;
477911106dfSjm199354 int add = (strcmp(vs_adm_subcmd, "add-engine") == 0) ? 1 : 0;
478911106dfSjm199354
479911106dfSjm199354
480911106dfSjm199354 if ((argc < 3) || ((!add) && (argc < 4)))
481911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
482911106dfSjm199354
483911106dfSjm199354 /* Get the engine id */
484911106dfSjm199354 engid = argv[argc - 1];
485911106dfSjm199354 if (strchr(engid, '=') || strcmp(argv[argc - 2], "-p") == 0) {
486911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
487911106dfSjm199354 }
488911106dfSjm199354
489911106dfSjm199354 if (strlen(engid) > VS_SE_NAME_LEN) {
490911106dfSjm199354 (void) fprintf(stderr, "%s\n",
491911106dfSjm199354 gettext("invalid scan engine"));
492911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
493911106dfSjm199354 }
494911106dfSjm199354
495911106dfSjm199354 propids = 0LL;
496911106dfSjm199354
497911106dfSjm199354 for (i = 2; i < (argc - 1); i++) {
498911106dfSjm199354 /* The "-p" is optional */
499911106dfSjm199354 if (strcmp(argv[i], "-p") == 0) {
500911106dfSjm199354 if (++i >= argc)
501911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
502911106dfSjm199354 }
503911106dfSjm199354
504911106dfSjm199354 if ((val = strchr(argv[i], '=')) == NULL)
505911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
506911106dfSjm199354
507911106dfSjm199354 *val = 0;
508911106dfSjm199354 val++;
509911106dfSjm199354
510911106dfSjm199354 /* Find the SE property pointer from the SE property name */
511911106dfSjm199354 if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
512911106dfSjm199354 (void) fprintf(stderr, "%s '%s'\n",
513911106dfSjm199354 gettext("invalid property"), argv[i]);
514911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
515911106dfSjm199354 }
516911106dfSjm199354
517911106dfSjm199354 propids |= vap->vap_id;
518911106dfSjm199354
519911106dfSjm199354 if ((vs_adm_parse(vap, val, &sep)) != 0) {
520911106dfSjm199354 (void) fprintf(stderr, "%s '%s'\n",
521911106dfSjm199354 gettext("invalid property value"), val);
522911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
523911106dfSjm199354 }
524911106dfSjm199354 }
525911106dfSjm199354
526911106dfSjm199354 if (add)
527911106dfSjm199354 rc = vs_props_se_create(engid, &sep, propids);
528911106dfSjm199354 else
529911106dfSjm199354 rc = vs_props_se_set(engid, &sep, propids);
530911106dfSjm199354
531911106dfSjm199354 if (rc != VS_ERR_NONE) {
532911106dfSjm199354 (void) fprintf(stderr, "%s\n", vs_strerror(rc));
533911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
534911106dfSjm199354 }
535911106dfSjm199354
536911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
537911106dfSjm199354 }
538911106dfSjm199354
539911106dfSjm199354
540911106dfSjm199354 /*
541911106dfSjm199354 * vs_adm_rem_engine
542911106dfSjm199354 */
543911106dfSjm199354 /* ARGSUSED */
544911106dfSjm199354 static int
vs_adm_rem_engine(int argc,char ** argv)545911106dfSjm199354 vs_adm_rem_engine(int argc, char **argv)
546911106dfSjm199354 {
547911106dfSjm199354 int rc;
548911106dfSjm199354 char *engid;
549911106dfSjm199354
550911106dfSjm199354 if (argc != 3)
551911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
552911106dfSjm199354
553911106dfSjm199354 engid = argv[2];
554911106dfSjm199354
555911106dfSjm199354 if (strlen(engid) > VS_SE_NAME_LEN) {
556911106dfSjm199354 (void) fprintf(stderr, "%s\n",
557911106dfSjm199354 gettext("invalid scan engine"));
558911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
559911106dfSjm199354 }
560911106dfSjm199354
561911106dfSjm199354 if ((rc = vs_props_se_delete(engid)) != VS_ERR_NONE) {
562911106dfSjm199354 (void) fprintf(stderr, "%s\n", vs_strerror(rc));
563911106dfSjm199354 return (rc);
564911106dfSjm199354 }
565911106dfSjm199354
566911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
567911106dfSjm199354 }
568911106dfSjm199354
569911106dfSjm199354
570911106dfSjm199354 /*
571911106dfSjm199354 * vs_adm_import
572911106dfSjm199354 */
573911106dfSjm199354 static int
vs_adm_import(int argc,char ** argv)574911106dfSjm199354 vs_adm_import(int argc, char **argv)
575911106dfSjm199354 {
576911106dfSjm199354 int rc;
577911106dfSjm199354 vs_props_t vp;
578911106dfSjm199354 uint64_t propids;
579911106dfSjm199354 char *filename;
580911106dfSjm199354
581911106dfSjm199354 if ((rc = vs_adm_file_usage(argc, argv)) != VS_ADM_EXIT_SUCCESS)
582911106dfSjm199354 return (rc);
583911106dfSjm199354
584911106dfSjm199354 filename = argv[argc - 1];
585911106dfSjm199354 rc = vs_adm_file_read(filename, vp.vp_types, sizeof (vp.vp_types));
586911106dfSjm199354 if (rc != VS_ADM_EXIT_SUCCESS)
587911106dfSjm199354 return (rc);
588911106dfSjm199354
589911106dfSjm199354 propids = VS_PROPID_TYPES;
590911106dfSjm199354 rc = vs_props_set(&vp, propids);
591911106dfSjm199354 if (rc != VS_ERR_NONE) {
592911106dfSjm199354 (void) fprintf(stderr, "%s\n", vs_strerror(rc));
593911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
594911106dfSjm199354 }
595911106dfSjm199354
596911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
597911106dfSjm199354 }
598911106dfSjm199354
599911106dfSjm199354
600911106dfSjm199354 /*
601911106dfSjm199354 * vs_adm_validate
602911106dfSjm199354 */
603911106dfSjm199354 static int
vs_adm_validate(int argc,char ** argv)604911106dfSjm199354 vs_adm_validate(int argc, char **argv)
605911106dfSjm199354 {
606911106dfSjm199354 int rc;
607911106dfSjm199354 vs_props_t vp;
608911106dfSjm199354 char *filename;
609911106dfSjm199354
610911106dfSjm199354 if ((rc = vs_adm_file_usage(argc, argv)) != VS_ADM_EXIT_SUCCESS)
611911106dfSjm199354 return (rc);
612911106dfSjm199354
613911106dfSjm199354 filename = argv[argc - 1];
614911106dfSjm199354 rc = vs_adm_file_read(filename, vp.vp_types, sizeof (vp.vp_types));
615911106dfSjm199354 if (rc != VS_ADM_EXIT_SUCCESS)
616911106dfSjm199354 return (rc);
617911106dfSjm199354
618911106dfSjm199354 if (vs_props_validate(&vp, VS_PROPID_TYPES) != VS_ERR_NONE) {
619911106dfSjm199354 (void) fprintf(stderr, "%s: %s\n", filename, vs_strerror(rc));
620911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
621911106dfSjm199354 }
622911106dfSjm199354
623911106dfSjm199354 (void) fprintf(stdout, "%s: valid\n", filename);
624911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
625911106dfSjm199354 }
626911106dfSjm199354
627911106dfSjm199354
628911106dfSjm199354 /*
629911106dfSjm199354 * vs_adm_export
630911106dfSjm199354 */
631911106dfSjm199354 static int
vs_adm_export(int argc,char ** argv)632911106dfSjm199354 vs_adm_export(int argc, char **argv)
633911106dfSjm199354 {
634911106dfSjm199354 int rc;
635911106dfSjm199354 vs_props_t vp;
636911106dfSjm199354 uint64_t propids;
637911106dfSjm199354 char *filename;
638911106dfSjm199354
639911106dfSjm199354 if ((rc = vs_adm_file_usage(argc, argv)) != VS_ADM_EXIT_SUCCESS)
640911106dfSjm199354 return (rc);
641911106dfSjm199354
642911106dfSjm199354 filename = argv[argc - 1];
643911106dfSjm199354 (void) memset(&vp, 0, sizeof (vs_props_t));
644911106dfSjm199354 propids = VS_PROPID_TYPES;
645911106dfSjm199354 if ((rc = vs_props_get(&vp, propids)) != VS_ERR_NONE) {
646911106dfSjm199354 (void) fprintf(stderr, "%s: %s\n", filename, vs_strerror(rc));
647911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
648911106dfSjm199354 }
649911106dfSjm199354
650911106dfSjm199354 rc = vs_adm_file_write(filename, vp.vp_types);
651911106dfSjm199354 if (rc != VS_ADM_EXIT_SUCCESS)
652911106dfSjm199354 return (rc);
653911106dfSjm199354
654911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
655911106dfSjm199354 }
656911106dfSjm199354
657911106dfSjm199354
658911106dfSjm199354 /*
659911106dfSjm199354 * vs_adm_file_usage
660911106dfSjm199354 *
661911106dfSjm199354 * import, export and validate - VS_PROPID_TYPES only
662911106dfSjm199354 */
663911106dfSjm199354 static int
vs_adm_file_usage(int argc,char ** argv)664911106dfSjm199354 vs_adm_file_usage(int argc, char **argv)
665911106dfSjm199354 {
666911106dfSjm199354 const vs_adm_property_t *vap;
667911106dfSjm199354 char *prop;
668911106dfSjm199354
669911106dfSjm199354 if (argc < 4)
670911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
671911106dfSjm199354
672911106dfSjm199354 /* -p optional */
673911106dfSjm199354 if (strcmp(argv[2], "-p") == 0) {
674911106dfSjm199354 if (argc != 5)
675911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
676911106dfSjm199354 } else if (argc != 4)
677911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
678911106dfSjm199354
679911106dfSjm199354 /* only VS_PROPID_TYPES supported */
680911106dfSjm199354 prop = argv[argc - 2];
681911106dfSjm199354 vap = vs_adm_prop_by_name(prop);
682911106dfSjm199354 if ((vap == NULL) || (vap->vap_id != VS_PROPID_TYPES)) {
683911106dfSjm199354 (void) fprintf(stderr, "%s '%s'\n",
684911106dfSjm199354 gettext("invalid property"), prop);
685911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
686911106dfSjm199354 }
687911106dfSjm199354
688911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
689911106dfSjm199354 }
690911106dfSjm199354
691911106dfSjm199354
692911106dfSjm199354 /*
693911106dfSjm199354 * vs_adm_file_read
694911106dfSjm199354 */
695911106dfSjm199354 static int
vs_adm_file_read(char * filename,char * buf,int len)696911106dfSjm199354 vs_adm_file_read(char *filename, char *buf, int len)
697911106dfSjm199354 {
698911106dfSjm199354 FILE *fp;
699911106dfSjm199354
700911106dfSjm199354 if ((fp = fopen(filename, "r")) == NULL) {
701911106dfSjm199354 (void) fprintf(stderr, "%s: %s\n", filename,
702911106dfSjm199354 vs_strerror(VS_ERR_SYS));
703911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
704911106dfSjm199354 }
705911106dfSjm199354
706911106dfSjm199354 (void) memset(buf, 0, len);
707911106dfSjm199354 if (fgets(buf, len, fp) == NULL) {
708911106dfSjm199354 (void) fprintf(stderr, "%s: %s\n", filename,
709911106dfSjm199354 gettext("invalid property value"));
710911106dfSjm199354 (void) fclose(fp);
711911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
712911106dfSjm199354 }
713911106dfSjm199354
714911106dfSjm199354 (void) fclose(fp);
715911106dfSjm199354
716911106dfSjm199354 /* remove newline */
717911106dfSjm199354 if (buf[strlen(buf) - 1] == '\n')
718911106dfSjm199354 buf[strlen(buf) - 1] = '\0';
719911106dfSjm199354
720911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
721911106dfSjm199354 }
722911106dfSjm199354
723911106dfSjm199354
724911106dfSjm199354 /*
725911106dfSjm199354 * vs_adm_file_write
726911106dfSjm199354 */
727911106dfSjm199354 static int
vs_adm_file_write(char * filename,char * buf)728911106dfSjm199354 vs_adm_file_write(char *filename, char *buf)
729911106dfSjm199354 {
730911106dfSjm199354 FILE *fp;
731911106dfSjm199354 int bytes;
732911106dfSjm199354
733911106dfSjm199354 if ((fp = fopen(filename, "w")) == NULL) {
734911106dfSjm199354 (void) fprintf(stderr, "%s: %s\n", filename,
735911106dfSjm199354 vs_strerror(VS_ERR_SYS));
736911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
737911106dfSjm199354 }
738911106dfSjm199354
739911106dfSjm199354 bytes = fprintf(fp, "%s\n", buf);
740911106dfSjm199354 if ((bytes < 0) || (bytes != strlen(buf) + 1)) {
741911106dfSjm199354 (void) fprintf(stderr, "%s: %s\n", filename,
742911106dfSjm199354 vs_strerror(VS_ERR_SYS));
743911106dfSjm199354 (void) fclose(fp);
744911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
745911106dfSjm199354 }
746911106dfSjm199354
747911106dfSjm199354 (void) fclose(fp);
748911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
749911106dfSjm199354 }
750911106dfSjm199354
751911106dfSjm199354
752911106dfSjm199354 /*
753911106dfSjm199354 * vs_adm_show
754911106dfSjm199354 *
755911106dfSjm199354 * Gets and displays all general properties and all scan engine
756911106dfSjm199354 * properties.
757911106dfSjm199354 */
758911106dfSjm199354 /* ARGSUSED */
759911106dfSjm199354 static int
vs_adm_show(int argc,char ** argv)760911106dfSjm199354 vs_adm_show(int argc, char **argv)
761911106dfSjm199354 {
762911106dfSjm199354 if (argc > 2)
763911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
764911106dfSjm199354
765911106dfSjm199354 (void) vs_adm_get(argc, argv);
766911106dfSjm199354 (void) vs_adm_get_engine(argc, argv);
767911106dfSjm199354
768911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
769911106dfSjm199354 }
770911106dfSjm199354
771911106dfSjm199354
772911106dfSjm199354 /*
773911106dfSjm199354 * vs_adm_stats
774911106dfSjm199354 *
775911106dfSjm199354 * Gets and displays vscan service statistics.
776911106dfSjm199354 */
777911106dfSjm199354 /* ARGSUSED */
778911106dfSjm199354 static int
vs_adm_stats(int argc,char ** argv)779911106dfSjm199354 vs_adm_stats(int argc, char **argv)
780911106dfSjm199354 {
781911106dfSjm199354 int rc;
782911106dfSjm199354 vs_stats_t stats;
783911106dfSjm199354
784911106dfSjm199354 /* get statistics */
785911106dfSjm199354 if (argc == 2) {
786911106dfSjm199354 if ((rc = vs_statistics(&stats)) == VS_ERR_NONE) {
787911106dfSjm199354 vs_adm_output_stats(&stats);
788911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
789911106dfSjm199354 } else {
790911106dfSjm199354 (void) fprintf(stdout, "%s\n", vs_strerror(rc));
791911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
792911106dfSjm199354 }
793911106dfSjm199354 }
794911106dfSjm199354
795911106dfSjm199354 /* reset statistics */
796911106dfSjm199354 if (argc == 3 && strcmp(argv[2], "-z") == 0) {
797911106dfSjm199354 if ((rc = vs_statistics_reset()) == VS_ERR_NONE) {
798911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
799911106dfSjm199354 } else {
800911106dfSjm199354 (void) fprintf(stdout, "%s\n", vs_strerror(rc));
801911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
802911106dfSjm199354 }
803911106dfSjm199354 }
804911106dfSjm199354
805911106dfSjm199354 /* usage error */
806911106dfSjm199354 return (vs_adm_usage(stdout));
807911106dfSjm199354 }
808911106dfSjm199354
809911106dfSjm199354
810911106dfSjm199354 /*
811911106dfSjm199354 * vs_adm_output_stats
812911106dfSjm199354 */
813911106dfSjm199354 static void
vs_adm_output_stats(vs_stats_t * stats)814911106dfSjm199354 vs_adm_output_stats(vs_stats_t *stats)
815911106dfSjm199354 {
816911106dfSjm199354 int i;
817911106dfSjm199354 char *engid;
818911106dfSjm199354
819911106dfSjm199354 if (stats == NULL)
820911106dfSjm199354 return;
821911106dfSjm199354
822911106dfSjm199354 (void) fprintf(stdout, "scanned=%lld\n", stats->vss_scanned);
823911106dfSjm199354 (void) fprintf(stdout, "infected=%lld\n", stats->vss_infected);
824911106dfSjm199354 if (stats->vss_cleaned > 0)
825911106dfSjm199354 (void) printf("cleaned=%lld\n", stats->vss_cleaned);
826911106dfSjm199354 (void) fprintf(stdout, "failed=%lld\n", stats->vss_failed);
827911106dfSjm199354
828911106dfSjm199354 for (i = 0; i < VS_SE_MAX; i++) {
829911106dfSjm199354 engid = stats->vss_eng[i].vss_engid;
830911106dfSjm199354 if (*engid == 0)
831911106dfSjm199354 break;
832911106dfSjm199354 (void) fprintf(stdout, "%s:errors=%lld\n", engid,
833911106dfSjm199354 stats->vss_eng[i].vss_errors);
834911106dfSjm199354 }
835911106dfSjm199354 }
836911106dfSjm199354
837911106dfSjm199354
838911106dfSjm199354 /*
839911106dfSjm199354 * vs_adm_props_from_input
840911106dfSjm199354 */
841911106dfSjm199354 static int
vs_adm_props_from_input(int argc,char ** argv,vs_props_t * vsprops,uint64_t * propids)842911106dfSjm199354 vs_adm_props_from_input(int argc, char **argv, vs_props_t *vsprops,
843911106dfSjm199354 uint64_t *propids)
844911106dfSjm199354 {
845911106dfSjm199354 const vs_adm_property_t *vap;
846911106dfSjm199354 char *val;
847911106dfSjm199354 int i;
848911106dfSjm199354
849911106dfSjm199354 (void) memset(vsprops, 0, sizeof (vs_props_t));
850911106dfSjm199354
851911106dfSjm199354 *propids = 0LL;
852911106dfSjm199354 for (i = 2; i < argc; i++) {
853911106dfSjm199354 /* The "-p" is optional */
854911106dfSjm199354 if (strcmp(argv[i], "-p") == 0) {
855911106dfSjm199354 if (++i >= argc)
856911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
857911106dfSjm199354 }
858911106dfSjm199354
859911106dfSjm199354 if ((val = strchr(argv[i], '=')) == NULL)
860911106dfSjm199354 return (VS_ADM_EXIT_USAGE);
861911106dfSjm199354
862911106dfSjm199354 /* Find the vscanadm property pointer from the property name */
863911106dfSjm199354 *val = '\0';
864911106dfSjm199354 val++;
865911106dfSjm199354 if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
866911106dfSjm199354 (void) fprintf(stderr, "%s '%s'\n",
867911106dfSjm199354 gettext("invalid property"), argv[i]);
868911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
869911106dfSjm199354 }
870911106dfSjm199354
871911106dfSjm199354 /* Add in the property id and parse the property value */
872911106dfSjm199354 *propids |= vap->vap_id;
873911106dfSjm199354 if ((vs_adm_parse(vap, val, vsprops)) != 0) {
874911106dfSjm199354 (void) fprintf(stderr, "%s '%s'\n",
875911106dfSjm199354 gettext("invalid property value"), val);
876911106dfSjm199354 return (VS_ADM_EXIT_ERROR);
877911106dfSjm199354 }
878911106dfSjm199354 }
879911106dfSjm199354
880911106dfSjm199354 return (VS_ADM_EXIT_SUCCESS);
881911106dfSjm199354 }
882911106dfSjm199354
883911106dfSjm199354
884911106dfSjm199354 /*
885911106dfSjm199354 * vs_adm_output_getcmd
886911106dfSjm199354 *
887911106dfSjm199354 * Prints the results of a get command; both the get for general
888911106dfSjm199354 * configuration properties as well as the get for an engine
889911106dfSjm199354 * properties.
890911106dfSjm199354 *
891911106dfSjm199354 */
892911106dfSjm199354 static void
vs_adm_output_getcmd(uint64_t propids,const void * props)893911106dfSjm199354 vs_adm_output_getcmd(uint64_t propids, const void *props)
894911106dfSjm199354 {
895911106dfSjm199354 char value[VS_ADM_PRINT_BUF_LEN];
896911106dfSjm199354 uint64_t propid;
897911106dfSjm199354 const vs_adm_property_t *vap;
898911106dfSjm199354 char *label = NULL;
899911106dfSjm199354
900911106dfSjm199354 if (VS_PROPID_IS_SE(propids))
901911106dfSjm199354 label = ((vs_props_se_t *)props)->vep_engid;
902911106dfSjm199354
903911106dfSjm199354 /*
904911106dfSjm199354 * Unparse values from the property structure into readable strings
905911106dfSjm199354 * and print them.
906911106dfSjm199354 */
907911106dfSjm199354 for (propid = 1LL; propid <= VS_PROPID_MAX; propid <<= 1) {
908911106dfSjm199354 if ((propids & propid) == 0)
909911106dfSjm199354 continue;
910911106dfSjm199354
911911106dfSjm199354 if ((vap = vs_adm_prop_by_id(propid)) == NULL)
912911106dfSjm199354 continue;
913911106dfSjm199354
914911106dfSjm199354 *value = '\0';
915911106dfSjm199354 vs_adm_unparse(vap, props, value, sizeof (value));
916911106dfSjm199354
917911106dfSjm199354 if (label)
918911106dfSjm199354 (void) fprintf(stdout, "%s:", label);
919911106dfSjm199354 (void) fprintf(stdout, "%s=%s\n", vap->vap_name, value);
920911106dfSjm199354 }
921911106dfSjm199354
922911106dfSjm199354 (void) fprintf(stdout, "\n");
923911106dfSjm199354 }
924911106dfSjm199354
925911106dfSjm199354
926911106dfSjm199354 /*
927911106dfSjm199354 * vs_adm_prop_by_name
928911106dfSjm199354 *
929911106dfSjm199354 * Finds and returns a pointer to a vscan property structure from the
930911106dfSjm199354 * property table by property name.
931911106dfSjm199354 */
932911106dfSjm199354 static const vs_adm_property_t *
vs_adm_prop_by_name(const char * propname)933911106dfSjm199354 vs_adm_prop_by_name(const char *propname)
934911106dfSjm199354 {
935911106dfSjm199354 const vs_adm_property_t *p;
936911106dfSjm199354
937911106dfSjm199354 for (p = vs_adm_props_all; p->vap_name != NULL; p++) {
938911106dfSjm199354 if (strcmp(propname, p->vap_name) == 0)
939911106dfSjm199354 return (p);
940911106dfSjm199354 }
941911106dfSjm199354
942911106dfSjm199354 return (NULL);
943911106dfSjm199354 }
944911106dfSjm199354
945911106dfSjm199354
946911106dfSjm199354 /*
947911106dfSjm199354 * vs_adm_prop_by_id
948911106dfSjm199354 *
949911106dfSjm199354 * Finds and returns a pointer to a vscan property structure from the
950911106dfSjm199354 * property table by property name.
951911106dfSjm199354 */
952911106dfSjm199354 static const vs_adm_property_t *
vs_adm_prop_by_id(const uint64_t propid)953911106dfSjm199354 vs_adm_prop_by_id(const uint64_t propid)
954911106dfSjm199354 {
955911106dfSjm199354 const vs_adm_property_t *p;
956911106dfSjm199354
957911106dfSjm199354 for (p = vs_adm_props_all; p->vap_id != 0; p++) {
958911106dfSjm199354 if (propid == p->vap_id)
959911106dfSjm199354 return (p);
960911106dfSjm199354 }
961911106dfSjm199354
962911106dfSjm199354 return (NULL);
963911106dfSjm199354 }
964911106dfSjm199354
965911106dfSjm199354
966911106dfSjm199354 /*
967911106dfSjm199354 * vs_adm_parse
968911106dfSjm199354 *
969911106dfSjm199354 * Entry point for parsing the user input strings into a data structure
970911106dfSjm199354 * used for setting values. Dispatches the actual parsing to the parse
971911106dfSjm199354 * routine for the specified vscanadm property.
972911106dfSjm199354 *
973911106dfSjm199354 * This function is used to dispatch parsing for values supplied by the
974911106dfSjm199354 * user for all subcommands; both the general configuration as well as
975911106dfSjm199354 * scan engine configuration. The structure pointer is therefore typed
976911106dfSjm199354 * as a void pointer, and cast appropriately in the parse routine for
977911106dfSjm199354 * the vscanadm property.
978911106dfSjm199354 */
979911106dfSjm199354 static int
vs_adm_parse(const vs_adm_property_t * vap,const char * valvap_name,void * vp)980911106dfSjm199354 vs_adm_parse(const vs_adm_property_t *vap, const char *valvap_name,
981911106dfSjm199354 void *vp)
982911106dfSjm199354 {
983911106dfSjm199354 return ((vap->vap_parse)(valvap_name, vp));
984911106dfSjm199354 }
985911106dfSjm199354
986911106dfSjm199354
987911106dfSjm199354 /*
988911106dfSjm199354 * vs_adm_parse_maxsize
989911106dfSjm199354 *
990911106dfSjm199354 * Parses a user-supplied string into a maxsize (decimal) value for
991911106dfSjm199354 * the general vscan configuration properties.
992911106dfSjm199354 */
993911106dfSjm199354 static int
vs_adm_parse_maxsize(const char * valstr,void * vp)994911106dfSjm199354 vs_adm_parse_maxsize(const char *valstr, void *vp)
995911106dfSjm199354 {
996911106dfSjm199354 vs_props_t *svcp = vp;
997911106dfSjm199354
998911106dfSjm199354 uint64_t maxsize;
999911106dfSjm199354 char *end;
1000911106dfSjm199354
1001911106dfSjm199354 errno = 0;
1002911106dfSjm199354 maxsize = strtoll(valstr, &end, 10);
1003911106dfSjm199354 if (errno != 0)
1004911106dfSjm199354 return (-1);
1005911106dfSjm199354 (void) snprintf(svcp->vp_maxsize, sizeof (svcp->vp_maxsize),
1006911106dfSjm199354 "%llu%s", maxsize, end);
1007911106dfSjm199354
1008911106dfSjm199354 return (0);
1009911106dfSjm199354 }
1010911106dfSjm199354
1011911106dfSjm199354
1012911106dfSjm199354 /*
1013911106dfSjm199354 * vs_adm_parse_maxsize_action
1014911106dfSjm199354 *
1015911106dfSjm199354 * Parses a user-supplied string into a maxsize action value for the
1016911106dfSjm199354 * general vscan configuration properties.
1017911106dfSjm199354 *
1018911106dfSjm199354 * Returns: 0 success
1019911106dfSjm199354 * -1 failure
1020911106dfSjm199354 */
1021911106dfSjm199354 static int
vs_adm_parse_maxsize_action(const char * valstr,void * vp)1022911106dfSjm199354 vs_adm_parse_maxsize_action(const char *valstr, void *vp)
1023911106dfSjm199354 {
1024911106dfSjm199354 vs_props_t *svcp = vp;
1025911106dfSjm199354
1026911106dfSjm199354 if (strcmp(valstr, VS_ADM_ALLOW) == 0) {
1027911106dfSjm199354 svcp->vp_maxsize_action = B_TRUE;
1028911106dfSjm199354 return (0);
1029911106dfSjm199354 }
1030911106dfSjm199354
1031911106dfSjm199354 if (strcmp(valstr, VS_ADM_DENY) == 0) {
1032911106dfSjm199354 svcp->vp_maxsize_action = B_FALSE;
1033911106dfSjm199354 return (0);
1034911106dfSjm199354 }
1035911106dfSjm199354
1036911106dfSjm199354 return (-1);
1037911106dfSjm199354 }
1038911106dfSjm199354
1039911106dfSjm199354
1040911106dfSjm199354 /*
1041911106dfSjm199354 * vs_adm_parse_types
1042911106dfSjm199354 *
1043911106dfSjm199354 * Returns: 0 success
1044911106dfSjm199354 * -1 on failure.
1045911106dfSjm199354 */
1046911106dfSjm199354 static int
vs_adm_parse_types(const char * valstr,void * vp)1047911106dfSjm199354 vs_adm_parse_types(const char *valstr, void *vp)
1048911106dfSjm199354 {
1049911106dfSjm199354 vs_props_t *svcp = vp;
1050911106dfSjm199354
1051911106dfSjm199354 if (strlen(valstr) >= sizeof (svcp->vp_types))
1052911106dfSjm199354 return (-1);
1053911106dfSjm199354
1054911106dfSjm199354 if (strlcpy(svcp->vp_types, valstr, sizeof (svcp->vp_types))
1055911106dfSjm199354 >= sizeof (svcp->vp_types))
1056911106dfSjm199354 return (-1);
1057911106dfSjm199354
1058911106dfSjm199354 return (0);
1059911106dfSjm199354 }
1060911106dfSjm199354
1061911106dfSjm199354
1062911106dfSjm199354 /*
1063911106dfSjm199354 * vs_adm_parse_enable
1064911106dfSjm199354 *
1065911106dfSjm199354 * Parses a user-supplied string into an enable value for the
1066911106dfSjm199354 * properties of a scan engine.
1067911106dfSjm199354 *
1068911106dfSjm199354 * Returns: 0 success
1069911106dfSjm199354 * -1 on failure.
1070911106dfSjm199354 */
1071911106dfSjm199354 static int
vs_adm_parse_enable(const char * valstr,void * vp)1072911106dfSjm199354 vs_adm_parse_enable(const char *valstr, void *vp)
1073911106dfSjm199354 {
1074911106dfSjm199354 vs_props_se_t *sep = vp;
1075911106dfSjm199354
1076911106dfSjm199354 if (strcmp(valstr, VS_ADM_ON) == 0) {
1077911106dfSjm199354 sep->vep_enable = B_TRUE;
1078911106dfSjm199354 return (0);
1079911106dfSjm199354 }
1080911106dfSjm199354
1081911106dfSjm199354 if (strcmp(valstr, VS_ADM_OFF) == 0) {
1082911106dfSjm199354 sep->vep_enable = B_FALSE;
1083911106dfSjm199354 return (0);
1084911106dfSjm199354 }
1085911106dfSjm199354
1086911106dfSjm199354 return (-1);
1087911106dfSjm199354 }
1088911106dfSjm199354
1089911106dfSjm199354
1090911106dfSjm199354 /*
1091911106dfSjm199354 * vs_adm_parse_host
1092911106dfSjm199354 *
1093911106dfSjm199354 * Parses a user-supplied string into an ip address value for the
1094911106dfSjm199354 * properties of a scan engine.
1095911106dfSjm199354 */
1096911106dfSjm199354 static int
vs_adm_parse_host(const char * valstr,void * vp)1097911106dfSjm199354 vs_adm_parse_host(const char *valstr, void *vp)
1098911106dfSjm199354 {
1099911106dfSjm199354 vs_props_se_t *sep = vp;
1100911106dfSjm199354
1101911106dfSjm199354 if (strlen(valstr) >= sizeof (sep->vep_host))
1102911106dfSjm199354 return (-1);
1103911106dfSjm199354
1104911106dfSjm199354 if (strlcpy(sep->vep_host, valstr, sizeof (sep->vep_host)) >=
1105911106dfSjm199354 sizeof (sep->vep_host))
1106911106dfSjm199354 return (-1);
1107911106dfSjm199354
1108911106dfSjm199354 return (0);
1109911106dfSjm199354 }
1110911106dfSjm199354
1111911106dfSjm199354
1112911106dfSjm199354 /*
1113911106dfSjm199354 * vs_adm_parse_port
1114911106dfSjm199354 *
1115911106dfSjm199354 * Parses a user-supplied string into a port value for the properties of
1116911106dfSjm199354 * a scan engine. The port is an unsigned short int, but the conversion
1117911106dfSjm199354 * must be done on a word-sized int. Casting the converted int into the
1118911106dfSjm199354 * port member of the property structure can result in a valid but
1119911106dfSjm199354 * unintended value, so the range is checked first for validity.
1120911106dfSjm199354 *
1121911106dfSjm199354 * Returns: 0 success
1122911106dfSjm199354 * -1 on failure.
1123911106dfSjm199354 */
1124911106dfSjm199354 static int
vs_adm_parse_port(const char * valstr,void * vp)1125911106dfSjm199354 vs_adm_parse_port(const char *valstr, void *vp)
1126911106dfSjm199354 {
1127911106dfSjm199354 vs_props_se_t *sep = vp;
1128911106dfSjm199354 unsigned long port;
1129911106dfSjm199354 char *end;
1130911106dfSjm199354
1131911106dfSjm199354 end = 0;
1132911106dfSjm199354 port = strtoul(valstr, &end, 0);
1133911106dfSjm199354 if (port > UINT16_MAX || (end < (valstr + strlen(valstr))))
1134911106dfSjm199354 return (-1);
1135911106dfSjm199354
1136911106dfSjm199354 sep->vep_port = port;
1137911106dfSjm199354
1138911106dfSjm199354 return (0);
1139911106dfSjm199354 }
1140911106dfSjm199354
1141911106dfSjm199354
1142911106dfSjm199354 /*
1143911106dfSjm199354 * vs_adm_parse_maxconn
1144911106dfSjm199354 *
1145911106dfSjm199354 * Parses a user-supplied string into a max connections (decimal) value
1146911106dfSjm199354 * for the properties of a scan engine.
1147911106dfSjm199354 *
1148911106dfSjm199354 * Returns: 0 success
1149911106dfSjm199354 * -1 on failure.
1150911106dfSjm199354 */
1151911106dfSjm199354 static int
vs_adm_parse_maxconn(const char * valstr,void * vp)1152911106dfSjm199354 vs_adm_parse_maxconn(const char *valstr, void *vp)
1153911106dfSjm199354 {
1154911106dfSjm199354 vs_props_se_t *sep = vp;
1155911106dfSjm199354 char *end;
1156911106dfSjm199354
1157911106dfSjm199354 sep->vep_maxconn = strtoll(valstr, &end, 10);
1158911106dfSjm199354 if (end < valstr + strlen(valstr))
1159911106dfSjm199354 return (-1);
1160911106dfSjm199354
1161911106dfSjm199354 return (0);
1162911106dfSjm199354 }
1163911106dfSjm199354
1164911106dfSjm199354
1165911106dfSjm199354 /*
1166911106dfSjm199354 * vs_adm_unparse
1167911106dfSjm199354 *
1168911106dfSjm199354 * Entry point for unparsing native data into a readable string
1169911106dfSjm199354 * used for display to the user. Dispatches the actual unparsing to
1170911106dfSjm199354 * the unparse routine for the specified vscanadm property.
1171911106dfSjm199354 *
1172911106dfSjm199354 * This function is used to dispatch unparsing for all subcommands.
1173911106dfSjm199354 * The structure pointer is therefore typed as a void pointer, and
1174911106dfSjm199354 * cast appropriately in the unparse routine for the vscanadm property.
1175911106dfSjm199354 */
1176911106dfSjm199354 static void
vs_adm_unparse(const vs_adm_property_t * vap,const void * vp,char * buf,size_t len)1177911106dfSjm199354 vs_adm_unparse(const vs_adm_property_t *vap, const void *vp,
1178911106dfSjm199354 char *buf, size_t len)
1179911106dfSjm199354 {
1180911106dfSjm199354 if ((vap->vap_unparse)(vp, buf, len) != 0)
1181911106dfSjm199354 (void) snprintf(buf, len, gettext(" (error) "));
1182911106dfSjm199354 }
1183911106dfSjm199354
1184911106dfSjm199354
1185911106dfSjm199354 /*
1186911106dfSjm199354 * vs_adm_unparse_maxsize
1187911106dfSjm199354 *
1188911106dfSjm199354 * Unparses a max fsize value in native data form into a
1189911106dfSjm199354 * user-readable string.
1190911106dfSjm199354 */
1191911106dfSjm199354 /* ARGSUSED */
1192911106dfSjm199354 static int
vs_adm_unparse_maxsize(const void * vp,char * buf,size_t len)1193911106dfSjm199354 vs_adm_unparse_maxsize(const void *vp, char *buf, size_t len)
1194911106dfSjm199354 {
1195911106dfSjm199354 const vs_props_t *svcp = vp;
1196911106dfSjm199354
1197911106dfSjm199354 (void) snprintf(buf, len, "%s", svcp->vp_maxsize);
1198911106dfSjm199354
1199911106dfSjm199354 return (0);
1200911106dfSjm199354 }
1201911106dfSjm199354
1202911106dfSjm199354
1203911106dfSjm199354 /*
1204911106dfSjm199354 * vs_adm_unparse_maxsize_action
1205911106dfSjm199354 *
1206911106dfSjm199354 * Unparses a max fsize action value in native data form into a
1207911106dfSjm199354 * user-readable string.
1208911106dfSjm199354 */
1209911106dfSjm199354 /* ARGSUSED */
1210911106dfSjm199354 static int
vs_adm_unparse_maxsize_action(const void * vp,char * buf,size_t len)1211911106dfSjm199354 vs_adm_unparse_maxsize_action(const void *vp, char *buf, size_t len)
1212911106dfSjm199354 {
1213911106dfSjm199354 const vs_props_t *svcp = vp;
1214911106dfSjm199354
1215911106dfSjm199354 (void) snprintf(buf, len, "%s",
1216911106dfSjm199354 svcp->vp_maxsize_action ? VS_ADM_ALLOW : VS_ADM_DENY);
1217911106dfSjm199354
1218911106dfSjm199354 return (0);
1219911106dfSjm199354 }
1220911106dfSjm199354
1221911106dfSjm199354
1222911106dfSjm199354 /*
1223911106dfSjm199354 * vs_adm_unparse_types
1224911106dfSjm199354 *
1225911106dfSjm199354 * Returns: 0 success
1226911106dfSjm199354 * -1 on failure.
1227911106dfSjm199354 */
1228911106dfSjm199354 static int
vs_adm_unparse_types(const void * vp,char * buf,size_t len)1229911106dfSjm199354 vs_adm_unparse_types(const void *vp, char *buf, size_t len)
1230911106dfSjm199354 {
1231911106dfSjm199354 const vs_props_t *svcp = vp;
1232911106dfSjm199354
1233911106dfSjm199354 (void) strlcpy(buf, svcp->vp_types, len);
1234911106dfSjm199354
1235911106dfSjm199354 return (0);
1236911106dfSjm199354 }
1237911106dfSjm199354
1238911106dfSjm199354
1239911106dfSjm199354 /*
1240911106dfSjm199354 * vs_adm_unparse_enable
1241911106dfSjm199354 *
1242911106dfSjm199354 * Unparses the enable value for a scan engine in native data
1243911106dfSjm199354 * form into a user-readable string.
1244911106dfSjm199354 */
1245911106dfSjm199354 /* ARGSUSED */
1246911106dfSjm199354 static int
vs_adm_unparse_enable(const void * vp,char * buf,size_t len)1247911106dfSjm199354 vs_adm_unparse_enable(const void *vp, char *buf, size_t len)
1248911106dfSjm199354 {
1249911106dfSjm199354 const vs_props_se_t *sep = vp;
1250911106dfSjm199354
1251911106dfSjm199354 (void) snprintf(buf, len, "%s",
1252911106dfSjm199354 sep->vep_enable ? VS_ADM_ON : VS_ADM_OFF);
1253911106dfSjm199354
1254911106dfSjm199354 return (0);
1255911106dfSjm199354 }
1256911106dfSjm199354
1257911106dfSjm199354
1258911106dfSjm199354 /*
1259911106dfSjm199354 * vs_adm_unparse_host
1260911106dfSjm199354 *
1261911106dfSjm199354 * Unparses an ip address for a scan engine in native data
1262911106dfSjm199354 * form into a user-readable string.
1263911106dfSjm199354 *
1264911106dfSjm199354 * Returns: 0 success
1265911106dfSjm199354 * -1 on failure.
1266911106dfSjm199354 */
1267911106dfSjm199354 /* ARGSUSED */
1268911106dfSjm199354 static int
vs_adm_unparse_host(const void * vp,char * buf,size_t len)1269911106dfSjm199354 vs_adm_unparse_host(const void *vp, char *buf, size_t len)
1270911106dfSjm199354 {
1271911106dfSjm199354 const vs_props_se_t *sep = vp;
1272911106dfSjm199354
1273911106dfSjm199354 (void) strlcpy(buf, sep->vep_host, len);
1274911106dfSjm199354
1275911106dfSjm199354 return (0);
1276911106dfSjm199354 }
1277911106dfSjm199354
1278911106dfSjm199354
1279911106dfSjm199354 /*
1280911106dfSjm199354 * vs_adm_unparse_port
1281911106dfSjm199354 *
1282911106dfSjm199354 * Unparses a port value for a scan engine in native data
1283911106dfSjm199354 * form into a user-readable string.
1284911106dfSjm199354 */
1285911106dfSjm199354 /* ARGSUSED */
1286911106dfSjm199354 static int
vs_adm_unparse_port(const void * vp,char * buf,size_t len)1287911106dfSjm199354 vs_adm_unparse_port(const void *vp, char *buf, size_t len)
1288911106dfSjm199354 {
1289911106dfSjm199354 const vs_props_se_t *sep = vp;
1290911106dfSjm199354
1291911106dfSjm199354 (void) snprintf(buf, len, "%hu", sep->vep_port);
1292911106dfSjm199354
1293911106dfSjm199354 return (0);
1294911106dfSjm199354 }
1295911106dfSjm199354
1296911106dfSjm199354
1297911106dfSjm199354 /*
1298911106dfSjm199354 * vs_adm_unparse_maxconn
1299911106dfSjm199354 *
1300911106dfSjm199354 * Unparses a max connecctions for a scan engine in native data
1301911106dfSjm199354 * form into a user-readable string.
1302911106dfSjm199354 *
1303911106dfSjm199354 */
1304911106dfSjm199354 /* ARGSUSED */
1305911106dfSjm199354 static int
vs_adm_unparse_maxconn(const void * vp,char * buf,size_t len)1306911106dfSjm199354 vs_adm_unparse_maxconn(const void *vp, char *buf, size_t len)
1307911106dfSjm199354 {
1308911106dfSjm199354 const vs_props_se_t *sep = vp;
1309911106dfSjm199354
1310911106dfSjm199354 (void) snprintf(buf, len, "%lld", sep->vep_maxconn);
1311911106dfSjm199354
1312911106dfSjm199354 return (0);
1313911106dfSjm199354 }
1314