static sfsistat test_body(SMFICTX *ctx, unsigned char *data, size_t data_len) { if (verbose == 0) printf("test_body %ld bytes\n", (long) data_len); else printf("%.*s", (int) data_len, data); return (test_reply(ctx, test_body_reply)); }
static sfsistat test_close(SMFICTX *ctx) { printf("test_close\n"); if (verbose) printf("conn_count %d\n", conn_count); if (conn_count > 0 && --conn_count == 0) exit(0); return (test_reply(ctx, test_close_reply)); }
static sfsistat test_rcpt(SMFICTX *ctx, char **argv) { char **cpp; printf("test_rcpt"); for (cpp = argv; *cpp; cpp++) printf(" \"%s\"", *cpp); printf("\n"); return (test_reply(ctx, test_rcpt_reply)); }
static sfsistat test_eom(SMFICTX *ctx) { printf("test_eom\n"); #ifdef SMFIR_REPLBODY if (body_file) { char buf[BUFSIZ + 2]; FILE *fp; size_t len; int count; if ((fp = fopen(body_file, "r")) == 0) { perror(body_file); } else { printf("replace body with content of %s\n", body_file); for (count = 0; fgets(buf, BUFSIZ, fp) != 0; count++) { len = strcspn(buf, "\n"); buf[len + 0] = '\r'; buf[len + 1] = '\n'; if (smfi_replacebody(ctx, buf, len + 2) == MI_FAILURE) { fprintf(stderr, "body replace failure\n"); exit(1); } if (verbose) printf("%.*s\n", (int) len, buf); } if (count == 0) perror("fgets"); (void) fclose(fp); } } #endif #ifdef SMFIR_CHGFROM if (chg_from != 0 && smfi_chgfrom(ctx, chg_from, "whatever") == MI_FAILURE) fprintf(stderr, "smfi_chgfrom failed\n"); #endif #ifdef SMFIR_INSHEADER if (ins_hdr && smfi_insheader(ctx, ins_idx, ins_hdr, ins_val) == MI_FAILURE) fprintf(stderr, "smfi_insheader failed\n"); #endif #ifdef SMFIR_CHGHEADER if (chg_hdr && smfi_chgheader(ctx, chg_hdr, chg_idx, chg_val) == MI_FAILURE) fprintf(stderr, "smfi_chgheader failed\n"); #endif { int count; for (count = 0; count < rcpt_count; count++) if (smfi_addrcpt(ctx, rcpt_addr[count]) == MI_FAILURE) fprintf(stderr, "smfi_addrcpt `%s' failed\n", rcpt_addr[count]); } return (test_reply(ctx, test_eom_reply)); }
static sfsistat test_connect(SMFICTX *ctx, char *name, struct sockaddr * sa) { const char *print_addr; char buf[BUFSIZ]; printf("test_connect %s ", name); switch (sa->sa_family) { case AF_INET: { struct sockaddr_in *sin = (struct sockaddr_in *) sa; print_addr = inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); if (print_addr == 0) print_addr = strerror(errno); printf("AF_INET (%s:%d)\n", print_addr, ntohs(sin->sin_port)); } break; #ifdef HAS_IPV6 case AF_INET6: { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; print_addr = inet_ntop(AF_INET, &sin6->sin6_addr, buf, sizeof(buf)); if (print_addr == 0) print_addr = strerror(errno); printf("AF_INET6 (%s:%d)\n", print_addr, ntohs(sin6->sin6_port)); } break; #endif case AF_UNIX: { #undef sun struct sockaddr_un *sun = (struct sockaddr_un *) sa; printf("AF_UNIX (%s)\n", sun->sun_path); } break; default: printf(" [unknown address family]\n"); break; } return (test_reply(ctx, test_connect_reply)); }
static sfsistat test_unknown(SMFICTX *ctx, const char *what) { printf("test_unknown %s\n", what); return (test_reply(ctx, test_unknown_reply)); }
static sfsistat test_data(SMFICTX *ctx) { printf("test_data\n"); return (test_reply(ctx, test_data_reply)); }
static sfsistat test_abort(SMFICTX *ctx) { printf("test_abort\n"); return (test_reply(ctx, test_abort_reply)); }
static sfsistat test_eoh(SMFICTX *ctx) { printf("test_eoh\n"); return (test_reply(ctx, test_eoh_reply)); }
sfsistat test_header(SMFICTX *ctx, char *name, char *value) { printf("test_header \"%s\" \"%s\"\n", name, value); return (test_reply(ctx, test_header_reply)); }
static sfsistat test_helo(SMFICTX *ctx, char *arg) { printf("test_helo \"%s\"\n", arg ? arg : "NULL"); return (test_reply(ctx, test_helo_reply)); }
static int do_command(cmd_request_t cmd) { struct booth_site *site; struct boothc_ticket_msg reply; struct booth_transport const *tpt; uint32_t leader_id; int rv; int reply_cnt = 0, msg_logged = 0; const char *op_str = ""; if (cmd == CMD_GRANT) op_str = "grant"; else if (cmd == CMD_REVOKE) op_str = "revoke"; rv = 0; site = NULL; /* Always use TCP for client - at least for now. */ tpt = booth_transport + TCP; if (!*cl.site) site = local; else { if (!find_site_by_name(cl.site, &site, 1)) { log_error("Site \"%s\" not configured.", cl.site); goto out_close; } } if (site->type == ARBITRATOR) { if (site == local) { log_error("We're just an arbitrator, cannot grant/revoke tickets here."); } else { log_error("%s is just an arbitrator, cannot grant/revoke tickets there.", cl.site); } goto out_close; } assert(site->type == SITE); /* We don't check for existence of ticket, so that asking can be * done without local configuration, too. * Although, that means that the UDP port has to be specified, too. */ if (!cl.msg.ticket.id[0]) { /* If the loaded configuration has only a single ticket defined, use that. */ if (booth_conf->ticket_count == 1) { strncpy(cl.msg.ticket.id, booth_conf->ticket[0].name, sizeof(cl.msg.ticket.id)); } else { log_error("No ticket given."); goto out_close; } } redirect: init_header(&cl.msg.header, cmd, 0, cl.options, 0, 0, sizeof(cl.msg)); rv = tpt->open(site); if (rv < 0) goto out_close; rv = tpt->send(site, &cl.msg, sendmsglen(&cl.msg)); if (rv < 0) goto out_close; read_more: rv = tpt->recv_auth(site, &reply, sizeof(reply)); if (rv < 0) { /* print any errors depending on the code sent by the * server */ (void)test_reply(ntohl(reply.header.result), cmd); goto out_close; } rv = test_reply(ntohl(reply.header.result), cmd); if (rv == 1) { tpt->close(site); leader_id = ntohl(reply.ticket.leader); if (!find_site_by_id(leader_id, &site)) { log_error("Message with unknown redirect site %x received", leader_id); rv = -1; goto out_close; } goto redirect; } else if (rv == 2 || rv == 3) { /* the server has more to say */ /* don't wait too long */ if (reply_cnt > 1 && !(cl.options & OPT_WAIT)) { rv = 0; log_info("Giving up on waiting for the definite result. " "Please use \"booth list\" later to " "see the outcome."); goto out_close; } if (reply_cnt == 0) { log_info("%s request sent, " "waiting for the result ...", op_str); msg_logged++; } else if (rv == 3 && msg_logged < 2) { log_info("waiting for the CIB commit ..."); msg_logged++; } reply_cnt++; goto read_more; } out_close: if (site) tpt->close(site); return rv; }