Lines Matching refs:ctx

54 #define donefunc_p(ctx) ((ctx).donefunc != NULL)  argument
71 struct ctl_cctx * ctx; member
148 struct ctl_cctx *ctx; in ctl_client() local
153 ctx = memget(sizeof *ctx); in ctl_client()
154 if (ctx == NULL) { in ctl_client()
158 ctx->state = initializing; in ctl_client()
159 ctx->ev = lev; in ctl_client()
160 ctx->logger = logger; in ctl_client()
161 ctx->timeout = evConsTime(timeout, 0); in ctl_client()
162 ctx->donefunc = donefunc; in ctl_client()
163 ctx->uap = uap; in ctl_client()
164 ctx->coID.opaque = NULL; in ctl_client()
165 ctx->tiID.opaque = NULL; in ctl_client()
166 ctx->rdID.opaque = NULL; in ctl_client()
167 ctx->wrID.opaque = NULL; in ctl_client()
168 buffer_init(ctx->inbuf); in ctl_client()
169 INIT_LIST(ctx->tran); in ctl_client()
170 INIT_LIST(ctx->wtran); in ctl_client()
171 ctx->sock = socket(sap->sa_family, SOCK_STREAM, PF_UNSPEC); in ctl_client()
172 if (ctx->sock > evHighestFD(ctx->ev)) { in ctl_client()
173 ctx->sock = -1; in ctl_client()
176 if (ctx->sock < 0) { in ctl_client()
177 (*ctx->logger)(ctl_error, "%s: socket: %s", in ctl_client()
182 if (setsockopt(ctx->sock, SOL_SOCKET, SO_REUSEADDR, in ctl_client()
184 (*ctx->logger)(ctl_warning, in ctl_client()
189 if (bind(ctx->sock, captmp, cap_len) < 0) { in ctl_client()
190 (*ctx->logger)(ctl_error, "%s: bind: %s", me, in ctl_client()
195 if (evConnect(lev, ctx->sock, (const struct sockaddr *)sap, sap_len, in ctl_client()
196 conn_done, ctx, &ctx->coID) < 0) { in ctl_client()
197 (*ctx->logger)(ctl_error, "%s: evConnect(fd %d): %s", in ctl_client()
198 me, ctx->sock, strerror(errno)); in ctl_client()
200 if (ctx != NULL) { in ctl_client()
201 if (ctx->sock >= 0) in ctl_client()
202 close(ctx->sock); in ctl_client()
203 memput(ctx, sizeof *ctx); in ctl_client()
207 new_state(ctx, connecting); in ctl_client()
208 return (ctx); in ctl_client()
217 ctl_endclient(struct ctl_cctx *ctx) { in ctl_endclient() argument
218 if (ctx->state != destroyed) in ctl_endclient()
219 destroy(ctx, 0); in ctl_endclient()
220 memput(ctx, sizeof *ctx); in ctl_endclient()
230 ctl_command(struct ctl_cctx *ctx, const char *cmd, size_t len, in ctl_command() argument
237 switch (ctx->state) { in ctl_command()
251 tran = new_tran(ctx, donefunc, uap, 1); in ctl_command()
254 if (ctl_bufget(&tran->outbuf, ctx->logger) < 0) in ctl_command()
262 start_write(ctx); in ctl_command()
269 new_tran(struct ctl_cctx *ctx, ctl_clntdone donefunc, void *uap, int w) { in new_tran() argument
274 new->ctx = ctx; in new_tran()
280 APPEND(ctx->tran, new, link); in new_tran()
282 APPEND(ctx->wtran, new, wlink); in new_tran()
287 start_write(struct ctl_cctx *ctx) { in start_write() argument
293 REQUIRE(ctx->state == connecting || ctx->state == connected); in start_write()
295 if (ctx->wrID.opaque != NULL) in start_write()
298 if (EMPTY(ctx->wtran)) { in start_write()
299 if (ctx->tiID.opaque != NULL) in start_write()
300 stop_timer(ctx); in start_write()
304 tran = HEAD(ctx->wtran); in start_write()
305 UNLINK(ctx->wtran, tran, wlink); in start_write()
307 if (ctx->tiID.opaque != NULL) in start_write()
308 touch_timer(ctx); in start_write()
310 start_timer(ctx); in start_write()
311 if (ctx->state == destroyed) in start_write()
317 if (evWrite(ctx->ev, ctx->sock, iov, iovp - iov, in start_write()
318 write_done, tran, &ctx->wrID) < 0) { in start_write()
319 (*ctx->logger)(ctl_error, "%s: evWrite: %s", me, in start_write()
321 error(ctx); in start_write()
324 if (evTimeRW(ctx->ev, ctx->wrID, ctx->tiID) < 0) { in start_write()
325 (*ctx->logger)(ctl_error, "%s: evTimeRW: %s", me, in start_write()
327 error(ctx); in start_write()
333 destroy(struct ctl_cctx *ctx, int notify) { in destroy() argument
336 if (ctx->sock != -1) { in destroy()
337 (void) close(ctx->sock); in destroy()
338 ctx->sock = -1; in destroy()
340 switch (ctx->state) { in destroy()
342 REQUIRE(ctx->wrID.opaque == NULL); in destroy()
343 REQUIRE(EMPTY(ctx->tran)); in destroy()
348 if (ctx->coID.opaque != NULL) { in destroy()
349 (void)evCancelConn(ctx->ev, ctx->coID); in destroy()
350 ctx->coID.opaque = NULL; in destroy()
354 REQUIRE(ctx->coID.opaque == NULL); in destroy()
355 if (ctx->wrID.opaque != NULL) { in destroy()
356 (void)evCancelRW(ctx->ev, ctx->wrID); in destroy()
357 ctx->wrID.opaque = NULL; in destroy()
359 if (ctx->rdID.opaque != NULL) in destroy()
360 stop_read(ctx); in destroy()
367 if (allocated_p(ctx->inbuf)) in destroy()
368 ctl_bufput(&ctx->inbuf); in destroy()
369 for (this = HEAD(ctx->tran); this != NULL; this = next) { in destroy()
374 (*this->donefunc)(ctx, this->uap, NULL, 0); in destroy()
377 if (ctx->tiID.opaque != NULL) in destroy()
378 stop_timer(ctx); in destroy()
379 new_state(ctx, destroyed); in destroy()
383 error(struct ctl_cctx *ctx) { in error() argument
384 REQUIRE(ctx->state != destroyed); in error()
385 destroy(ctx, 1); in error()
389 new_state(struct ctl_cctx *ctx, enum state new_state) { in new_state() argument
392 (*ctx->logger)(ctl_debug, "%s: %s -> %s", me, in new_state()
393 state_names[ctx->state], state_names[new_state]); in new_state()
394 ctx->state = new_state; in new_state()
403 struct ctl_cctx *ctx = uap; in conn_done() local
412 ctx->coID.opaque = NULL; in conn_done()
414 (*ctx->logger)(ctl_error, "%s: evConnect: %s", me, in conn_done()
416 error(ctx); in conn_done()
419 new_state(ctx, connected); in conn_done()
420 tran = new_tran(ctx, ctx->donefunc, ctx->uap, 0); in conn_done()
422 (*ctx->logger)(ctl_error, "%s: new_tran failed: %s", me, in conn_done()
424 error(ctx); in conn_done()
427 start_read(ctx); in conn_done()
428 if (ctx->state == destroyed) { in conn_done()
429 (*ctx->logger)(ctl_error, "%s: start_read failed: %s", in conn_done()
431 error(ctx); in conn_done()
439 struct ctl_cctx *ctx = tran->ctx; in write_done() local
444 ctx->wrID.opaque = NULL; in write_done()
445 if (ctx->tiID.opaque != NULL) in write_done()
446 touch_timer(ctx); in write_done()
448 start_write(ctx); in write_done()
450 destroy(ctx, 1); in write_done()
452 start_read(ctx); in write_done()
456 start_read(struct ctl_cctx *ctx) { in start_read() argument
459 REQUIRE(ctx->state == connecting || ctx->state == connected); in start_read()
460 REQUIRE(ctx->rdID.opaque == NULL); in start_read()
461 if (evSelectFD(ctx->ev, ctx->sock, EV_READ, readable, ctx, in start_read()
462 &ctx->rdID) < 0) in start_read()
464 (*ctx->logger)(ctl_error, "%s: evSelect(fd %d): %s", me, in start_read()
465 ctx->sock, strerror(errno)); in start_read()
466 error(ctx); in start_read()
472 stop_read(struct ctl_cctx *ctx) { in stop_read() argument
473 REQUIRE(ctx->coID.opaque == NULL); in stop_read()
474 REQUIRE(ctx->rdID.opaque != NULL); in stop_read()
475 (void)evDeselectFD(ctx->ev, ctx->rdID); in stop_read()
476 ctx->rdID.opaque = NULL; in stop_read()
482 struct ctl_cctx *ctx = uap; in readable() local
489 REQUIRE(ctx != NULL); in readable()
492 REQUIRE(ctx->state == connected); in readable()
493 REQUIRE(!EMPTY(ctx->tran)); in readable()
494 tran = HEAD(ctx->tran); in readable()
495 if (!allocated_p(ctx->inbuf) && in readable()
496 ctl_bufget(&ctx->inbuf, ctx->logger) < 0) { in readable()
497 (*ctx->logger)(ctl_error, "%s: can't get an input buffer", me); in readable()
498 error(ctx); in readable()
501 n = read(ctx->sock, ctx->inbuf.text + ctx->inbuf.used, in readable()
502 MAX_LINELEN - ctx->inbuf.used); in readable()
504 (*ctx->logger)(ctl_warning, "%s: read: %s", me, in readable()
506 error(ctx); in readable()
509 if (ctx->tiID.opaque != NULL) in readable()
510 touch_timer(ctx); in readable()
511 ctx->inbuf.used += n; in readable()
512 (*ctx->logger)(ctl_debug, "%s: read %d, used %d", me, in readable()
513 n, ctx->inbuf.used); in readable()
515 eos = memchr(ctx->inbuf.text, '\n', ctx->inbuf.used); in readable()
516 if (eos != NULL && eos != ctx->inbuf.text && eos[-1] == '\r') { in readable()
520 if (!arpacode_p(ctx->inbuf.text)) { in readable()
522 (*ctx->logger)(ctl_error, "%s: no arpa code (%s)", me, in readable()
523 ctx->inbuf.text); in readable()
524 error(ctx); in readable()
527 if (arpadone_p(ctx->inbuf.text)) in readable()
529 else if (arpacont_p(ctx->inbuf.text)) in readable()
533 (*ctx->logger)(ctl_error, "%s: no arpa flag (%s)", me, in readable()
534 ctx->inbuf.text); in readable()
535 error(ctx); in readable()
538 (*tran->donefunc)(ctx, tran->uap, ctx->inbuf.text, in readable()
540 ctx->inbuf.used -= ((eos - ctx->inbuf.text) + 1); in readable()
541 if (ctx->inbuf.used == 0U) in readable()
542 ctl_bufput(&ctx->inbuf); in readable()
544 memmove(ctx->inbuf.text, eos + 1, ctx->inbuf.used); in readable()
546 UNLINK(ctx->tran, tran, link); in readable()
548 stop_read(ctx); in readable()
549 start_write(ctx); in readable()
552 if (allocated_p(ctx->inbuf)) in readable()
556 if (ctx->inbuf.used == (size_t)MAX_LINELEN) { in readable()
557 (*ctx->logger)(ctl_error, "%s: line too long (%-10s...)", me, in readable()
558 ctx->inbuf.text); in readable()
559 error(ctx); in readable()
566 start_timer(struct ctl_cctx *ctx) { in start_timer() argument
569 REQUIRE(ctx->tiID.opaque == NULL); in start_timer()
570 if (evSetIdleTimer(ctx->ev, timer, ctx, ctx->timeout, &ctx->tiID) < 0){ in start_timer()
571 (*ctx->logger)(ctl_error, "%s: evSetIdleTimer: %s", me, in start_timer()
573 error(ctx); in start_timer()
579 stop_timer(struct ctl_cctx *ctx) { in stop_timer() argument
582 REQUIRE(ctx->tiID.opaque != NULL); in stop_timer()
583 if (evClearIdleTimer(ctx->ev, ctx->tiID) < 0) { in stop_timer()
584 (*ctx->logger)(ctl_error, "%s: evClearIdleTimer: %s", me, in stop_timer()
586 error(ctx); in stop_timer()
589 ctx->tiID.opaque = NULL; in stop_timer()
593 touch_timer(struct ctl_cctx *ctx) { in touch_timer() argument
594 REQUIRE(ctx->tiID.opaque != NULL); in touch_timer()
596 evTouchIdleTimer(ctx->ev, ctx->tiID); in touch_timer()
602 struct ctl_cctx *ctx = uap; in timer() local
608 ctx->tiID.opaque = NULL; in timer()
609 (*ctx->logger)(ctl_error, "%s: timeout after %u seconds while %s", me, in timer()
610 ctx->timeout.tv_sec, state_names[ctx->state]); in timer()
611 error(ctx); in timer()