ref: 4a3b80329a99d6d11a070d42c0103810bfdb7625
dir: /util.c/
/* * This work is dedicated to the public domain. * See COPYING file for more information. */ #include <sys/socket.h> #include <sys/stat.h> #include <errno.h> #include <fcntl.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #ifdef __gnu_linux__ #include <bsd/err.h> #else #include <err.h> #endif #define FALSE 0 #define TRUE 1 /* * ecalloc - calloc with error handling */ void * ecalloc(size_t nmemb, size_t size) { void *p; if ((p = calloc(nmemb, size)) == NULL) err(1, "calloc"); return p; } /* * realloc0 -- allocate more memory and zero new memory * ptr - pointer of the old memory * osize - size of old memory * nsize - size to new memory */ void * realloc0(void *ptr, size_t osize, size_t nsize) { void *p; if ((p = realloc(ptr, nsize)) == NULL) err(1, "realloc"); memset(((char *)p + osize), 0, nsize - osize); return p; } char* split(char **str, char ch) { char *token = *str; if (**str == '\0') return *str; while (**str != ch && **str != '\0') (*str)++; if (**str == '\0') return token; **str = '\0'; (*str)++; while(**str == ch && **str != '\0') (*str)++; return token; } int fifo_open(char *path) { struct stat st; int fd; /* make fifo if it doesn't exists */ if (lstat(path, &st) != -1) { if (!(st.st_mode & S_IFIFO)) errx(1, "'%s' is not a fifo file", path); } else if (mkfifo(path, S_IRWXU) == -1) { err(1, "mkfifo: %s", path); } fd = open(path, O_RDONLY | O_NONBLOCK, 0); if (fd == -1) err(1, "open: %s", path); return fd; } ssize_t writeall(int fd, char *buf) { ssize_t left, sent, n; left = (ssize_t)strlen(buf); sent = 0; while (sent < left) { if ((n = write(fd, buf+sent, (size_t)left)) == -1) err(1, "%d: write", fd); sent += n; left -= n; } return sent; } int dial(char *host, char *port) { static struct addrinfo hints, *res = NULL, *res0; int fd = -1, r; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((r = getaddrinfo(host, port, &hints, &res0)) != 0) { warnx("getaddrinfo: %s", gai_strerror(r)); return -1; } for (res = res0; res != NULL; res = res->ai_next) { if ((fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) continue; if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { warn("fnctl"); continue; } if ((connect(fd, res->ai_addr, res->ai_addrlen) == -1) && (errno == EINPROGRESS)) break; warn("connect"); close(fd); fd = -1; } if (fd == -1) warnx("cannot connect to %s", host); freeaddrinfo(res0); return fd; } ssize_t readline(int fd, char *buffer, size_t size) { size_t i = 0; char c; ssize_t l; do { l = read(fd, &c, sizeof(char)); if (l > 0) buffer[i++] = c; else if (l == 0) return 0; else if (l == -1 && errno == EAGAIN) continue; else return -1; } while ((i < size) && (c != '\r') && (c != '\n')); buffer[i-1] = '\0'; return (ssize_t)i; }