ref: 202447793107a549c7e418dc3b2208caa89a0bb3
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 <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define FALSE 0 #define TRUE 1 void print_log(int level, FILE *stream, const char *fmt, va_list arg) { size_t len; if (level > LOG_LEVEL) return; vfprintf(stream, fmt, arg); len = strlen(fmt); if (len && fmt[len-1] == ':') fprintf(stream, " %s\n", strerror(errno)); else fprintf(stream, "\n"); } void log1(const char *fmt, ...) { va_list arg; va_start(arg, fmt); print_log(1, stdout, fmt, arg); va_end(arg); } void log2(const char *fmt, ...) { va_list arg; va_start(arg, fmt); print_log(2, stdout, fmt, arg); va_end(arg); } void log3(const char *fmt, ...) { va_list arg; va_start(arg, fmt); print_log(3, stdout, fmt, arg); va_end(arg); } void warnf(const char *fmt, ...) { va_list arg; fprintf(stderr, "warn: "); va_start(arg, fmt); print_log(0, stderr, fmt, arg); va_end(arg); } void fatal(const char *fmt, ...) { va_list arg; fprintf(stderr, "error: "); va_start(arg, fmt); print_log(0, stderr, fmt, arg); va_end(arg); exit(1); } void * emalloc(size_t size) { void *p; if ((p = malloc(size)) == NULL) fatal("malloc:"); return p; } void * ecalloc(size_t nmemb, size_t size) { void *p; if ((p = calloc(nmemb, size)) == NULL) fatal("calloc:"); return p; } void * erealloc(void *ptr, size_t size) { void *p; if ((p = realloc(ptr, size)) == NULL) fatal("realloc:"); 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 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) { warnf("getaddrinfo: %s", gai_strerror(r)); return -1; } for (res = res0; res != NULL; res = res->ai_next) { fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol); if (fd == -1) { warnf("socket:"); continue; } if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) { warnf("fnctl:"); continue; } if ((connect(fd, res->ai_addr, res->ai_addrlen) == -1) && (errno == EINPROGRESS)) break; warnf("connect:"); close(fd); fd = -1; } if (fd == -1) warnf("failed to connect to %s", host); freeaddrinfo(res0); return fd; } int fifo_open(char *path) { struct stat st; int fd; /* make a fifo file if it doesn't exists */ if (lstat(path, &st) != -1) { if (!(st.st_mode & S_IFIFO)) fatal("%s: not a fifo file", path); } else if (mkfifo(path, S_IRWXU) == -1) { fatal("mkfifo: %s:", path); } fd = open(path, O_RDONLY | O_NONBLOCK, 0); if (fd == -1) fatal("open: %s:", path); return fd; } ssize_t readline(int fd, char *buffer, size_t size) { size_t i = 0; char c; ssize_t l; while (i < size) { l = read(fd, &c, sizeof(char)); if (l == -1 && errno == EAGAIN) continue; else if (l == -1 || l == 0) return l; if (c == '\r' || c == '\n') break; buffer[i++] = c; } buffer[i++] = '\0'; return (ssize_t)i; } 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) fatal("%d: write:", fd); sent += n; left -= n; } return sent; } /* very simple string hash function */ unsigned int hash_str(void *key, unsigned int cap) { unsigned int i, sum = 0; for (i = 0; i < (unsigned int)strlen(key); i++) { sum += ((unsigned char *)key)[i] * (i + 1); } return (sum % cap); }