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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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