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

📄 ctl_srvr.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
	sess->csctx = csctx;	return (old);}/* Private functions. */static voidctl_accept(evContext lev, void *uap, int fd,	   const void *lav, int lalen,	   const void *rav, int ralen){	static const char me[] = "ctl_accept";	struct ctl_sctx *ctx = uap;	struct ctl_sess *sess = NULL;	char tmp[MAX_NTOP];	UNUSED(lev);	UNUSED(lalen);	UNUSED(ralen);	if (fd < 0) {		(*ctx->logger)(ctl_error, "%s: accept: %s",			       me, strerror(errno));		return;	}	if (ctx->cur_sess == ctx->max_sess) {		(*ctx->logger)(ctl_error, "%s: %s: too many control sessions",			       me, ctl_sa_ntop((const struct sockaddr *)rav,					       tmp, sizeof tmp,					       ctx->logger));		(void) close(fd);		return;	}	sess = memget(sizeof *sess);	if (sess == NULL) {		(*ctx->logger)(ctl_error, "%s: memget: %s", me,			       strerror(errno));		(void) close(fd);		return;	}	if (fcntl(fd, F_SETFD, 1) < 0) {		(*ctx->logger)(ctl_warning, "%s: fcntl: %s", me,			       strerror(errno));	}	ctx->cur_sess++;	INIT_LINK(sess, link);	APPEND(ctx->sess, sess, link);	sess->ctx = ctx;	sess->sock = fd;	sess->wrID.opaque = NULL;	sess->rdID.opaque = NULL;	sess->wrtiID.opaque = NULL;	sess->rdtiID.opaque = NULL;	sess->respctx = NULL;	sess->csctx = NULL;	if (((const struct sockaddr *)rav)->sa_family == AF_UNIX)		ctl_sa_copy((const struct sockaddr *)lav,			    (struct sockaddr *)&sess->sa);	else		ctl_sa_copy((const struct sockaddr *)rav,			    (struct sockaddr *)&sess->sa);	sess->donefunc = NULL;	buffer_init(sess->inbuf);	buffer_init(sess->outbuf);	sess->state = available;	ctl_new_state(sess, initializing, me);	sess->verb = ctx->connverb;	(*ctx->logger)(ctl_debug, "%s: %s: accepting (fd %d)",		       me, address_expr, sess->sock);	(*ctx->connverb->func)(ctx, sess, ctx->connverb, "", 0,			       (const struct sockaddr *)rav, ctx->uctx);}static voidctl_new_state(struct ctl_sess *sess, enum state new_state, const char *reason){	static const char me[] = "ctl_new_state";	struct ctl_sctx *ctx = sess->ctx;	char tmp[MAX_NTOP];	(*ctx->logger)(ctl_debug, "%s: %s: %s -> %s (%s)",		       me, address_expr,		       state_names[sess->state],		       state_names[new_state], reason);	sess->state = new_state;}static voidctl_close(struct ctl_sess *sess) {	static const char me[] = "ctl_close";	struct ctl_sctx *ctx = sess->ctx;	char tmp[MAX_NTOP];	REQUIRE(sess->state == initializing ||		sess->state == writing ||		sess->state == reading ||		sess->state == processing ||		sess->state == reading_data ||		sess->state == idling);	REQUIRE(sess->sock != -1);	if (sess->state == reading || sess->state == reading_data)		ctl_stop_read(sess);	else if (sess->state == writing) {		if (sess->wrID.opaque != NULL) {			(void) evCancelRW(ctx->ev, sess->wrID);			sess->wrID.opaque = NULL;		}		if (sess->wrtiID.opaque != NULL) {			(void) evClearIdleTimer(ctx->ev, sess->wrtiID);			sess->wrtiID.opaque = NULL;		}	}	ctl_new_state(sess, closing, me);	(void) close(sess->sock);	if (allocated_p(sess->inbuf))		ctl_bufput(&sess->inbuf);	if (allocated_p(sess->outbuf))		ctl_bufput(&sess->outbuf);	(*ctx->logger)(ctl_debug, "%s: %s: closed (fd %d)",		       me, address_expr, sess->sock);	UNLINK(ctx->sess, sess, link);	memput(sess, sizeof *sess);	ctx->cur_sess--;}static voidctl_start_read(struct ctl_sess *sess) {	static const char me[] = "ctl_start_read";	struct ctl_sctx *ctx = sess->ctx;	char tmp[MAX_NTOP];	REQUIRE(sess->state == initializing ||		sess->state == writing ||		sess->state == processing ||		sess->state == idling);	REQUIRE(sess->rdtiID.opaque == NULL);	REQUIRE(sess->rdID.opaque == NULL);	sess->inbuf.used = 0;	if (evSetIdleTimer(ctx->ev, ctl_rdtimeout, sess, ctx->timeout,			   &sess->rdtiID) < 0)	{		(*ctx->logger)(ctl_error, "%s: %s: evSetIdleTimer: %s", me,			       address_expr, strerror(errno));		ctl_close(sess);		return;	}	if (evSelectFD(ctx->ev, sess->sock, EV_READ,		       ctl_readable, sess, &sess->rdID) < 0) {		(*ctx->logger)(ctl_error, "%s: %s: evSelectFD: %s", me,			       address_expr, strerror(errno));		return;	}	ctl_new_state(sess, reading, me);}static voidctl_stop_read(struct ctl_sess *sess) {	static const char me[] = "ctl_stop_read";	struct ctl_sctx *ctx = sess->ctx;	REQUIRE(sess->state == reading || sess->state == reading_data);	REQUIRE(sess->rdID.opaque != NULL);	(void) evDeselectFD(ctx->ev, sess->rdID);	sess->rdID.opaque = NULL;	if (sess->rdtiID.opaque != NULL) {		(void) evClearIdleTimer(ctx->ev, sess->rdtiID);		sess->rdtiID.opaque = NULL;	}	ctl_new_state(sess, idling, me);}static voidctl_readable(evContext lev, void *uap, int fd, int evmask) {	static const char me[] = "ctl_readable";	struct ctl_sess *sess = uap;	struct ctl_sctx *ctx = sess->ctx;	char *eos, tmp[MAX_NTOP];	ssize_t n;	REQUIRE(sess != NULL);	REQUIRE(fd >= 0);	REQUIRE(evmask == EV_READ);	REQUIRE(sess->state == reading || sess->state == reading_data);	evTouchIdleTimer(lev, sess->rdtiID);	if (!allocated_p(sess->inbuf) &&	    ctl_bufget(&sess->inbuf, ctx->logger) < 0) {		(*ctx->logger)(ctl_error, "%s: %s: cant get an input buffer",			       me, address_expr);		ctl_close(sess);		return;	}	n = read(sess->sock, sess->inbuf.text + sess->inbuf.used,		 MAX_LINELEN - sess->inbuf.used);	if (n <= 0) {		(*ctx->logger)(ctl_debug, "%s: %s: read: %s",			       me, address_expr,			       (n == 0) ? "Unexpected EOF" : strerror(errno));		ctl_close(sess);		return;	}	sess->inbuf.used += n;	eos = memchr(sess->inbuf.text, '\n', sess->inbuf.used);	if (eos != NULL && eos != sess->inbuf.text && eos[-1] == '\r') {		eos[-1] = '\0';		if ((sess->respflags & CTL_DATA) != 0) {			INSIST(sess->verb != NULL);			(*sess->verb->func)(sess->ctx, sess, sess->verb,					    sess->inbuf.text,					    CTL_DATA, sess->respctx,					    sess->ctx->uctx);		} else {			ctl_stop_read(sess);			ctl_docommand(sess);		}		sess->inbuf.used -= ((eos - sess->inbuf.text) + 1);		if (sess->inbuf.used == 0U)			ctl_bufput(&sess->inbuf);		else			memmove(sess->inbuf.text, eos + 1, sess->inbuf.used);		return;	}	if (sess->inbuf.used == (size_t)MAX_LINELEN) {		(*ctx->logger)(ctl_error, "%s: %s: line too long, closing",			       me, address_expr);		ctl_close(sess);	}}static voidctl_wrtimeout(evContext lev, void *uap,	      struct timespec due,	      struct timespec itv){	static const char me[] = "ctl_wrtimeout";	struct ctl_sess *sess = uap;	struct ctl_sctx *ctx = sess->ctx;	char tmp[MAX_NTOP];		UNUSED(lev);	UNUSED(due);	UNUSED(itv);	REQUIRE(sess->state == writing);	sess->wrtiID.opaque = NULL;	(*ctx->logger)(ctl_warning, "%s: %s: write timeout, closing",		       me, address_expr);	if (sess->wrID.opaque != NULL) {		(void) evCancelRW(ctx->ev, sess->wrID);		sess->wrID.opaque = NULL;	}	ctl_signal_done(ctx, sess);	ctl_new_state(sess, processing, me);	ctl_close(sess);}static voidctl_rdtimeout(evContext lev, void *uap,	      struct timespec due,	      struct timespec itv){	static const char me[] = "ctl_rdtimeout";	struct ctl_sess *sess = uap;	struct ctl_sctx *ctx = sess->ctx;	char tmp[MAX_NTOP];	UNUSED(lev);	UNUSED(due);	UNUSED(itv);	REQUIRE(sess->state == reading);	sess->rdtiID.opaque = NULL;	(*ctx->logger)(ctl_warning, "%s: %s: timeout, closing",		       me, address_expr);	if (sess->state == reading || sess->state == reading_data)		ctl_stop_read(sess);	ctl_signal_done(ctx, sess);	ctl_new_state(sess, processing, me);	ctl_response(sess, ctx->timeoutcode, "Timeout.", CTL_EXIT, NULL,		     NULL, NULL, NULL, 0);}static voidctl_docommand(struct ctl_sess *sess) {	static const char me[] = "ctl_docommand";	char *name, *rest, tmp[MAX_NTOP];	struct ctl_sctx *ctx = sess->ctx;	const struct ctl_verb *verb;	REQUIRE(allocated_p(sess->inbuf));	(*ctx->logger)(ctl_debug, "%s: %s: \"%s\" [%u]",		       me, address_expr,		       sess->inbuf.text, (u_int)sess->inbuf.used);	ctl_new_state(sess, processing, me);	name = sess->inbuf.text + strspn(sess->inbuf.text, space);	rest = name + strcspn(name, space);	if (*rest != '\0') {		*rest++ = '\0';		rest += strspn(rest, space);	}	for (verb = ctx->verbs;	     verb != NULL && verb->name != NULL && verb->func != NULL;	     verb++)		if (verb->name[0] != '\0' && strcasecmp(name, verb->name) == 0)			break;	if (verb != NULL && verb->name != NULL && verb->func != NULL) {		sess->verb = verb;		(*verb->func)(ctx, sess, verb, rest, 0, NULL, ctx->uctx);	} else {		char buf[1100];		if (sizeof "Unrecognized command \"\" (args \"\")" +		    strlen(name) + strlen(rest) > sizeof buf)			strcpy(buf, "Unrecognized command (buf ovf)");		else			sprintf(buf,				"Unrecognized command \"%s\" (args \"%s\")",				name, rest);		ctl_response(sess, ctx->unkncode, buf, 0, NULL, NULL, NULL,			     NULL, 0);	}}static voidctl_writedone(evContext lev, void *uap, int fd, int bytes) {	static const char me[] = "ctl_writedone";	struct ctl_sess *sess = uap;	struct ctl_sctx *ctx = sess->ctx;	char tmp[MAX_NTOP];	int save_errno = errno;	UNUSED(lev);	UNUSED(uap);	REQUIRE(sess->state == writing);	REQUIRE(fd == sess->sock);	REQUIRE(sess->wrtiID.opaque != NULL);	sess->wrID.opaque = NULL;	(void) evClearIdleTimer(ctx->ev, sess->wrtiID);	sess->wrtiID.opaque = NULL;	if (bytes < 0) {		(*ctx->logger)(ctl_error, "%s: %s: %s",			       me, address_expr, strerror(save_errno));		ctl_close(sess);		return;	}	INSIST(allocated_p(sess->outbuf));	ctl_bufput(&sess->outbuf);	if ((sess->respflags & CTL_EXIT) != 0) {		ctl_signal_done(ctx, sess);		ctl_close(sess);		return;	} else if ((sess->respflags & CTL_MORE) != 0) {		INSIST(sess->verb != NULL);		(*sess->verb->func)(sess->ctx, sess, sess->verb, "",				    CTL_MORE, sess->respctx, sess->ctx->uctx);	} else {		ctl_signal_done(ctx, sess);		ctl_start_read(sess);	}}static voidctl_morehelp(struct ctl_sctx *ctx, struct ctl_sess *sess,	     const struct ctl_verb *verb, const char *text,	     u_int respflags, const void *respctx, void *uctx){	const struct ctl_verb *this = respctx, *next = this + 1;	UNUSED(ctx);	UNUSED(verb);	UNUSED(text);	UNUSED(uctx);	REQUIRE(!lastverb_p(this));	REQUIRE((respflags & CTL_MORE) != 0);	if (lastverb_p(next))		respflags &= ~CTL_MORE;	ctl_response(sess, sess->helpcode, this->help, respflags, next,		     NULL, NULL, NULL, 0);}static voidctl_signal_done(struct ctl_sctx *ctx, struct ctl_sess *sess) {	if (sess->donefunc != NULL) {		(*sess->donefunc)(ctx, sess, sess->uap);		sess->donefunc = NULL;	}}

⌨️ 快捷键说明

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