#include <stdio.h>
#include <strings.h>
#include <limits.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <libintl.h>
#include <locale.h>
#include <libvscan.h>
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
#define VS_ADM_MAXSIZE "max-size"
#define VS_ADM_MAXSIZE_ACTION "max-size-action"
#define VS_ADM_TYPES "types"
#define VS_ADM_SE_ENABLE "enable"
#define VS_ADM_SE_HOST "host"
#define VS_ADM_SE_PORT "port"
#define VS_ADM_SE_MAXCONN "max-connection"
#define VS_ADM_ON "on"
#define VS_ADM_OFF "off"
#define VS_ADM_ALLOW "allow"
#define VS_ADM_DENY "deny"
#define VS_ADM_PRINT_BUF_LEN 4096
#define VS_ADM_EXIT_SUCCESS 0
#define VS_ADM_EXIT_ERROR 1
#define VS_ADM_EXIT_USAGE 2
typedef struct vs_adm_property {
const char *vap_name;
uint64_t vap_id;
int (*vap_parse)(const char *, void *);
int (*vap_unparse)(const void *, char *, size_t);
} vs_adm_property_t;
#define VS_ADM_HELP_GET ("[-p property]...\n" \
"\tdisplay vscan properties")
#define VS_ADM_HELP_SET ("-p property=value [-p property=value]...\n" \
"\tset values of vscan properties")
#define VS_ADM_HELP_GET_ENG ("[-p property] [engine_id]\n" \
"\tdisplay values of scan engine properties")
#define VS_ADM_HELP_ADD_ENG ("[-p property=value]... engine_id\n" \
"\tadd scan engine")
#define VS_ADM_HELP_SET_ENG ("-p property=value [-p property=value]" \
"... engine_id\n\tset values of scan engine properties")
#define VS_ADM_HELP_REM_ENG ("engine_id\n" \
"\tremove scan engine")
#define VS_ADM_HELP_SHOW ("\n\tdisplay the values of all vscan " \
"service and scan engine properties")
#define VS_ADM_HELP_STATS ("[-z]\n\tdisplay vscan service statistics")
#define VS_ADM_HELP_IMPORT ("-p property filename\n" \
"\timport property from file")
#define VS_ADM_HELP_EXPORT ("-p property filename\n" \
"\texport property to file")
#define VS_ADM_HELP_VALIDATE ("-p property filename\n" \
"\tvalidate property in file")
typedef struct vs_adm_cmd {
int (*vac_func)(int, char *[]);
const char *vac_name;
char *vac_helpid;
}
vs_adm_cmd_t;
static int vs_adm_set(int, char **);
static int vs_adm_get(int, char **);
static int vs_adm_set_engine(int, char **);
static int vs_adm_get_engine(int, char **);
static int vs_adm_rem_engine(int, char **);
static int vs_adm_show(int, char **);
static int vs_adm_stats(int, char **);
static int vs_adm_import(int, char **);
static int vs_adm_export(int, char **);
static int vs_adm_validate(int, char **);
static int vs_adm_parse_maxsize(const char *, void *);
static int vs_adm_parse_maxsize_action(const char *, void *);
static int vs_adm_parse_types(const char *, void *);
static int vs_adm_parse_enable(const char *, void *);
static int vs_adm_parse_host(const char *, void *);
static int vs_adm_parse_port(const char *, void *);
static int vs_adm_parse_maxconn(const char *, void *);
static int vs_adm_unparse_maxsize(const void *, char *, size_t);
static int vs_adm_unparse_maxsize_action(const void *, char *, size_t);
static int vs_adm_unparse_types(const void *, char *, size_t);
static int vs_adm_unparse_enable(const void *, char *, size_t);
static int vs_adm_unparse_host(const void *, char *, size_t);
static int vs_adm_unparse_port(const void *, char *, size_t);
static int vs_adm_unparse_maxconn(const void *, char *, size_t);
static const vs_adm_property_t vs_adm_props_all[] = {
{ VS_ADM_MAXSIZE, VS_PROPID_MAXSIZE,
vs_adm_parse_maxsize, vs_adm_unparse_maxsize },
{ VS_ADM_MAXSIZE_ACTION, VS_PROPID_MAXSIZE_ACTION,
vs_adm_parse_maxsize_action, vs_adm_unparse_maxsize_action },
{ VS_ADM_TYPES, VS_PROPID_TYPES,
vs_adm_parse_types, vs_adm_unparse_types },
{ VS_ADM_SE_ENABLE, VS_PROPID_SE_ENABLE,
vs_adm_parse_enable, vs_adm_unparse_enable },
{ VS_ADM_SE_HOST, VS_PROPID_SE_HOST,
vs_adm_parse_host, vs_adm_unparse_host },
{ VS_ADM_SE_PORT, VS_PROPID_SE_PORT,
vs_adm_parse_port, vs_adm_unparse_port },
{ VS_ADM_SE_MAXCONN, VS_PROPID_SE_MAXCONN,
vs_adm_parse_maxconn, vs_adm_unparse_maxconn },
{ NULL, 0, NULL, NULL }
};
static const vs_adm_cmd_t vs_adm_cmds[] =
{
{ vs_adm_get, "get", VS_ADM_HELP_GET },
{ vs_adm_set, "set", VS_ADM_HELP_SET },
{ vs_adm_get_engine, "get-engine", VS_ADM_HELP_GET_ENG },
{ vs_adm_set_engine, "set-engine", VS_ADM_HELP_SET_ENG },
{ vs_adm_set_engine, "add-engine", VS_ADM_HELP_ADD_ENG },
{ vs_adm_rem_engine, "remove-engine", VS_ADM_HELP_REM_ENG },
{ vs_adm_import, "import", VS_ADM_HELP_IMPORT },
{ vs_adm_export, "export", VS_ADM_HELP_EXPORT },
{ vs_adm_validate, "validate", VS_ADM_HELP_VALIDATE },
{ vs_adm_show, "show", VS_ADM_HELP_SHOW },
{ vs_adm_stats, "stats", VS_ADM_HELP_STATS },
{ NULL, NULL, NULL }
};
static const char *vs_adm_cmd;
static const char *vs_adm_subcmd;
static int vs_adm_usage(FILE *);
static int vs_adm_props_from_input(int, char **, vs_props_t *, uint64_t *);
static void vs_adm_output_getcmd(uint64_t, const void *);
static void vs_adm_output_stats(vs_stats_t *);
static const vs_adm_property_t *vs_adm_prop_by_name(const char *);
static const vs_adm_property_t *vs_adm_prop_by_id(const uint64_t);
static int vs_adm_parse(const vs_adm_property_t *, const char *, void *);
static void vs_adm_unparse(const vs_adm_property_t *, const void *,
char *, size_t);
static int vs_adm_file_read(char *, char *, int);
static int vs_adm_file_write(char *, char *);
static int vs_adm_file_usage(int argc, char **argv);
int
main(int argc, char **argv)
{
const vs_adm_cmd_t *cp;
const char *p;
int i, err;
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
if ((p = strrchr(argv[0], '/')) == NULL)
vs_adm_cmd = argv[0];
else
vs_adm_cmd = p + 1;
vs_adm_subcmd = argv[1];
if (argc < 2)
return (vs_adm_usage(stdout));
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-?") == 0)
return (vs_adm_usage(stdout));
}
for (cp = vs_adm_cmds; cp->vac_name != NULL; cp++) {
if (strcmp(cp->vac_name, vs_adm_subcmd) == 0)
break;
}
if (cp->vac_name == NULL) {
(void) fprintf(stderr, "%s: %s -- %s\n",
gettext("invalid subcommand"),
vs_adm_cmd, vs_adm_subcmd);
return (vs_adm_usage(stderr));
}
err = cp->vac_func(argc, argv);
return (err == VS_ADM_EXIT_USAGE ? vs_adm_usage(stderr) : err);
}
static int
vs_adm_usage(FILE *fp)
{
const vs_adm_cmd_t *cp;
for (cp = vs_adm_cmds; cp->vac_name != NULL; cp++) {
(void) fprintf(fp, "%s %s", vs_adm_cmd, cp->vac_name);
if (cp->vac_helpid != NULL)
(void) fprintf(fp, " %s\n", cp->vac_helpid);
}
return (VS_ADM_EXIT_USAGE);
}
static int
vs_adm_get(int argc, char **argv)
{
uint64_t propids;
int i, rc;
vs_props_t vp;
const vs_adm_property_t *vap;
(void) memset(&vp, 0, sizeof (vp));
if (argc <= 2) {
propids = VS_PROPID_GEN_ALL;
} else {
propids = 0LL;
for (i = 2; i < argc; i++) {
if (strcmp(argv[i], "-p") == 0) {
if (++i >= argc)
return (VS_ADM_EXIT_USAGE);
}
if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
(void) fprintf(stderr, "%s '%s'\n",
gettext("invalid property"), argv[i]);
return (VS_ADM_EXIT_ERROR);
}
propids |= vap->vap_id;
}
}
rc = vs_props_get(&vp, propids);
if (rc != VS_ERR_NONE) {
(void) fprintf(stderr, "%s\n", vs_strerror(rc));
return (VS_ADM_EXIT_ERROR);
}
vs_adm_output_getcmd(propids, &vp);
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_set(int argc, char **argv)
{
vs_props_t vp;
uint64_t propids;
int rc;
if (argc < 3)
return (VS_ADM_EXIT_USAGE);
rc = vs_adm_props_from_input(argc, argv, &vp, &propids);
if (rc != VS_ADM_EXIT_SUCCESS)
return (rc);
rc = vs_props_set(&vp, propids);
if (rc != VS_ERR_NONE) {
(void) fprintf(stderr, "%s\n", vs_strerror(rc));
return (VS_ADM_EXIT_ERROR);
}
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_get_engine(int argc, char **argv)
{
int i, rc;
uint64_t propids;
char *engid = NULL;
const vs_adm_property_t *vap;
vs_props_all_t va;
propids = 0LL;
for (i = 2; i < argc; i++) {
if (strcmp(argv[i], "-p") != 0) {
if (i != (argc - 1))
return (VS_ADM_EXIT_USAGE);
engid = argv[i];
if (strlen(engid) > VS_SE_NAME_LEN) {
(void) fprintf(stderr, "%s\n",
gettext("invalid scan engine"));
return (VS_ADM_EXIT_ERROR);
}
} else {
if (++i >= argc)
return (VS_ADM_EXIT_USAGE);
if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
(void) fprintf(stderr, "%s '%s'\n",
gettext("invalid property"), argv[i]);
return (VS_ADM_EXIT_ERROR);
}
propids |= vap->vap_id;
}
}
if (propids == 0LL)
propids = VS_PROPID_SE_ALL;
if (engid) {
rc = vs_props_se_get(engid, &va.va_se[0], propids);
if (rc != VS_ERR_NONE) {
(void) fprintf(stderr, "%s\n", vs_strerror(rc));
return (VS_ADM_EXIT_ERROR);
}
vs_adm_output_getcmd(propids, &va.va_se[0]);
return (VS_ADM_EXIT_SUCCESS);
}
if ((rc = vs_props_get_all(&va)) != VS_ERR_NONE) {
(void) fprintf(stderr, "%s\n", vs_strerror(rc));
return (VS_ADM_EXIT_ERROR);
}
for (i = 0; i < VS_SE_MAX; i++) {
if (*(va.va_se[i].vep_engid) == 0)
break;
vs_adm_output_getcmd(propids, &va.va_se[i]);
}
if (i == 0) {
(void) fprintf(stdout, "%s\n",
gettext("no scan engines configured"));
}
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_set_engine(int argc, char **argv)
{
const vs_adm_property_t *vap;
vs_props_se_t sep;
char *val;
uint64_t propids;
int i, rc;
char *engid;
int add = (strcmp(vs_adm_subcmd, "add-engine") == 0) ? 1 : 0;
if ((argc < 3) || ((!add) && (argc < 4)))
return (VS_ADM_EXIT_USAGE);
engid = argv[argc - 1];
if (strchr(engid, '=') || strcmp(argv[argc - 2], "-p") == 0) {
return (VS_ADM_EXIT_USAGE);
}
if (strlen(engid) > VS_SE_NAME_LEN) {
(void) fprintf(stderr, "%s\n",
gettext("invalid scan engine"));
return (VS_ADM_EXIT_ERROR);
}
propids = 0LL;
for (i = 2; i < (argc - 1); i++) {
if (strcmp(argv[i], "-p") == 0) {
if (++i >= argc)
return (VS_ADM_EXIT_USAGE);
}
if ((val = strchr(argv[i], '=')) == NULL)
return (VS_ADM_EXIT_USAGE);
*val = 0;
val++;
if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
(void) fprintf(stderr, "%s '%s'\n",
gettext("invalid property"), argv[i]);
return (VS_ADM_EXIT_ERROR);
}
propids |= vap->vap_id;
if ((vs_adm_parse(vap, val, &sep)) != 0) {
(void) fprintf(stderr, "%s '%s'\n",
gettext("invalid property value"), val);
return (VS_ADM_EXIT_ERROR);
}
}
if (add)
rc = vs_props_se_create(engid, &sep, propids);
else
rc = vs_props_se_set(engid, &sep, propids);
if (rc != VS_ERR_NONE) {
(void) fprintf(stderr, "%s\n", vs_strerror(rc));
return (VS_ADM_EXIT_ERROR);
}
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_rem_engine(int argc, char **argv)
{
int rc;
char *engid;
if (argc != 3)
return (VS_ADM_EXIT_USAGE);
engid = argv[2];
if (strlen(engid) > VS_SE_NAME_LEN) {
(void) fprintf(stderr, "%s\n",
gettext("invalid scan engine"));
return (VS_ADM_EXIT_ERROR);
}
if ((rc = vs_props_se_delete(engid)) != VS_ERR_NONE) {
(void) fprintf(stderr, "%s\n", vs_strerror(rc));
return (rc);
}
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_import(int argc, char **argv)
{
int rc;
vs_props_t vp;
uint64_t propids;
char *filename;
if ((rc = vs_adm_file_usage(argc, argv)) != VS_ADM_EXIT_SUCCESS)
return (rc);
filename = argv[argc - 1];
rc = vs_adm_file_read(filename, vp.vp_types, sizeof (vp.vp_types));
if (rc != VS_ADM_EXIT_SUCCESS)
return (rc);
propids = VS_PROPID_TYPES;
rc = vs_props_set(&vp, propids);
if (rc != VS_ERR_NONE) {
(void) fprintf(stderr, "%s\n", vs_strerror(rc));
return (VS_ADM_EXIT_ERROR);
}
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_validate(int argc, char **argv)
{
int rc;
vs_props_t vp;
char *filename;
if ((rc = vs_adm_file_usage(argc, argv)) != VS_ADM_EXIT_SUCCESS)
return (rc);
filename = argv[argc - 1];
rc = vs_adm_file_read(filename, vp.vp_types, sizeof (vp.vp_types));
if (rc != VS_ADM_EXIT_SUCCESS)
return (rc);
if (vs_props_validate(&vp, VS_PROPID_TYPES) != VS_ERR_NONE) {
(void) fprintf(stderr, "%s: %s\n", filename, vs_strerror(rc));
return (VS_ADM_EXIT_ERROR);
}
(void) fprintf(stdout, "%s: valid\n", filename);
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_export(int argc, char **argv)
{
int rc;
vs_props_t vp;
uint64_t propids;
char *filename;
if ((rc = vs_adm_file_usage(argc, argv)) != VS_ADM_EXIT_SUCCESS)
return (rc);
filename = argv[argc - 1];
(void) memset(&vp, 0, sizeof (vs_props_t));
propids = VS_PROPID_TYPES;
if ((rc = vs_props_get(&vp, propids)) != VS_ERR_NONE) {
(void) fprintf(stderr, "%s: %s\n", filename, vs_strerror(rc));
return (VS_ADM_EXIT_ERROR);
}
rc = vs_adm_file_write(filename, vp.vp_types);
if (rc != VS_ADM_EXIT_SUCCESS)
return (rc);
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_file_usage(int argc, char **argv)
{
const vs_adm_property_t *vap;
char *prop;
if (argc < 4)
return (VS_ADM_EXIT_USAGE);
if (strcmp(argv[2], "-p") == 0) {
if (argc != 5)
return (VS_ADM_EXIT_USAGE);
} else if (argc != 4)
return (VS_ADM_EXIT_USAGE);
prop = argv[argc - 2];
vap = vs_adm_prop_by_name(prop);
if ((vap == NULL) || (vap->vap_id != VS_PROPID_TYPES)) {
(void) fprintf(stderr, "%s '%s'\n",
gettext("invalid property"), prop);
return (VS_ADM_EXIT_USAGE);
}
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_file_read(char *filename, char *buf, int len)
{
FILE *fp;
if ((fp = fopen(filename, "r")) == NULL) {
(void) fprintf(stderr, "%s: %s\n", filename,
vs_strerror(VS_ERR_SYS));
return (VS_ADM_EXIT_ERROR);
}
(void) memset(buf, 0, len);
if (fgets(buf, len, fp) == NULL) {
(void) fprintf(stderr, "%s: %s\n", filename,
gettext("invalid property value"));
(void) fclose(fp);
return (VS_ADM_EXIT_ERROR);
}
(void) fclose(fp);
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_file_write(char *filename, char *buf)
{
FILE *fp;
int bytes;
if ((fp = fopen(filename, "w")) == NULL) {
(void) fprintf(stderr, "%s: %s\n", filename,
vs_strerror(VS_ERR_SYS));
return (VS_ADM_EXIT_ERROR);
}
bytes = fprintf(fp, "%s\n", buf);
if ((bytes < 0) || (bytes != strlen(buf) + 1)) {
(void) fprintf(stderr, "%s: %s\n", filename,
vs_strerror(VS_ERR_SYS));
(void) fclose(fp);
return (VS_ADM_EXIT_ERROR);
}
(void) fclose(fp);
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_show(int argc, char **argv)
{
if (argc > 2)
return (VS_ADM_EXIT_USAGE);
(void) vs_adm_get(argc, argv);
(void) vs_adm_get_engine(argc, argv);
return (VS_ADM_EXIT_SUCCESS);
}
static int
vs_adm_stats(int argc, char **argv)
{
int rc;
vs_stats_t stats;
if (argc == 2) {
if ((rc = vs_statistics(&stats)) == VS_ERR_NONE) {
vs_adm_output_stats(&stats);
return (VS_ADM_EXIT_SUCCESS);
} else {
(void) fprintf(stdout, "%s\n", vs_strerror(rc));
return (VS_ADM_EXIT_ERROR);
}
}
if (argc == 3 && strcmp(argv[2], "-z") == 0) {
if ((rc = vs_statistics_reset()) == VS_ERR_NONE) {
return (VS_ADM_EXIT_SUCCESS);
} else {
(void) fprintf(stdout, "%s\n", vs_strerror(rc));
return (VS_ADM_EXIT_ERROR);
}
}
return (vs_adm_usage(stdout));
}
static void
vs_adm_output_stats(vs_stats_t *stats)
{
int i;
char *engid;
if (stats == NULL)
return;
(void) fprintf(stdout, "scanned=%lld\n", stats->vss_scanned);
(void) fprintf(stdout, "infected=%lld\n", stats->vss_infected);
if (stats->vss_cleaned > 0)
(void) printf("cleaned=%lld\n", stats->vss_cleaned);
(void) fprintf(stdout, "failed=%lld\n", stats->vss_failed);
for (i = 0; i < VS_SE_MAX; i++) {
engid = stats->vss_eng[i].vss_engid;
if (*engid == 0)
break;
(void) fprintf(stdout, "%s:errors=%lld\n", engid,
stats->vss_eng[i].vss_errors);
}
}
static int
vs_adm_props_from_input(int argc, char **argv, vs_props_t *vsprops,
uint64_t *propids)
{
const vs_adm_property_t *vap;
char *val;
int i;
(void) memset(vsprops, 0, sizeof (vs_props_t));
*propids = 0LL;
for (i = 2; i < argc; i++) {
if (strcmp(argv[i], "-p") == 0) {
if (++i >= argc)
return (VS_ADM_EXIT_USAGE);
}
if ((val = strchr(argv[i], '=')) == NULL)
return (VS_ADM_EXIT_USAGE);
*val = '\0';
val++;
if ((vap = vs_adm_prop_by_name(argv[i])) == NULL) {
(void) fprintf(stderr, "%s '%s'\n",
gettext("invalid property"), argv[i]);
return (VS_ADM_EXIT_ERROR);
}
*propids |= vap->vap_id;
if ((vs_adm_parse(vap, val, vsprops)) != 0) {
(void) fprintf(stderr, "%s '%s'\n",
gettext("invalid property value"), val);
return (VS_ADM_EXIT_ERROR);
}
}
return (VS_ADM_EXIT_SUCCESS);
}
static void
vs_adm_output_getcmd(uint64_t propids, const void *props)
{
char value[VS_ADM_PRINT_BUF_LEN];
uint64_t propid;
const vs_adm_property_t *vap;
char *label = NULL;
if (VS_PROPID_IS_SE(propids))
label = ((vs_props_se_t *)props)->vep_engid;
for (propid = 1LL; propid <= VS_PROPID_MAX; propid <<= 1) {
if ((propids & propid) == 0)
continue;
if ((vap = vs_adm_prop_by_id(propid)) == NULL)
continue;
*value = '\0';
vs_adm_unparse(vap, props, value, sizeof (value));
if (label)
(void) fprintf(stdout, "%s:", label);
(void) fprintf(stdout, "%s=%s\n", vap->vap_name, value);
}
(void) fprintf(stdout, "\n");
}
static const vs_adm_property_t *
vs_adm_prop_by_name(const char *propname)
{
const vs_adm_property_t *p;
for (p = vs_adm_props_all; p->vap_name != NULL; p++) {
if (strcmp(propname, p->vap_name) == 0)
return (p);
}
return (NULL);
}
static const vs_adm_property_t *
vs_adm_prop_by_id(const uint64_t propid)
{
const vs_adm_property_t *p;
for (p = vs_adm_props_all; p->vap_id != 0; p++) {
if (propid == p->vap_id)
return (p);
}
return (NULL);
}
static int
vs_adm_parse(const vs_adm_property_t *vap, const char *valvap_name,
void *vp)
{
return ((vap->vap_parse)(valvap_name, vp));
}
static int
vs_adm_parse_maxsize(const char *valstr, void *vp)
{
vs_props_t *svcp = vp;
uint64_t maxsize;
char *end;
errno = 0;
maxsize = strtoll(valstr, &end, 10);
if (errno != 0)
return (-1);
(void) snprintf(svcp->vp_maxsize, sizeof (svcp->vp_maxsize),
"%llu%s", maxsize, end);
return (0);
}
static int
vs_adm_parse_maxsize_action(const char *valstr, void *vp)
{
vs_props_t *svcp = vp;
if (strcmp(valstr, VS_ADM_ALLOW) == 0) {
svcp->vp_maxsize_action = B_TRUE;
return (0);
}
if (strcmp(valstr, VS_ADM_DENY) == 0) {
svcp->vp_maxsize_action = B_FALSE;
return (0);
}
return (-1);
}
static int
vs_adm_parse_types(const char *valstr, void *vp)
{
vs_props_t *svcp = vp;
if (strlen(valstr) >= sizeof (svcp->vp_types))
return (-1);
if (strlcpy(svcp->vp_types, valstr, sizeof (svcp->vp_types))
>= sizeof (svcp->vp_types))
return (-1);
return (0);
}
static int
vs_adm_parse_enable(const char *valstr, void *vp)
{
vs_props_se_t *sep = vp;
if (strcmp(valstr, VS_ADM_ON) == 0) {
sep->vep_enable = B_TRUE;
return (0);
}
if (strcmp(valstr, VS_ADM_OFF) == 0) {
sep->vep_enable = B_FALSE;
return (0);
}
return (-1);
}
static int
vs_adm_parse_host(const char *valstr, void *vp)
{
vs_props_se_t *sep = vp;
if (strlen(valstr) >= sizeof (sep->vep_host))
return (-1);
if (strlcpy(sep->vep_host, valstr, sizeof (sep->vep_host)) >=
sizeof (sep->vep_host))
return (-1);
return (0);
}
static int
vs_adm_parse_port(const char *valstr, void *vp)
{
vs_props_se_t *sep = vp;
unsigned long port;
char *end;
end = 0;
port = strtoul(valstr, &end, 0);
if (port > UINT16_MAX || (end < (valstr + strlen(valstr))))
return (-1);
sep->vep_port = port;
return (0);
}
static int
vs_adm_parse_maxconn(const char *valstr, void *vp)
{
vs_props_se_t *sep = vp;
char *end;
sep->vep_maxconn = strtoll(valstr, &end, 10);
if (end < valstr + strlen(valstr))
return (-1);
return (0);
}
static void
vs_adm_unparse(const vs_adm_property_t *vap, const void *vp,
char *buf, size_t len)
{
if ((vap->vap_unparse)(vp, buf, len) != 0)
(void) snprintf(buf, len, gettext(" (error) "));
}
static int
vs_adm_unparse_maxsize(const void *vp, char *buf, size_t len)
{
const vs_props_t *svcp = vp;
(void) snprintf(buf, len, "%s", svcp->vp_maxsize);
return (0);
}
static int
vs_adm_unparse_maxsize_action(const void *vp, char *buf, size_t len)
{
const vs_props_t *svcp = vp;
(void) snprintf(buf, len, "%s",
svcp->vp_maxsize_action ? VS_ADM_ALLOW : VS_ADM_DENY);
return (0);
}
static int
vs_adm_unparse_types(const void *vp, char *buf, size_t len)
{
const vs_props_t *svcp = vp;
(void) strlcpy(buf, svcp->vp_types, len);
return (0);
}
static int
vs_adm_unparse_enable(const void *vp, char *buf, size_t len)
{
const vs_props_se_t *sep = vp;
(void) snprintf(buf, len, "%s",
sep->vep_enable ? VS_ADM_ON : VS_ADM_OFF);
return (0);
}
static int
vs_adm_unparse_host(const void *vp, char *buf, size_t len)
{
const vs_props_se_t *sep = vp;
(void) strlcpy(buf, sep->vep_host, len);
return (0);
}
static int
vs_adm_unparse_port(const void *vp, char *buf, size_t len)
{
const vs_props_se_t *sep = vp;
(void) snprintf(buf, len, "%hu", sep->vep_port);
return (0);
}
static int
vs_adm_unparse_maxconn(const void *vp, char *buf, size_t len)
{
const vs_props_se_t *sep = vp;
(void) snprintf(buf, len, "%lld", sep->vep_maxconn);
return (0);
}