/*
* Copyright (C) 2004-2006, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#endif /* not lint */
/* Extern. */
#include "port_before.h"
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include <isc/assertions.h>
#include <isc/eventlib.h>
#include <isc/memcluster.h>
#include "ctl_p.h"
#include "port_after.h"
#ifdef SPRINTF_CHAR
#else
#endif
/* Macros. */
/* Types. */
enum state {
};
union sa_un {
#ifndef NO_SOCKADDR_UN
#endif
};
struct ctl_sess {
int sock;
const void * respctx;
void * uap;
void * csctx;
};
struct ctl_sctx {
void * uctx;
int sock;
int max_sess;
int cur_sess;
};
/* Forward. */
static void ctl_accept(evContext, void *, int,
const void *, int,
const void *, int);
static void ctl_new_state(struct ctl_sess *,
enum state,
const char *);
static void ctl_start_read(struct ctl_sess *);
static void ctl_stop_read(struct ctl_sess *);
static void ctl_readable(evContext, void *, int, int);
static void ctl_rdtimeout(evContext, void *,
struct timespec,
struct timespec);
static void ctl_wrtimeout(evContext, void *,
struct timespec,
struct timespec);
static void ctl_docommand(struct ctl_sess *);
static void ctl_writedone(evContext, void *, int, int);
static void ctl_morehelp(struct ctl_sctx *,
struct ctl_sess *,
const struct ctl_verb *,
const char *,
u_int, const void *, void *);
static void ctl_signal_done(struct ctl_sctx *,
struct ctl_sess *);
/* Private data. */
static const char * state_names[] = {
"available", "initializing", "writing", "reading",
"reading_data", "processing", "idling", "quitting", "closing"
};
};
/* Public. */
/*%
* void
* ctl_server()
* create, condition, and start a listener on the control port.
*/
struct ctl_sctx *
{
int save_errno;
logger = ctl_logger;
connverb++)
break;
return (NULL);
}
return (NULL);
}
}
save_errno = errno;
errno = save_errno;
return (NULL);
}
return (NULL);
}
#ifdef NO_UNIX_REUSEADDR
#endif
"%s: setsockopt(REUSEADDR): %s",
}
save_errno = errno;
errno = save_errno;
return (NULL);
}
}
save_errno = errno;
errno = save_errno;
return (NULL);
}
return (ctx);
}
/*%
* void
* ctl_endserver(ctx)
* if the control listener is open, close it. clean out all eventlib
* stuff. close all active sessions.
*/
void
}
}
}
}
/*%
* If body is non-NULL then it we add a "." line after it.
* Caller must have escaped lines with leading ".".
*/
void
{
int n;
me, address_expr);
goto untimely;
}
me, address_expr);
goto untimely;
}
text));
*pc = '\040';
char *tmp;
}
goto untimely;
}
{
goto untimely;
}
return;
}
}
void
}
void *
}
void *
return (old);
}
/* Private functions. */
static void
{
if (fd < 0) {
return;
}
return;
}
return;
}
}
else
}
static void
{
}
static void
}
}
}
}
static void
{
return;
}
return;
}
}
static void
}
}
static void
ssize_t n;
me, address_expr);
return;
}
if (n <= 0) {
return;
}
} else {
}
else
return;
}
me, address_expr);
}
}
static void
{
me, address_expr);
}
}
static void
{
me, address_expr);
}
static void
if (*rest != '\0') {
*rest++ = '\0';
}
verb++)
break;
} else {
if (sizeof "Unrecognized command \"\" (args \"\")" +
else
"Unrecognized command \"%s\" (args \"%s\")",
NULL, 0);
}
}
static void
if (bytes < 0) {
return;
}
return;
} else {
}
}
static void
{
if (lastverb_p(next))
}
static void
}
}
/*! \file */