ref: 7c65a52929d95ad5a4108706bb32c7c7f754b193
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
#ifdef __gnu_linux__
char *strlcpy(char *dst, const char *src, size_t n)
{
return strncpy(dst, src, n);
}
#endif
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
debug(int level, const char *fmt, ...)
{
va_list arg;
va_start(arg, fmt);
print_log(level, 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;
}
/* 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);
}