⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctl_srvr.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
#if !defined(lint) && !defined(SABER)static const char rcsid[] = "$Id: ctl_srvr.c,v 1.3.2.1.4.3 2004/03/17 01:13:35 marka Exp $";#endif /* not lint *//* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1998,1999 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * 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. *//* Extern. */#include "port_before.h"#include <sys/param.h>#include <sys/file.h>#include <sys/socket.h>#include <sys/un.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <arpa/inet.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>#include <isc/assertions.h>#include <isc/ctl.h>#include <isc/eventlib.h>#include <isc/list.h>#include <isc/logging.h>#include <isc/memcluster.h>#include "ctl_p.h"#include "port_after.h"#ifdef SPRINTF_CHAR# define SPRINTF(x) strlen(sprintf/**/x)#else# define SPRINTF(x) ((size_t)sprintf x)#endif/* Macros. */#define	lastverb_p(verb)	(verb->name == NULL || verb->func == NULL)#define	address_expr		ctl_sa_ntop((struct sockaddr *)&sess->sa, \					    tmp, sizeof tmp, ctx->logger)/* Types. */enum state {	available = 0, initializing, writing, reading, reading_data,	processing, idling, quitting, closing};union sa_un {	struct sockaddr_in in;#ifndef NO_SOCKADDR_UN	struct sockaddr_un un;#endif};struct ctl_sess {	LINK(struct ctl_sess)	link;	struct ctl_sctx *	ctx;	enum state		state;	int			sock;	union sa_un		sa;	evFileID		rdID;	evStreamID		wrID;	evTimerID		rdtiID;	evTimerID		wrtiID;	struct ctl_buf		inbuf;	struct ctl_buf		outbuf;	const struct ctl_verb *	verb;	u_int			helpcode;	const void *		respctx;	u_int			respflags;	ctl_srvrdone		donefunc;	void *			uap;	void *			csctx;};struct ctl_sctx {	evContext		ev;	void *			uctx;	u_int			unkncode;	u_int			timeoutcode;	const struct ctl_verb *	verbs;	const struct ctl_verb *	connverb;	int			sock;	int			max_sess;	int			cur_sess;	struct timespec		timeout;	ctl_logfunc		logger;	evConnID		acID;	LIST(struct ctl_sess)	sess;};/* Forward. */static void			ctl_accept(evContext, void *, int,					   const void *, int,					   const void *, int);static void			ctl_close(struct ctl_sess *);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"};static const char		space[] = " ";static const struct ctl_verb	fakehelpverb = {	"fakehelp", ctl_morehelp , NULL};/* Public. *//* * void * ctl_server() *	create, condition, and start a listener on the control port. */struct ctl_sctx *ctl_server(evContext lev, const struct sockaddr *sap, size_t sap_len,	   const struct ctl_verb *verbs,	   u_int unkncode, u_int timeoutcode,	   u_int timeout, int backlog, int max_sess,	   ctl_logfunc logger, void *uctx){	static const char me[] = "ctl_server";	static const int on = 1;	const struct ctl_verb *connverb;	struct ctl_sctx *ctx;	int save_errno;	if (logger == NULL)		logger = ctl_logger;	for (connverb = verbs;	     connverb->name != NULL && connverb->func != NULL;	     connverb++)		if (connverb->name[0] == '\0')			break;	if (connverb->func == NULL) {		(*logger)(ctl_error, "%s: no connection verb found", me);		return (NULL);	}	ctx = memget(sizeof *ctx);	if (ctx == NULL) {		(*logger)(ctl_error, "%s: getmem: %s", me, strerror(errno));		return (NULL);	}	ctx->ev = lev;	ctx->uctx = uctx;	ctx->unkncode = unkncode;	ctx->timeoutcode = timeoutcode;	ctx->verbs = verbs;	ctx->timeout = evConsTime(timeout, 0);	ctx->logger = logger;	ctx->connverb = connverb;	ctx->max_sess = max_sess;	ctx->cur_sess = 0;	INIT_LIST(ctx->sess);	ctx->sock = socket(sap->sa_family, SOCK_STREAM, PF_UNSPEC);	if (ctx->sock > evHighestFD(ctx->ev)) {		ctx->sock = -1;		errno = ENOTSOCK;	}	if (ctx->sock < 0) {		save_errno = errno;		(*ctx->logger)(ctl_error, "%s: socket: %s",			       me, strerror(errno));		memput(ctx, sizeof *ctx);		errno = save_errno;		return (NULL);	}	if (ctx->sock > evHighestFD(lev)) {		close(ctx->sock);		(*ctx->logger)(ctl_error, "%s: file descriptor > evHighestFD");		errno = ENFILE;		memput(ctx, sizeof *ctx);		return (NULL);	}#ifdef NO_UNIX_REUSEADDR	if (sap->sa_family != AF_UNIX)#endif		if (setsockopt(ctx->sock, SOL_SOCKET, SO_REUSEADDR,			       (const char *)&on, sizeof on) != 0) {			(*ctx->logger)(ctl_warning,				       "%s: setsockopt(REUSEADDR): %s",				       me, strerror(errno));		}	if (bind(ctx->sock, sap, sap_len) < 0) {		char tmp[MAX_NTOP];		save_errno = errno;		(*ctx->logger)(ctl_error, "%s: bind: %s: %s",			       me, ctl_sa_ntop((const struct sockaddr *)sap,			       tmp, sizeof tmp, ctx->logger),			       strerror(save_errno));		close(ctx->sock);		memput(ctx, sizeof *ctx);		errno = save_errno;		return (NULL);	}	if (fcntl(ctx->sock, F_SETFD, 1) < 0) {		(*ctx->logger)(ctl_warning, "%s: fcntl: %s", me,			       strerror(errno));	}	if (evListen(lev, ctx->sock, backlog, ctl_accept, ctx,		     &ctx->acID) < 0) {		save_errno = errno;		(*ctx->logger)(ctl_error, "%s: evListen(fd %d): %s",			       me, ctx->sock, strerror(errno));		close(ctx->sock);		memput(ctx, sizeof *ctx);		errno = save_errno;		return (NULL);	}	(*ctx->logger)(ctl_debug, "%s: new ctx %p, sock %d",		       me, ctx, ctx->sock);	return (ctx);}/* * void * ctl_endserver(ctx) *	if the control listener is open, close it.  clean out all eventlib *	stuff.  close all active sessions. */voidctl_endserver(struct ctl_sctx *ctx) {	static const char me[] = "ctl_endserver";	struct ctl_sess *this, *next;	(*ctx->logger)(ctl_debug, "%s: ctx %p, sock %d, acID %p, sess %p",		       me, ctx, ctx->sock, ctx->acID.opaque, ctx->sess);	if (ctx->acID.opaque != NULL) {		(void)evCancelConn(ctx->ev, ctx->acID);		ctx->acID.opaque = NULL;	}	if (ctx->sock != -1) {		(void) close(ctx->sock);		ctx->sock = -1;	}	for (this = HEAD(ctx->sess); this != NULL; this = next) {		next = NEXT(this, link);		ctl_close(this);	}	memput(ctx, sizeof *ctx);}/* * If body is non-NULL then it we add a "." line after it. * Caller must have  escaped lines with leading ".". */voidctl_response(struct ctl_sess *sess, u_int code, const char *text,	     u_int flags, const void *respctx, ctl_srvrdone donefunc,	     void *uap, const char *body, size_t bodylen){	static const char me[] = "ctl_response";	struct iovec iov[3], *iovp = iov;	struct ctl_sctx *ctx = sess->ctx;	char tmp[MAX_NTOP], *pc;	int n;	REQUIRE(sess->state == initializing ||		sess->state == processing ||		sess->state == reading_data ||		sess->state == writing);	REQUIRE(sess->wrtiID.opaque == NULL);	REQUIRE(sess->wrID.opaque == NULL);	ctl_new_state(sess, writing, me);	sess->donefunc = donefunc;	sess->uap = uap;	if (!allocated_p(sess->outbuf) &&	    ctl_bufget(&sess->outbuf, ctx->logger) < 0) {		(*ctx->logger)(ctl_error, "%s: %s: cant get an output buffer",			       me, address_expr);		goto untimely;	}	if (sizeof "000-\r\n" + strlen(text) > (size_t)MAX_LINELEN) {		(*ctx->logger)(ctl_error, "%s: %s: output buffer ovf, closing",			       me, address_expr);		goto untimely;	}	sess->outbuf.used = SPRINTF((sess->outbuf.text, "%03d%c%s\r\n",				     code, (flags & CTL_MORE) != 0 ? '-' : ' ',				     text));	for (pc = sess->outbuf.text, n = 0;	     n < (int)sess->outbuf.used-2; pc++, n++)		if (!isascii((unsigned char)*pc) ||		    !isprint((unsigned char)*pc))			*pc = '\040';	*iovp++ = evConsIovec(sess->outbuf.text, sess->outbuf.used);	if (body != NULL) {		char *tmp;		DE_CONST(body, tmp);		*iovp++ = evConsIovec(tmp, bodylen);		DE_CONST(".\r\n", tmp);		*iovp++ = evConsIovec(tmp, 3);	}	(*ctx->logger)(ctl_debug, "%s: [%d] %s", me,		       sess->outbuf.used, sess->outbuf.text);	if (evWrite(ctx->ev, sess->sock, iov, iovp - iov,		    ctl_writedone, sess, &sess->wrID) < 0) {		(*ctx->logger)(ctl_error, "%s: %s: evWrite: %s", me,			       address_expr, strerror(errno));		goto untimely;	}	if (evSetIdleTimer(ctx->ev, ctl_wrtimeout, sess, ctx->timeout,			   &sess->wrtiID) < 0)	{		(*ctx->logger)(ctl_error, "%s: %s: evSetIdleTimer: %s", me,			       address_expr, strerror(errno));		goto untimely;	}	if (evTimeRW(ctx->ev, sess->wrID, sess->wrtiID) < 0) {		(*ctx->logger)(ctl_error, "%s: %s: evTimeRW: %s", me,			       address_expr, strerror(errno)); untimely:		ctl_signal_done(ctx, sess);		ctl_close(sess);		return;	}	sess->respctx = respctx;	sess->respflags = flags;}voidctl_sendhelp(struct ctl_sess *sess, u_int code) {	static const char me[] = "ctl_sendhelp";	struct ctl_sctx *ctx = sess->ctx;	sess->helpcode = code;	sess->verb = &fakehelpverb;	ctl_morehelp(ctx, sess, NULL, me, CTL_MORE,		     (const void *)ctx->verbs, NULL);}void *ctl_getcsctx(struct ctl_sess *sess) {	return (sess->csctx);}void *ctl_setcsctx(struct ctl_sess *sess, void *csctx) {	void *old = sess->csctx;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -