/*
* Copyright (C) 2004, 2005, 2007, 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>
#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"
/* Constants. */
/* Macros. */
/* Types. */
enum state {
};
struct ctl_tran {
void * uap;
};
struct ctl_cctx {
int sock;
void * uap;
};
/* Forward. */
static void start_write(struct ctl_cctx *);
const void *, int,
const void *, int);
static void write_done(evContext, void *, int, int);
static void start_read(struct ctl_cctx *);
static void start_timer(struct ctl_cctx *);
static void stop_timer(struct ctl_cctx *);
static void touch_timer(struct ctl_cctx *);
#ifndef HAVE_MEMCHR
static void *
const unsigned char *p = b;
size_t i;
for (i = 0; i < len; i++, p++)
if (*p == (unsigned char)c)
return ((void *)p);
return (NULL);
}
#endif
/* Private data. */
static const char * const state_names[] = {
"initializing", "connecting", "connected", "destroyed"
};
/* Public. */
/*%
* void
* ctl_client()
* create, condition, and connect to a listener on the control port.
*/
struct ctl_cctx *
{
logger = ctl_logger;
goto fatal;
}
}
goto fatal;
}
"%s: setsockopt(REUSEADDR): %s",
}
goto fatal;
}
}
}
return (NULL);
}
return (ctx);
}
/*%
* void
* ctl_endclient(ctx)
* close a client and release all of its resources.
*/
void
}
/*%
* int
* ctl_command(ctx, cmd, len, donefunc, uap)
* Queue a transaction, which will begin with sending cmd
* and complete by calling donefunc with the answer.
*/
int
{
char *pc;
unsigned int n;
case destroyed:
return (-1);
case connecting:
case connected:
break;
default:
abort();
}
return (-1);
}
return (-1);
return (-1);
*pc = '\040';
return (0);
}
/* Private. */
static struct ctl_tran *
return (NULL);
if (w)
return (new);
}
static void
char * tmp;
/* If there is a write in progress, don't try to write more yet. */
return;
/* If there are no trans, make sure timer is off, and we're done. */
return;
}
/* Pull it off the head of the write queue. */
/* Since there are some trans, make sure timer is successfully "on". */
else
return;
/* Marshall a newline-terminated message and clock it out. */
return;
}
return;
}
}
static void
}
case connecting:
/*
* This test is nec'y since destroy() can be called from
* start_read() while the state is still "connecting".
*/
}
break;
case connected:
}
break;
case destroyed:
break;
default:
abort();
}
}
}
static void
}
static void
}
static void
{
if (fd < 0) {
return;
}
return;
}
return;
}
}
static void
if (bytes < 0)
else
}
static void
{
return;
}
}
static void
}
static void
ssize_t n;
char *eos;
return;
}
if (n <= 0) {
return;
}
int done = 0;
/* XXX Doesn't FTP do this sometimes? Is it legal? */
return;
}
done = 1;
done = 0;
else {
/* XXX Doesn't FTP do this sometimes? Is it legal? */
return;
}
else
if (done) {
return;
}
goto again;
return;
}
}
}
/* Timer related stuff. */
static void
return;
}
}
static void
return;
}
}
static void
}
static void
}
/*! \file */