/*- * Copyright (c) 2004 Free (Olivier Beyssac) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * */ #include #include #include #include #include #include #include #include #include "options.h" #include "client.h" #include "utils.h" #include "net.h" #define timeout_read(sd,buf,rd,errorcode) \ do { \ struct timeval tv; \ fd_set rset; \ \ /* Handle timeout */ \ tv.tv_sec = opt.notify_timeout; \ tv.tv_usec = 0; \ FD_ZERO(&rset); \ FD_SET(sd, &rset); \ net_socket_set_nb(sd); \ if ((select(sd + 1, &rset, NULL, NULL, &tv)) <= 0) { \ close(sd); \ return errorcode; \ } \ \ if ((rd = read(sd, &buf, sizeof(buf))) <= 0) { \ close(sd); \ return errorcode; \ } \ } while (0) extern struct options opt; /* Connect to host:port and return a socket descriptor if success, -1 otherwise */ extern int client_connect(const char *host, const char *port) { int sd; char buf[MAX_CMD_LEN]; ssize_t rd; if ((sd = net_client_sock_create(host, port)) == -1) return -1; /* Read banner and return -1 if error/timeout */ timeout_read(sd, buf, rd, -1); return sd; } /* Send a command and return the result code or -1 */ extern int client_send_cmdi(const int sd, const int cmd, const char *value) { char *buf; if ((buf = client_send_cmdc(sd, cmd, value)) == NULL) return -1; if (!isdigit(buf[0]) || !isdigit(buf[1]) || !isdigit(buf[2])) return -1; return (buf[0] - '0') * 100 + (buf[1] - '0') * 10 + buf[2] - '0'; } /* Send a command and return the resulting message line or NULL */ extern char *client_send_cmdc(const int sd, const int cmd, const char *value) { static char buf[MAX_CMD_LEN]; ssize_t rd; switch (cmd) { case CMD_SUBMIT: sprintf(buf, "ip=%s\r\n", value); break; case CMD_INSERT: sprintf(buf, "ipbl=%s\r\n", value); break; case CMD_DECR: sprintf(buf, "ipdecr=%s\r\n", value); break; case CMD_QUERY: default: sprintf(buf, "ip?=%s\r\n", value); } write(sd, buf, strlen(buf)); /* Read and return NULL if timeout/error */ timeout_read(sd, buf, rd, NULL); if (rd < 2) { return NULL; } buf[rd-2] = '\0'; return buf; }