4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
34 #include <arpa/inet.h>
36 #include <sys/types.h>
43 #if !defined(TEXT_DOMAIN)
44 #define TEXT_DOMAIN "SYS_TEST"
49 #define VS_ADM_MAXSIZE "max-size"
50 #define VS_ADM_MAXSIZE_ACTION "max-size-action"
51 #define VS_ADM_TYPES "types"
53 /* Scan Engine Property Names */
54 #define VS_ADM_SE_ENABLE "enable"
55 #define VS_ADM_SE_HOST "host"
56 #define VS_ADM_SE_PORT "port"
57 #define VS_ADM_SE_MAXCONN "max-connection"
60 #define VS_ADM_ON "on"
61 #define VS_ADM_OFF "off"
62 #define VS_ADM_ALLOW "allow"
63 #define VS_ADM_DENY "deny"
67 * Print buffer length: used for sizing buffers that are filled with
68 * user-readable strings for property values. Define a number that
69 * accounts for some pre-value information, and won't (likely)
70 * wrap an 80-column display
72 #define VS_ADM_PRINT_BUF_LEN 4096
74 /* Program exit codes */
75 #define VS_ADM_EXIT_SUCCESS 0
76 #define VS_ADM_EXIT_ERROR 1
77 #define VS_ADM_EXIT_USAGE 2
81 * vscanadm property definition. Maps the property ids to a
82 * property name, and includes functions to convert to and from
83 * input strings and native data.
85 typedef struct vs_adm_property
{
88 int (*vap_parse
)(const char *, void *);
89 int (*vap_unparse
)(const void *, char *, size_t);
93 /* usage/help information for subcommnds */
94 #define VS_ADM_HELP_GET ("[-p property]...\n" \
95 "\tdisplay vscan properties")
96 #define VS_ADM_HELP_SET ("-p property=value [-p property=value]...\n" \
97 "\tset values of vscan properties")
98 #define VS_ADM_HELP_GET_ENG ("[-p property] [engine_id]\n" \
99 "\tdisplay values of scan engine properties")
100 #define VS_ADM_HELP_ADD_ENG ("[-p property=value]... engine_id\n" \
102 #define VS_ADM_HELP_SET_ENG ("-p property=value [-p property=value]" \
103 "... engine_id\n\tset values of scan engine properties")
104 #define VS_ADM_HELP_REM_ENG ("engine_id\n" \
105 "\tremove scan engine")
106 #define VS_ADM_HELP_SHOW ("\n\tdisplay the values of all vscan " \
107 "service and scan engine properties")
108 #define VS_ADM_HELP_STATS ("[-z]\n\tdisplay vscan service statistics")
109 #define VS_ADM_HELP_IMPORT ("-p property filename\n" \
110 "\timport property from file")
111 #define VS_ADM_HELP_EXPORT ("-p property filename\n" \
112 "\texport property to file")
113 #define VS_ADM_HELP_VALIDATE ("-p property filename\n" \
114 "\tvalidate property in file")
118 * vscanadm command structure. Encapsulates the vscanadm
119 * subcommand name, pointer to the subcommand implementation
120 * function, and a help id to get usage/help information.
122 typedef struct vs_adm_cmd
{
123 int (*vac_func
)(int, char *[]);
124 const char *vac_name
;
130 /* Subcommand implementation functions */
131 static int vs_adm_set(int, char **);
132 static int vs_adm_get(int, char **);
133 static int vs_adm_set_engine(int, char **);
134 static int vs_adm_get_engine(int, char **);
135 static int vs_adm_rem_engine(int, char **);
136 static int vs_adm_show(int, char **);
137 static int vs_adm_stats(int, char **);
138 static int vs_adm_import(int, char **);
139 static int vs_adm_export(int, char **);
140 static int vs_adm_validate(int, char **);
144 * Parse routines to transform libvscan API data into user-readable strings
146 static int vs_adm_parse_maxsize(const char *, void *);
147 static int vs_adm_parse_maxsize_action(const char *, void *);
148 static int vs_adm_parse_types(const char *, void *);
149 static int vs_adm_parse_enable(const char *, void *);
150 static int vs_adm_parse_host(const char *, void *);
151 static int vs_adm_parse_port(const char *, void *);
152 static int vs_adm_parse_maxconn(const char *, void *);
156 * Unparse routines to transform strings from the user input into
159 * While some value validation is performed in the course of unparsing
160 * string data, complete value validation is left to libvscan.
161 * Values that are in unacceptable form, out of range, or otherwise
162 * violate rules for a given property will be rejected
164 static int vs_adm_unparse_maxsize(const void *, char *, size_t);
165 static int vs_adm_unparse_maxsize_action(const void *, char *, size_t);
166 static int vs_adm_unparse_types(const void *, char *, size_t);
167 static int vs_adm_unparse_enable(const void *, char *, size_t);
168 static int vs_adm_unparse_host(const void *, char *, size_t);
169 static int vs_adm_unparse_port(const void *, char *, size_t);
170 static int vs_adm_unparse_maxconn(const void *, char *, size_t);
174 * The properties table includes a vscanadm property entry, specifying
175 * the property nane, property id, parse amd inparse methods,
176 * for each vscanadm property.
178 static const vs_adm_property_t vs_adm_props_all
[] = {
179 { VS_ADM_MAXSIZE
, VS_PROPID_MAXSIZE
,
180 vs_adm_parse_maxsize
, vs_adm_unparse_maxsize
},
181 { VS_ADM_MAXSIZE_ACTION
, VS_PROPID_MAXSIZE_ACTION
,
182 vs_adm_parse_maxsize_action
, vs_adm_unparse_maxsize_action
},
183 { VS_ADM_TYPES
, VS_PROPID_TYPES
,
184 vs_adm_parse_types
, vs_adm_unparse_types
},
185 { VS_ADM_SE_ENABLE
, VS_PROPID_SE_ENABLE
,
186 vs_adm_parse_enable
, vs_adm_unparse_enable
},
187 { VS_ADM_SE_HOST
, VS_PROPID_SE_HOST
,
188 vs_adm_parse_host
, vs_adm_unparse_host
},
189 { VS_ADM_SE_PORT
, VS_PROPID_SE_PORT
,
190 vs_adm_parse_port
, vs_adm_unparse_port
},
191 { VS_ADM_SE_MAXCONN
, VS_PROPID_SE_MAXCONN
,
192 vs_adm_parse_maxconn
, vs_adm_unparse_maxconn
},
193 { NULL
, 0, NULL
, NULL
}
198 * The subcommand table. Used to find the subcommand specified
199 * by the user and dispatch the processing for the subcommand.
200 * Also used to display usage information for each subcommand.
202 static const vs_adm_cmd_t vs_adm_cmds
[] =
204 { vs_adm_get
, "get", VS_ADM_HELP_GET
},
205 { vs_adm_set
, "set", VS_ADM_HELP_SET
},
206 { vs_adm_get_engine
, "get-engine", VS_ADM_HELP_GET_ENG
},
207 { vs_adm_set_engine
, "set-engine", VS_ADM_HELP_SET_ENG
},
208 { vs_adm_set_engine
, "add-engine", VS_ADM_HELP_ADD_ENG
},
209 { vs_adm_rem_engine
, "remove-engine", VS_ADM_HELP_REM_ENG
},
210 { vs_adm_import
, "import", VS_ADM_HELP_IMPORT
},
211 { vs_adm_export
, "export", VS_ADM_HELP_EXPORT
},
212 { vs_adm_validate
, "validate", VS_ADM_HELP_VALIDATE
},
213 { vs_adm_show
, "show", VS_ADM_HELP_SHOW
},
214 { vs_adm_stats
, "stats", VS_ADM_HELP_STATS
},
219 static const char *vs_adm_cmd
;
220 static const char *vs_adm_subcmd
;
222 static int vs_adm_usage(FILE *);
223 static int vs_adm_props_from_input(int, char **, vs_props_t
*, uint64_t *);
224 static void vs_adm_output_getcmd(uint64_t, const void *);
225 static void vs_adm_output_stats(vs_stats_t
*);
226 static const vs_adm_property_t
*vs_adm_prop_by_name(const char *);
227 static const vs_adm_property_t
*vs_adm_prop_by_id(const uint64_t);
228 static int vs_adm_parse(const vs_adm_property_t
*, const char *, void *);
229 static void vs_adm_unparse(const vs_adm_property_t
*, const void *,
232 static int vs_adm_file_read(char *, char *, int);
233 static int vs_adm_file_write(char *, char *);
234 static int vs_adm_file_usage(int argc
, char **argv
);
240 main(int argc
, char **argv
)
242 const vs_adm_cmd_t
*cp
;
246 (void) setlocale(LC_ALL
, "");
247 (void) textdomain(TEXT_DOMAIN
);
249 /* executable and subcommand names */
250 if ((p
= strrchr(argv
[0], '/')) == NULL
)
251 vs_adm_cmd
= argv
[0];
255 vs_adm_subcmd
= argv
[1];
257 /* require at least command and sub-command */
259 return (vs_adm_usage(stdout
));
261 /* Check for the "-?" help switch */
262 for (i
= 1; i
< argc
; i
++) {
263 if (strcmp(argv
[i
], "-?") == 0)
264 return (vs_adm_usage(stdout
));
267 /* Locate the specified subcommand */
268 for (cp
= vs_adm_cmds
; cp
->vac_name
!= NULL
; cp
++) {
269 if (strcmp(cp
->vac_name
, vs_adm_subcmd
) == 0)
273 if (cp
->vac_name
== NULL
) {
274 (void) fprintf(stderr
, "%s: %s -- %s\n",
275 gettext("invalid subcommand"),
276 vs_adm_cmd
, vs_adm_subcmd
);
277 return (vs_adm_usage(stderr
));
280 /* invoke sub-command handler */
281 err
= cp
->vac_func(argc
, argv
);
283 return (err
== VS_ADM_EXIT_USAGE
? vs_adm_usage(stderr
) : err
);
291 vs_adm_usage(FILE *fp
)
293 const vs_adm_cmd_t
*cp
;
295 for (cp
= vs_adm_cmds
; cp
->vac_name
!= NULL
; cp
++) {
296 (void) fprintf(fp
, "%s %s", vs_adm_cmd
, cp
->vac_name
);
297 if (cp
->vac_helpid
!= NULL
)
298 (void) fprintf(fp
, " %s\n", cp
->vac_helpid
);
301 return (VS_ADM_EXIT_USAGE
);
308 * Gets and displays general vscan service configuration properties.
311 vs_adm_get(int argc
, char **argv
)
316 const vs_adm_property_t
*vap
;
318 (void) memset(&vp
, 0, sizeof (vp
));
321 propids
= VS_PROPID_GEN_ALL
;
324 for (i
= 2; i
< argc
; i
++) {
325 /* the "-p" specifier is optional */
326 if (strcmp(argv
[i
], "-p") == 0) {
328 return (VS_ADM_EXIT_USAGE
);
331 if ((vap
= vs_adm_prop_by_name(argv
[i
])) == NULL
) {
332 (void) fprintf(stderr
, "%s '%s'\n",
333 gettext("invalid property"), argv
[i
]);
334 return (VS_ADM_EXIT_ERROR
);
337 propids
|= vap
->vap_id
;
341 rc
= vs_props_get(&vp
, propids
);
342 if (rc
!= VS_ERR_NONE
) {
343 (void) fprintf(stderr
, "%s\n", vs_strerror(rc
));
344 return (VS_ADM_EXIT_ERROR
);
347 vs_adm_output_getcmd(propids
, &vp
);
349 return (VS_ADM_EXIT_SUCCESS
);
356 * Sets values for general vscan service configuration properties
358 * Calls a common function used by the set, add, and remove
359 * subcommands to modify general property values.
362 vs_adm_set(int argc
, char **argv
)
369 return (VS_ADM_EXIT_USAGE
);
371 rc
= vs_adm_props_from_input(argc
, argv
, &vp
, &propids
);
372 if (rc
!= VS_ADM_EXIT_SUCCESS
)
375 rc
= vs_props_set(&vp
, propids
);
376 if (rc
!= VS_ERR_NONE
) {
377 (void) fprintf(stderr
, "%s\n", vs_strerror(rc
));
378 return (VS_ADM_EXIT_ERROR
);
381 return (VS_ADM_EXIT_SUCCESS
);
388 * Gets and displays scan engine configuration properties for
389 * one or more scan engines.
392 vs_adm_get_engine(int argc
, char **argv
)
397 const vs_adm_property_t
*vap
;
401 for (i
= 2; i
< argc
; i
++) {
402 /* if not preceded by -p, must be engine id and must be last */
403 if (strcmp(argv
[i
], "-p") != 0) {
405 return (VS_ADM_EXIT_USAGE
);
408 if (strlen(engid
) > VS_SE_NAME_LEN
) {
409 (void) fprintf(stderr
, "%s\n",
410 gettext("invalid scan engine"));
411 return (VS_ADM_EXIT_ERROR
);
414 /* property should follow the -p */
416 return (VS_ADM_EXIT_USAGE
);
418 if ((vap
= vs_adm_prop_by_name(argv
[i
])) == NULL
) {
419 (void) fprintf(stderr
, "%s '%s'\n",
420 gettext("invalid property"), argv
[i
]);
421 return (VS_ADM_EXIT_ERROR
);
424 propids
|= vap
->vap_id
;
429 propids
= VS_PROPID_SE_ALL
;
431 /* get properties for specified engine */
433 rc
= vs_props_se_get(engid
, &va
.va_se
[0], propids
);
434 if (rc
!= VS_ERR_NONE
) {
435 (void) fprintf(stderr
, "%s\n", vs_strerror(rc
));
436 return (VS_ADM_EXIT_ERROR
);
438 vs_adm_output_getcmd(propids
, &va
.va_se
[0]);
439 return (VS_ADM_EXIT_SUCCESS
);
442 /* get properties for all engines */
443 if ((rc
= vs_props_get_all(&va
)) != VS_ERR_NONE
) {
444 (void) fprintf(stderr
, "%s\n", vs_strerror(rc
));
445 return (VS_ADM_EXIT_ERROR
);
448 for (i
= 0; i
< VS_SE_MAX
; i
++) {
449 if (*(va
.va_se
[i
].vep_engid
) == 0)
451 vs_adm_output_getcmd(propids
, &va
.va_se
[i
]);
454 (void) fprintf(stdout
, "%s\n",
455 gettext("no scan engines configured"));
458 return (VS_ADM_EXIT_SUCCESS
);
465 * Sets one or more scan engine configuration properties for a
466 * single scan engine.
469 vs_adm_set_engine(int argc
, char **argv
)
471 const vs_adm_property_t
*vap
;
477 int add
= (strcmp(vs_adm_subcmd
, "add-engine") == 0) ? 1 : 0;
480 if ((argc
< 3) || ((!add
) && (argc
< 4)))
481 return (VS_ADM_EXIT_USAGE
);
483 /* Get the engine id */
484 engid
= argv
[argc
- 1];
485 if (strchr(engid
, '=') || strcmp(argv
[argc
- 2], "-p") == 0) {
486 return (VS_ADM_EXIT_USAGE
);
489 if (strlen(engid
) > VS_SE_NAME_LEN
) {
490 (void) fprintf(stderr
, "%s\n",
491 gettext("invalid scan engine"));
492 return (VS_ADM_EXIT_ERROR
);
497 for (i
= 2; i
< (argc
- 1); i
++) {
498 /* The "-p" is optional */
499 if (strcmp(argv
[i
], "-p") == 0) {
501 return (VS_ADM_EXIT_USAGE
);
504 if ((val
= strchr(argv
[i
], '=')) == NULL
)
505 return (VS_ADM_EXIT_USAGE
);
510 /* Find the SE property pointer from the SE property name */
511 if ((vap
= vs_adm_prop_by_name(argv
[i
])) == NULL
) {
512 (void) fprintf(stderr
, "%s '%s'\n",
513 gettext("invalid property"), argv
[i
]);
514 return (VS_ADM_EXIT_ERROR
);
517 propids
|= vap
->vap_id
;
519 if ((vs_adm_parse(vap
, val
, &sep
)) != 0) {
520 (void) fprintf(stderr
, "%s '%s'\n",
521 gettext("invalid property value"), val
);
522 return (VS_ADM_EXIT_ERROR
);
527 rc
= vs_props_se_create(engid
, &sep
, propids
);
529 rc
= vs_props_se_set(engid
, &sep
, propids
);
531 if (rc
!= VS_ERR_NONE
) {
532 (void) fprintf(stderr
, "%s\n", vs_strerror(rc
));
533 return (VS_ADM_EXIT_ERROR
);
536 return (VS_ADM_EXIT_SUCCESS
);
545 vs_adm_rem_engine(int argc
, char **argv
)
551 return (VS_ADM_EXIT_USAGE
);
555 if (strlen(engid
) > VS_SE_NAME_LEN
) {
556 (void) fprintf(stderr
, "%s\n",
557 gettext("invalid scan engine"));
558 return (VS_ADM_EXIT_ERROR
);
561 if ((rc
= vs_props_se_delete(engid
)) != VS_ERR_NONE
) {
562 (void) fprintf(stderr
, "%s\n", vs_strerror(rc
));
566 return (VS_ADM_EXIT_SUCCESS
);
574 vs_adm_import(int argc
, char **argv
)
581 if ((rc
= vs_adm_file_usage(argc
, argv
)) != VS_ADM_EXIT_SUCCESS
)
584 filename
= argv
[argc
- 1];
585 rc
= vs_adm_file_read(filename
, vp
.vp_types
, sizeof (vp
.vp_types
));
586 if (rc
!= VS_ADM_EXIT_SUCCESS
)
589 propids
= VS_PROPID_TYPES
;
590 rc
= vs_props_set(&vp
, propids
);
591 if (rc
!= VS_ERR_NONE
) {
592 (void) fprintf(stderr
, "%s\n", vs_strerror(rc
));
593 return (VS_ADM_EXIT_ERROR
);
596 return (VS_ADM_EXIT_SUCCESS
);
604 vs_adm_validate(int argc
, char **argv
)
610 if ((rc
= vs_adm_file_usage(argc
, argv
)) != VS_ADM_EXIT_SUCCESS
)
613 filename
= argv
[argc
- 1];
614 rc
= vs_adm_file_read(filename
, vp
.vp_types
, sizeof (vp
.vp_types
));
615 if (rc
!= VS_ADM_EXIT_SUCCESS
)
618 if (vs_props_validate(&vp
, VS_PROPID_TYPES
) != VS_ERR_NONE
) {
619 (void) fprintf(stderr
, "%s: %s\n", filename
, vs_strerror(rc
));
620 return (VS_ADM_EXIT_ERROR
);
623 (void) fprintf(stdout
, "%s: valid\n", filename
);
624 return (VS_ADM_EXIT_SUCCESS
);
632 vs_adm_export(int argc
, char **argv
)
639 if ((rc
= vs_adm_file_usage(argc
, argv
)) != VS_ADM_EXIT_SUCCESS
)
642 filename
= argv
[argc
- 1];
643 (void) memset(&vp
, 0, sizeof (vs_props_t
));
644 propids
= VS_PROPID_TYPES
;
645 if ((rc
= vs_props_get(&vp
, propids
)) != VS_ERR_NONE
) {
646 (void) fprintf(stderr
, "%s: %s\n", filename
, vs_strerror(rc
));
647 return (VS_ADM_EXIT_ERROR
);
650 rc
= vs_adm_file_write(filename
, vp
.vp_types
);
651 if (rc
!= VS_ADM_EXIT_SUCCESS
)
654 return (VS_ADM_EXIT_SUCCESS
);
661 * import, export and validate - VS_PROPID_TYPES only
664 vs_adm_file_usage(int argc
, char **argv
)
666 const vs_adm_property_t
*vap
;
670 return (VS_ADM_EXIT_USAGE
);
673 if (strcmp(argv
[2], "-p") == 0) {
675 return (VS_ADM_EXIT_USAGE
);
676 } else if (argc
!= 4)
677 return (VS_ADM_EXIT_USAGE
);
679 /* only VS_PROPID_TYPES supported */
680 prop
= argv
[argc
- 2];
681 vap
= vs_adm_prop_by_name(prop
);
682 if ((vap
== NULL
) || (vap
->vap_id
!= VS_PROPID_TYPES
)) {
683 (void) fprintf(stderr
, "%s '%s'\n",
684 gettext("invalid property"), prop
);
685 return (VS_ADM_EXIT_USAGE
);
688 return (VS_ADM_EXIT_SUCCESS
);
696 vs_adm_file_read(char *filename
, char *buf
, int len
)
700 if ((fp
= fopen(filename
, "r")) == NULL
) {
701 (void) fprintf(stderr
, "%s: %s\n", filename
,
702 vs_strerror(VS_ERR_SYS
));
703 return (VS_ADM_EXIT_ERROR
);
706 (void) memset(buf
, 0, len
);
707 if (fgets(buf
, len
, fp
) == NULL
) {
708 (void) fprintf(stderr
, "%s: %s\n", filename
,
709 gettext("invalid property value"));
711 return (VS_ADM_EXIT_ERROR
);
717 if (buf
[strlen(buf
) - 1] == '\n')
718 buf
[strlen(buf
) - 1] = '\0';
720 return (VS_ADM_EXIT_SUCCESS
);
728 vs_adm_file_write(char *filename
, char *buf
)
733 if ((fp
= fopen(filename
, "w")) == NULL
) {
734 (void) fprintf(stderr
, "%s: %s\n", filename
,
735 vs_strerror(VS_ERR_SYS
));
736 return (VS_ADM_EXIT_ERROR
);
739 bytes
= fprintf(fp
, "%s\n", buf
);
740 if ((bytes
< 0) || (bytes
!= strlen(buf
) + 1)) {
741 (void) fprintf(stderr
, "%s: %s\n", filename
,
742 vs_strerror(VS_ERR_SYS
));
744 return (VS_ADM_EXIT_ERROR
);
748 return (VS_ADM_EXIT_SUCCESS
);
755 * Gets and displays all general properties and all scan engine
760 vs_adm_show(int argc
, char **argv
)
763 return (VS_ADM_EXIT_USAGE
);
765 (void) vs_adm_get(argc
, argv
);
766 (void) vs_adm_get_engine(argc
, argv
);
768 return (VS_ADM_EXIT_SUCCESS
);
775 * Gets and displays vscan service statistics.
779 vs_adm_stats(int argc
, char **argv
)
786 if ((rc
= vs_statistics(&stats
)) == VS_ERR_NONE
) {
787 vs_adm_output_stats(&stats
);
788 return (VS_ADM_EXIT_SUCCESS
);
790 (void) fprintf(stdout
, "%s\n", vs_strerror(rc
));
791 return (VS_ADM_EXIT_ERROR
);
795 /* reset statistics */
796 if (argc
== 3 && strcmp(argv
[2], "-z") == 0) {
797 if ((rc
= vs_statistics_reset()) == VS_ERR_NONE
) {
798 return (VS_ADM_EXIT_SUCCESS
);
800 (void) fprintf(stdout
, "%s\n", vs_strerror(rc
));
801 return (VS_ADM_EXIT_ERROR
);
806 return (vs_adm_usage(stdout
));
811 * vs_adm_output_stats
814 vs_adm_output_stats(vs_stats_t
*stats
)
822 (void) fprintf(stdout
, "scanned=%lld\n", stats
->vss_scanned
);
823 (void) fprintf(stdout
, "infected=%lld\n", stats
->vss_infected
);
824 if (stats
->vss_cleaned
> 0)
825 (void) printf("cleaned=%lld\n", stats
->vss_cleaned
);
826 (void) fprintf(stdout
, "failed=%lld\n", stats
->vss_failed
);
828 for (i
= 0; i
< VS_SE_MAX
; i
++) {
829 engid
= stats
->vss_eng
[i
].vss_engid
;
832 (void) fprintf(stdout
, "%s:errors=%lld\n", engid
,
833 stats
->vss_eng
[i
].vss_errors
);
839 * vs_adm_props_from_input
842 vs_adm_props_from_input(int argc
, char **argv
, vs_props_t
*vsprops
,
845 const vs_adm_property_t
*vap
;
849 (void) memset(vsprops
, 0, sizeof (vs_props_t
));
852 for (i
= 2; i
< argc
; i
++) {
853 /* The "-p" is optional */
854 if (strcmp(argv
[i
], "-p") == 0) {
856 return (VS_ADM_EXIT_USAGE
);
859 if ((val
= strchr(argv
[i
], '=')) == NULL
)
860 return (VS_ADM_EXIT_USAGE
);
862 /* Find the vscanadm property pointer from the property name */
865 if ((vap
= vs_adm_prop_by_name(argv
[i
])) == NULL
) {
866 (void) fprintf(stderr
, "%s '%s'\n",
867 gettext("invalid property"), argv
[i
]);
868 return (VS_ADM_EXIT_ERROR
);
871 /* Add in the property id and parse the property value */
872 *propids
|= vap
->vap_id
;
873 if ((vs_adm_parse(vap
, val
, vsprops
)) != 0) {
874 (void) fprintf(stderr
, "%s '%s'\n",
875 gettext("invalid property value"), val
);
876 return (VS_ADM_EXIT_ERROR
);
880 return (VS_ADM_EXIT_SUCCESS
);
885 * vs_adm_output_getcmd
887 * Prints the results of a get command; both the get for general
888 * configuration properties as well as the get for an engine
893 vs_adm_output_getcmd(uint64_t propids
, const void *props
)
895 char value
[VS_ADM_PRINT_BUF_LEN
];
897 const vs_adm_property_t
*vap
;
900 if (VS_PROPID_IS_SE(propids
))
901 label
= ((vs_props_se_t
*)props
)->vep_engid
;
904 * Unparse values from the property structure into readable strings
907 for (propid
= 1LL; propid
<= VS_PROPID_MAX
; propid
<<= 1) {
908 if ((propids
& propid
) == 0)
911 if ((vap
= vs_adm_prop_by_id(propid
)) == NULL
)
915 vs_adm_unparse(vap
, props
, value
, sizeof (value
));
918 (void) fprintf(stdout
, "%s:", label
);
919 (void) fprintf(stdout
, "%s=%s\n", vap
->vap_name
, value
);
922 (void) fprintf(stdout
, "\n");
927 * vs_adm_prop_by_name
929 * Finds and returns a pointer to a vscan property structure from the
930 * property table by property name.
932 static const vs_adm_property_t
*
933 vs_adm_prop_by_name(const char *propname
)
935 const vs_adm_property_t
*p
;
937 for (p
= vs_adm_props_all
; p
->vap_name
!= NULL
; p
++) {
938 if (strcmp(propname
, p
->vap_name
) == 0)
949 * Finds and returns a pointer to a vscan property structure from the
950 * property table by property name.
952 static const vs_adm_property_t
*
953 vs_adm_prop_by_id(const uint64_t propid
)
955 const vs_adm_property_t
*p
;
957 for (p
= vs_adm_props_all
; p
->vap_id
!= 0; p
++) {
958 if (propid
== p
->vap_id
)
969 * Entry point for parsing the user input strings into a data structure
970 * used for setting values. Dispatches the actual parsing to the parse
971 * routine for the specified vscanadm property.
973 * This function is used to dispatch parsing for values supplied by the
974 * user for all subcommands; both the general configuration as well as
975 * scan engine configuration. The structure pointer is therefore typed
976 * as a void pointer, and cast appropriately in the parse routine for
977 * the vscanadm property.
980 vs_adm_parse(const vs_adm_property_t
*vap
, const char *valvap_name
,
983 return ((vap
->vap_parse
)(valvap_name
, vp
));
988 * vs_adm_parse_maxsize
990 * Parses a user-supplied string into a maxsize (decimal) value for
991 * the general vscan configuration properties.
994 vs_adm_parse_maxsize(const char *valstr
, void *vp
)
996 vs_props_t
*svcp
= vp
;
1002 maxsize
= strtoll(valstr
, &end
, 10);
1005 (void) snprintf(svcp
->vp_maxsize
, sizeof (svcp
->vp_maxsize
),
1006 "%llu%s", maxsize
, end
);
1013 * vs_adm_parse_maxsize_action
1015 * Parses a user-supplied string into a maxsize action value for the
1016 * general vscan configuration properties.
1018 * Returns: 0 success
1022 vs_adm_parse_maxsize_action(const char *valstr
, void *vp
)
1024 vs_props_t
*svcp
= vp
;
1026 if (strcmp(valstr
, VS_ADM_ALLOW
) == 0) {
1027 svcp
->vp_maxsize_action
= B_TRUE
;
1031 if (strcmp(valstr
, VS_ADM_DENY
) == 0) {
1032 svcp
->vp_maxsize_action
= B_FALSE
;
1041 * vs_adm_parse_types
1043 * Returns: 0 success
1047 vs_adm_parse_types(const char *valstr
, void *vp
)
1049 vs_props_t
*svcp
= vp
;
1051 if (strlen(valstr
) >= sizeof (svcp
->vp_types
))
1054 if (strlcpy(svcp
->vp_types
, valstr
, sizeof (svcp
->vp_types
))
1055 >= sizeof (svcp
->vp_types
))
1063 * vs_adm_parse_enable
1065 * Parses a user-supplied string into an enable value for the
1066 * properties of a scan engine.
1068 * Returns: 0 success
1072 vs_adm_parse_enable(const char *valstr
, void *vp
)
1074 vs_props_se_t
*sep
= vp
;
1076 if (strcmp(valstr
, VS_ADM_ON
) == 0) {
1077 sep
->vep_enable
= B_TRUE
;
1081 if (strcmp(valstr
, VS_ADM_OFF
) == 0) {
1082 sep
->vep_enable
= B_FALSE
;
1093 * Parses a user-supplied string into an ip address value for the
1094 * properties of a scan engine.
1097 vs_adm_parse_host(const char *valstr
, void *vp
)
1099 vs_props_se_t
*sep
= vp
;
1101 if (strlen(valstr
) >= sizeof (sep
->vep_host
))
1104 if (strlcpy(sep
->vep_host
, valstr
, sizeof (sep
->vep_host
)) >=
1105 sizeof (sep
->vep_host
))
1115 * Parses a user-supplied string into a port value for the properties of
1116 * a scan engine. The port is an unsigned short int, but the conversion
1117 * must be done on a word-sized int. Casting the converted int into the
1118 * port member of the property structure can result in a valid but
1119 * unintended value, so the range is checked first for validity.
1121 * Returns: 0 success
1125 vs_adm_parse_port(const char *valstr
, void *vp
)
1127 vs_props_se_t
*sep
= vp
;
1132 port
= strtoul(valstr
, &end
, 0);
1133 if (port
> UINT16_MAX
|| (end
< (valstr
+ strlen(valstr
))))
1136 sep
->vep_port
= port
;
1143 * vs_adm_parse_maxconn
1145 * Parses a user-supplied string into a max connections (decimal) value
1146 * for the properties of a scan engine.
1148 * Returns: 0 success
1152 vs_adm_parse_maxconn(const char *valstr
, void *vp
)
1154 vs_props_se_t
*sep
= vp
;
1157 sep
->vep_maxconn
= strtoll(valstr
, &end
, 10);
1158 if (end
< valstr
+ strlen(valstr
))
1168 * Entry point for unparsing native data into a readable string
1169 * used for display to the user. Dispatches the actual unparsing to
1170 * the unparse routine for the specified vscanadm property.
1172 * This function is used to dispatch unparsing for all subcommands.
1173 * The structure pointer is therefore typed as a void pointer, and
1174 * cast appropriately in the unparse routine for the vscanadm property.
1177 vs_adm_unparse(const vs_adm_property_t
*vap
, const void *vp
,
1178 char *buf
, size_t len
)
1180 if ((vap
->vap_unparse
)(vp
, buf
, len
) != 0)
1181 (void) snprintf(buf
, len
, gettext(" (error) "));
1186 * vs_adm_unparse_maxsize
1188 * Unparses a max fsize value in native data form into a
1189 * user-readable string.
1193 vs_adm_unparse_maxsize(const void *vp
, char *buf
, size_t len
)
1195 const vs_props_t
*svcp
= vp
;
1197 (void) snprintf(buf
, len
, "%s", svcp
->vp_maxsize
);
1204 * vs_adm_unparse_maxsize_action
1206 * Unparses a max fsize action value in native data form into a
1207 * user-readable string.
1211 vs_adm_unparse_maxsize_action(const void *vp
, char *buf
, size_t len
)
1213 const vs_props_t
*svcp
= vp
;
1215 (void) snprintf(buf
, len
, "%s",
1216 svcp
->vp_maxsize_action
? VS_ADM_ALLOW
: VS_ADM_DENY
);
1223 * vs_adm_unparse_types
1225 * Returns: 0 success
1229 vs_adm_unparse_types(const void *vp
, char *buf
, size_t len
)
1231 const vs_props_t
*svcp
= vp
;
1233 (void) strlcpy(buf
, svcp
->vp_types
, len
);
1240 * vs_adm_unparse_enable
1242 * Unparses the enable value for a scan engine in native data
1243 * form into a user-readable string.
1247 vs_adm_unparse_enable(const void *vp
, char *buf
, size_t len
)
1249 const vs_props_se_t
*sep
= vp
;
1251 (void) snprintf(buf
, len
, "%s",
1252 sep
->vep_enable
? VS_ADM_ON
: VS_ADM_OFF
);
1259 * vs_adm_unparse_host
1261 * Unparses an ip address for a scan engine in native data
1262 * form into a user-readable string.
1264 * Returns: 0 success
1269 vs_adm_unparse_host(const void *vp
, char *buf
, size_t len
)
1271 const vs_props_se_t
*sep
= vp
;
1273 (void) strlcpy(buf
, sep
->vep_host
, len
);
1280 * vs_adm_unparse_port
1282 * Unparses a port value for a scan engine in native data
1283 * form into a user-readable string.
1287 vs_adm_unparse_port(const void *vp
, char *buf
, size_t len
)
1289 const vs_props_se_t
*sep
= vp
;
1291 (void) snprintf(buf
, len
, "%hu", sep
->vep_port
);
1298 * vs_adm_unparse_maxconn
1300 * Unparses a max connecctions for a scan engine in native data
1301 * form into a user-readable string.
1306 vs_adm_unparse_maxconn(const void *vp
, char *buf
, size_t len
)
1308 const vs_props_se_t
*sep
= vp
;
1310 (void) snprintf(buf
, len
, "%lld", sep
->vep_maxconn
);