/* $Id: client.c,v 1.5 2003/04/13 09:26:04 steve Exp $ */ /*- * Copyright (c) 2001 Steve C. Woodford. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Steve C. Woodford. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "client.h" #include "listener.h" #include "logger.h" #include "config.h" static struct client_ops *client_types[] = { &listener_ops, &logger_ops, NULL }; static const char *cf_client_opt_readonly(void *, char **, int, int, void *); static const char *cf_client_opt_allowbreak(void *, char **, int, int, void *); static const char *cf_client_opt_suppressbanner(void *, char **, int, int, void *); static const char *cf_client_opt_timeout(void *, char **, int, int, void *); static struct config_tokens cf_client_option_tokens[] = { {"readonly", 1, cf_client_opt_readonly}, {"allowbreak", 1, cf_client_opt_allowbreak}, {"timeout", 1, cf_client_opt_timeout}, {"suppressbanner", 1, cf_client_opt_suppressbanner}, {NULL, 0, NULL} }; int client_init(struct client_ctx **ccp, struct client_ctx *pcc, struct client_ops *cops, struct client_options *copts, const void *carg) { struct client_ctx *cc; if ((cc = calloc(1, sizeof(*cc))) == NULL) return (-1); cc->cc_parent = pcc; cc->cc_ops = cops; if (copts) cc->cc_options = *copts; cc->cc_fd = -1; if (cops->co_init && (cops->co_init)(cc, carg) < 0) { (void) free(cc); return (-1); } if (pcc) (void) client_ioctl(pcc, CLIENT_IOCTL_NEW_CHILD, NULL, cc); *ccp = cc; return (0); } void client_destroy(struct client_ctx *cc) { if (cc->cc_ops->co_destroy) (cc->cc_ops->co_destroy)(cc); if (cc->cc_parent) (void) client_ioctl(cc->cc_parent,CLIENT_IOCTL_CHILD_DELETED, NULL, cc); (void) free(cc); } const char * cf_client_init(void *cs, char **argv, int argc, int is_compound, void *arg) { struct client_ops **co; for (co = client_types; *co; co++) if (strcasecmp((*co)->co_name, argv[1]) == 0) break; if (*co == NULL) return (config_err(cs, "Unknown client type `%s'", argv[1])); return (((*co)->co_cf_init)(cs, argv, argc, is_compound, arg)); } const char * cf_client_options(void *cs, struct client_options *co) { return (config_parse(cs, cf_client_option_tokens, (void *)co)); } /* ARGSUSED */ static const char * cf_client_opt_readonly(void *cs, char **argv, int argc, int cmpnd, void *arg) { struct client_options *co = arg; return (config_boolean(cs, argv[1], &co->co_readonly)); } /* ARGSUSED */ static const char * cf_client_opt_allowbreak(void *cs, char **argv, int argc, int cmpnd, void *arg) { struct client_options *co = arg; return (config_boolean(cs, argv[1], &co->co_allowbreak)); } /* ARGSUSED */ static const char * cf_client_opt_timeout(void *cs, char **argv, int argc, int cmpnd, void *arg) { struct client_options *co = arg; return (config_integer(cs, argv[1], &co->co_timeout)); } /* ARGSUSED */ static const char * cf_client_opt_suppressbanner(void *cs, char **argv, int argc, int cmpnd, void *arg) { struct client_options *co = arg; return (config_boolean(cs, argv[1], &co->co_suppressbanner)); }