ticl

tiny irc channel linker
git clone git://git.ircforever.org/ticl
Log | Files | Refs | Submodules | README | LICENSE

util.c (3591B)


      1 /*
      2  * This work is dedicated to the public domain.
      3  * See COPYING file for more information.
      4  */
      5 
      6 #include <sys/socket.h>
      7 #include <sys/stat.h>
      8 
      9 #include <errno.h>
     10 #include <fcntl.h>
     11 #include <netdb.h>
     12 #include <stdarg.h>
     13 #include <stdio.h>
     14 #include <stdlib.h>
     15 #include <string.h>
     16 #include <unistd.h>
     17 
     18 #define FALSE	0
     19 #define TRUE	1
     20 
     21 #ifdef __gnu_linux__
     22 char *strlcpy(char *dst, const char *src, size_t n)
     23 {
     24 	return strncpy(dst, src, n);
     25 }
     26 #endif
     27 
     28 void
     29 print_log(int level, FILE *stream, const char *fmt, va_list arg)
     30 {
     31 	size_t	len;
     32 
     33 	if (level > LOG_LEVEL)
     34 		return;
     35 
     36 	vfprintf(stream, fmt, arg);
     37 	len = strlen(fmt);
     38 	if (len && fmt[len-1] == ':')
     39 		fprintf(stream, " %s\n", strerror(errno));
     40 	else
     41 		fprintf(stream, "\n");
     42 }
     43 
     44 void
     45 debug(int level, const char *fmt, ...)
     46 {
     47 	va_list arg;
     48 	va_start(arg, fmt);
     49 	print_log(level, stdout, fmt, arg);
     50 	va_end(arg);
     51 }
     52 
     53 void
     54 warnf(const char *fmt, ...)
     55 {
     56 	va_list arg;
     57 	fprintf(stderr, "warn: ");
     58 	va_start(arg, fmt);
     59 	print_log(0, stderr, fmt, arg);
     60 	va_end(arg);
     61 }
     62 
     63 void
     64 fatal(const char *fmt, ...)
     65 {
     66 	va_list arg;
     67 	fprintf(stderr, "error: ");
     68 	va_start(arg, fmt);
     69 	print_log(0, stderr, fmt, arg);
     70 	va_end(arg);
     71 	exit(1);
     72 }
     73 
     74 void *
     75 emalloc(size_t size)
     76 {
     77 	void *p;
     78 	if ((p = malloc(size)) == NULL)
     79 		fatal("malloc:");
     80 	return p;
     81 }
     82 
     83 void *
     84 ecalloc(size_t nmemb, size_t size)
     85 {
     86 	void *p;
     87 	if ((p = calloc(nmemb, size)) == NULL)
     88 		fatal("calloc:");
     89 	return p;
     90 }
     91 
     92 void *
     93 erealloc(void *ptr, size_t size)
     94 {
     95 	void *p;
     96 	if ((p = realloc(ptr, size)) == NULL)
     97 		fatal("realloc:");
     98 	return p;
     99 }
    100 
    101 char*
    102 split(char **str, char ch)
    103 {
    104 	char *token = *str;
    105 
    106 	if (**str == '\0') return *str;
    107 
    108 	while (**str != ch && **str != '\0')
    109 		(*str)++;
    110 	if (**str == '\0')
    111 		return token;
    112 	**str = '\0';
    113 	(*str)++;
    114 	while(**str == ch && **str != '\0')
    115 		(*str)++;
    116 	return token;
    117 }
    118 
    119 int
    120 dial(char *host, char *port)
    121 {
    122 	static struct addrinfo hints, *res = NULL, *res0;
    123 	int fd = -1, r;
    124 
    125 	memset(&hints, 0, sizeof(hints));
    126 	hints.ai_family = AF_UNSPEC;
    127 	hints.ai_socktype = SOCK_STREAM;
    128 
    129 	if ((r = getaddrinfo(host, port, &hints, &res0)) != 0) {
    130 		warnf("getaddrinfo: %s", gai_strerror(r));
    131 		return -1;
    132 	}
    133 	for (res = res0; res != NULL; res = res->ai_next) {
    134 		fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    135 		if (fd == -1) {
    136 			warnf("socket:");
    137 			continue;
    138 		}
    139 		if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
    140 			warnf("fnctl:");
    141 			continue;
    142 		}
    143 		if ((connect(fd, res->ai_addr, res->ai_addrlen) == -1) &&
    144 		    (errno == EINPROGRESS))
    145 			break;
    146 		warnf("connect:");
    147 		close(fd);
    148 		fd = -1;
    149 	}
    150 	if (fd == -1)
    151 		warnf("failed to connect to %s", host);
    152 
    153 	freeaddrinfo(res0);
    154 	return fd;
    155 }
    156 
    157 int
    158 fifo_open(char *path)
    159 {
    160 	struct stat st;
    161 	int fd;
    162 
    163 	/* make a fifo file if it doesn't exists */
    164 	if (lstat(path, &st) != -1) {
    165 		if (!(st.st_mode & S_IFIFO))
    166 			fatal("%s: not a fifo file", path);
    167 	} else if (mkfifo(path, S_IRWXU) == -1) {
    168 		fatal("mkfifo: %s:", path);
    169 	}
    170 
    171 	fd = open(path, O_RDONLY | O_NONBLOCK, 0);
    172 	if (fd == -1)
    173 		fatal("open: %s:", path);
    174 
    175 	return fd;
    176 }
    177 
    178 ssize_t
    179 readline(int fd, char *buffer, size_t size)
    180 {
    181 	size_t i = 0;
    182 	char c;
    183 	ssize_t l;
    184 
    185 	while (i < size) {
    186 		l = read(fd, &c, sizeof(char));
    187 		if (l == -1 && errno == EAGAIN)
    188 			continue;
    189 		else if (l == -1 || l == 0)
    190 			return l;
    191 
    192 		if (c == '\r' || c == '\n')
    193 			break;
    194 		buffer[i++] = c;
    195 	}
    196 	buffer[i++] = '\0';
    197 	return (ssize_t)i;
    198 }
    199 
    200 /* very simple string hash function */
    201 unsigned int
    202 hash_str(void *key, unsigned int cap)
    203 {
    204 	unsigned int i, sum = 0;
    205 
    206 	for (i = 0; i < (unsigned int)strlen(key); i++) {
    207 		sum += ((unsigned char *)key)[i] * (i + 1);
    208 	}
    209 	return (sum % cap);
    210 }