Lines Matching refs:ctx

60 #define donefunc_p(ctx) ((ctx).donefunc != NULL)
77 struct ctl_cctx * ctx;
154 struct ctl_cctx *ctx;
159 ctx = memget(sizeof *ctx);
160 if (ctx == NULL) {
164 ctx->state = initializing;
165 ctx->ev = lev;
166 ctx->logger = logger;
167 ctx->timeout = evConsTime(timeout, 0);
168 ctx->donefunc = donefunc;
169 ctx->uap = uap;
170 ctx->coID.opaque = NULL;
171 ctx->tiID.opaque = NULL;
172 ctx->rdID.opaque = NULL;
173 ctx->wrID.opaque = NULL;
174 buffer_init(ctx->inbuf);
175 INIT_LIST(ctx->tran);
176 INIT_LIST(ctx->wtran);
177 ctx->sock = socket(sap->sa_family, SOCK_STREAM, PF_UNSPEC);
178 if (ctx->sock > evHighestFD(ctx->ev)) {
179 ctx->sock = -1;
182 if (ctx->sock < 0) {
183 (*ctx->logger)(ctl_error, "%s: socket: %s",
188 if (setsockopt(ctx->sock, SOL_SOCKET, SO_REUSEADDR,
190 (*ctx->logger)(ctl_warning,
195 if (bind(ctx->sock, captmp, cap_len) < 0) {
196 (*ctx->logger)(ctl_error, "%s: bind: %s", me,
201 if (evConnect(lev, ctx->sock, (const struct sockaddr *)sap, sap_len,
202 conn_done, ctx, &ctx->coID) < 0) {
203 (*ctx->logger)(ctl_error, "%s: evConnect(fd %d): %s",
204 me, ctx->sock, strerror(errno));
206 if (ctx != NULL) {
207 if (ctx->sock >= 0)
208 close(ctx->sock);
209 memput(ctx, sizeof *ctx);
213 new_state(ctx, connecting);
214 return (ctx);
219 * ctl_endclient(ctx)
223 ctl_endclient(struct ctl_cctx *ctx) {
224 if (ctx->state != destroyed)
225 destroy(ctx, 0);
226 memput(ctx, sizeof *ctx);
231 * ctl_command(ctx, cmd, len, donefunc, uap)
236 ctl_command(struct ctl_cctx *ctx, const char *cmd, size_t len,
243 switch (ctx->state) {
257 tran = new_tran(ctx, donefunc, uap, 1);
260 if (ctl_bufget(&tran->outbuf, ctx->logger) < 0)
268 start_write(ctx);
275 new_tran(struct ctl_cctx *ctx, ctl_clntdone donefunc, void *uap, int w) {
280 new->ctx = ctx;
286 APPEND(ctx->tran, new, link);
288 APPEND(ctx->wtran, new, wlink);
293 start_write(struct ctl_cctx *ctx) {
299 REQUIRE(ctx->state == connecting || ctx->state == connected);
301 if (ctx->wrID.opaque != NULL)
304 if (EMPTY(ctx->wtran)) {
305 if (ctx->tiID.opaque != NULL)
306 stop_timer(ctx);
310 tran = HEAD(ctx->wtran);
311 UNLINK(ctx->wtran, tran, wlink);
313 if (ctx->tiID.opaque != NULL)
314 touch_timer(ctx);
316 start_timer(ctx);
317 if (ctx->state == destroyed)
323 if (evWrite(ctx->ev, ctx->sock, iov, iovp - iov,
324 write_done, tran, &ctx->wrID) < 0) {
325 (*ctx->logger)(ctl_error, "%s: evWrite: %s", me,
327 error(ctx);
330 if (evTimeRW(ctx->ev, ctx->wrID, ctx->tiID) < 0) {
331 (*ctx->logger)(ctl_error, "%s: evTimeRW: %s", me,
333 error(ctx);
339 destroy(struct ctl_cctx *ctx, int notify) {
342 if (ctx->sock != -1) {
343 (void) close(ctx->sock);
344 ctx->sock = -1;
346 switch (ctx->state) {
348 REQUIRE(ctx->wrID.opaque == NULL);
349 REQUIRE(EMPTY(ctx->tran));
354 if (ctx->coID.opaque != NULL) {
355 (void)evCancelConn(ctx->ev, ctx->coID);
356 ctx->coID.opaque = NULL;
360 REQUIRE(ctx->coID.opaque == NULL);
361 if (ctx->wrID.opaque != NULL) {
362 (void)evCancelRW(ctx->ev, ctx->wrID);
363 ctx->wrID.opaque = NULL;
365 if (ctx->rdID.opaque != NULL)
366 stop_read(ctx);
373 if (allocated_p(ctx->inbuf))
374 ctl_bufput(&ctx->inbuf);
375 for (this = HEAD(ctx->tran); this != NULL; this = next) {
380 (*this->donefunc)(ctx, this->uap, NULL, 0);
383 if (ctx->tiID.opaque != NULL)
384 stop_timer(ctx);
385 new_state(ctx, destroyed);
389 error(struct ctl_cctx *ctx) {
390 REQUIRE(ctx->state != destroyed);
391 destroy(ctx, 1);
395 new_state(struct ctl_cctx *ctx, enum state new_state) {
398 (*ctx->logger)(ctl_debug, "%s: %s -> %s", me,
399 state_names[ctx->state], state_names[new_state]);
400 ctx->state = new_state;
409 struct ctl_cctx *ctx = uap;
418 ctx->coID.opaque = NULL;
420 (*ctx->logger)(ctl_error, "%s: evConnect: %s", me,
422 error(ctx);
425 new_state(ctx, connected);
426 tran = new_tran(ctx, ctx->donefunc, ctx->uap, 0);
428 (*ctx->logger)(ctl_error, "%s: new_tran failed: %s", me,
430 error(ctx);
433 start_read(ctx);
434 if (ctx->state == destroyed) {
435 (*ctx->logger)(ctl_error, "%s: start_read failed: %s",
437 error(ctx);
445 struct ctl_cctx *ctx = tran->ctx;
450 ctx->wrID.opaque = NULL;
451 if (ctx->tiID.opaque != NULL)
452 touch_timer(ctx);
454 start_write(ctx);
456 destroy(ctx, 1);
458 start_read(ctx);
462 start_read(struct ctl_cctx *ctx) {
465 REQUIRE(ctx->state == connecting || ctx->state == connected);
466 REQUIRE(ctx->rdID.opaque == NULL);
467 if (evSelectFD(ctx->ev, ctx->sock, EV_READ, readable, ctx,
468 &ctx->rdID) < 0)
470 (*ctx->logger)(ctl_error, "%s: evSelect(fd %d): %s", me,
471 ctx->sock, strerror(errno));
472 error(ctx);
478 stop_read(struct ctl_cctx *ctx) {
479 REQUIRE(ctx->coID.opaque == NULL);
480 REQUIRE(ctx->rdID.opaque != NULL);
481 (void)evDeselectFD(ctx->ev, ctx->rdID);
482 ctx->rdID.opaque = NULL;
488 struct ctl_cctx *ctx = uap;
495 REQUIRE(ctx != NULL);
498 REQUIRE(ctx->state == connected);
499 REQUIRE(!EMPTY(ctx->tran));
500 tran = HEAD(ctx->tran);
501 if (!allocated_p(ctx->inbuf) &&
502 ctl_bufget(&ctx->inbuf, ctx->logger) < 0) {
503 (*ctx->logger)(ctl_error, "%s: can't get an input buffer", me);
504 error(ctx);
507 n = read(ctx->sock, ctx->inbuf.text + ctx->inbuf.used,
508 MAX_LINELEN - ctx->inbuf.used);
510 (*ctx->logger)(ctl_warning, "%s: read: %s", me,
512 error(ctx);
515 if (ctx->tiID.opaque != NULL)
516 touch_timer(ctx);
517 ctx->inbuf.used += n;
518 (*ctx->logger)(ctl_debug, "%s: read %d, used %d", me,
519 n, ctx->inbuf.used);
521 eos = memchr(ctx->inbuf.text, '\n', ctx->inbuf.used);
522 if (eos != NULL && eos != ctx->inbuf.text && eos[-1] == '\r') {
526 if (!arpacode_p(ctx->inbuf.text)) {
528 (*ctx->logger)(ctl_error, "%s: no arpa code (%s)", me,
529 ctx->inbuf.text);
530 error(ctx);
533 if (arpadone_p(ctx->inbuf.text))
535 else if (arpacont_p(ctx->inbuf.text))
539 (*ctx->logger)(ctl_error, "%s: no arpa flag (%s)", me,
540 ctx->inbuf.text);
541 error(ctx);
544 (*tran->donefunc)(ctx, tran->uap, ctx->inbuf.text,
546 ctx->inbuf.used -= ((eos - ctx->inbuf.text) + 1);
547 if (ctx->inbuf.used == 0U)
548 ctl_bufput(&ctx->inbuf);
550 memmove(ctx->inbuf.text, eos + 1, ctx->inbuf.used);
552 UNLINK(ctx->tran, tran, link);
554 stop_read(ctx);
555 start_write(ctx);
558 if (allocated_p(ctx->inbuf))
562 if (ctx->inbuf.used == (size_t)MAX_LINELEN) {
563 (*ctx->logger)(ctl_error, "%s: line too long (%-10s...)", me,
564 ctx->inbuf.text);
565 error(ctx);
572 start_timer(struct ctl_cctx *ctx) {
575 REQUIRE(ctx->tiID.opaque == NULL);
576 if (evSetIdleTimer(ctx->ev, timer, ctx, ctx->timeout, &ctx->tiID) < 0){
577 (*ctx->logger)(ctl_error, "%s: evSetIdleTimer: %s", me,
579 error(ctx);
585 stop_timer(struct ctl_cctx *ctx) {
588 REQUIRE(ctx->tiID.opaque != NULL);
589 if (evClearIdleTimer(ctx->ev, ctx->tiID) < 0) {
590 (*ctx->logger)(ctl_error, "%s: evClearIdleTimer: %s", me,
592 error(ctx);
595 ctx->tiID.opaque = NULL;
599 touch_timer(struct ctl_cctx *ctx) {
600 REQUIRE(ctx->tiID.opaque != NULL);
602 evTouchIdleTimer(ctx->ev, ctx->tiID);
608 struct ctl_cctx *ctx = uap;
614 ctx->tiID.opaque = NULL;
615 (*ctx->logger)(ctl_error, "%s: timeout after %u seconds while %s", me,
616 ctx->timeout.tv_sec, state_names[ctx->state]);
617 error(ctx);