1 #include <string.h>
2 #include <time.h>
3 #include "util.h"
4 #ifdef __MINGW32__
5 #  include "compat.h"
6 #endif
7 
8 /* Return the smallest power of 2 not less than n */
ceil2(uint32_t n)9 uint32_t ceil2(uint32_t n)
10 {
11 	--n;
12 	n |= n >> 1;
13 	n |= n >> 2;
14 	n |= n >> 4;
15 	n |= n >> 8;
16 	n |= n >> 16;
17 	return n + 1;
18 }
19 
20 /* Return the largest power of 2 not greater than n */
floor2(uint32_t n)21 uint32_t floor2(uint32_t n)
22 {
23 	n |= n >> 1;
24 	n |= n >> 2;
25 	n |= n >> 4;
26 	n |= n >> 8;
27 	n |= n >> 16;
28 	return n - (n >> 1);
29 }
30 
31 #include <stdlib.h>
ver2int(const char * version)32 unsigned long ver2int(const char* version)
33 {
34 	unsigned long v;
35 	char* p;
36 
37 	v = (unsigned long)(strtod(version, &p) * 1e7 + 0.5);
38 	while (*p)
39 		v += *p++;
40 
41 	return v;
42 }
43 
44 
45 #if !HAVE_STRCASESTR || __WIN32__
46 #  include <ctype.h>
47 // from git 1.6.1.2 compat/strcasestr.c
strcasestr(const char * haystack,const char * needle)48 char *strcasestr(const char *haystack, const char *needle)
49 {
50 	int nlen = strlen(needle);
51 	int hlen = strlen(haystack) - nlen + 1;
52 	int i;
53 
54 	for (i = 0; i < hlen; i++) {
55 		int j;
56 		for (j = 0; j < nlen; j++) {
57 			unsigned char c1 = haystack[i+j];
58 			unsigned char c2 = needle[j];
59 			if (toupper(c1) != toupper(c2))
60 				goto next;
61 		}
62 		return (char *) haystack + i;
63 	next: ;
64 	}
65 	return NULL;
66 }
67 #endif // !HAVE_STRCASESTR
68 
69 
70 #if !HAVE_STRLCPY || __win32__
71 // from git 1.6.1.2 compat/strcasestr.c
strlcpy(char * dest,const char * src,size_t size)72 size_t strlcpy(char *dest, const char *src, size_t size)
73 {
74 	size_t ret = strlen(src);
75 
76 	if (size) {
77 		size_t len = (ret >= size) ? size - 1 : ret;
78 		memcpy(dest, src, len);
79 		dest[len] = '\0';
80 	}
81 	return ret;
82 }
83 #endif // !HAVE_STRLCPY
84 
85 
86 #ifdef __WIN32__
set_cloexec(int fd,unsigned char v)87 int set_cloexec(int fd, unsigned char v) { return 0; }
88 #else
89 #  include <unistd.h>
90 #  include <fcntl.h>
set_cloexec(int fd,unsigned char v)91 int set_cloexec(int fd, unsigned char v)
92 {
93 	int f = fcntl(fd, F_GETFD);
94 	return f == -1 ? f : fcntl(fd, F_SETFD, (v ? f | FD_CLOEXEC : f & ~FD_CLOEXEC));
95 }
96 #endif // __WIN32__
97 
98 
set_nonblock(int fd,unsigned char v)99 int set_nonblock(int fd, unsigned char v)
100 {
101 #ifndef __WIN32__
102 	int f = fcntl(fd, F_GETFL);
103 	return f == -1 ? f : fcntl(fd, F_SETFL, (v ? f | O_NONBLOCK : f & ~O_NONBLOCK));
104 #else // __WIN32__
105 	u_long v_ = (u_long)v;
106 	errno = 0;
107 	if (ioctlsocket(fd, FIONBIO, &v_) == SOCKET_ERROR) {
108 		errno = WSAGetLastError();
109 		return -1;
110 	}
111 	else
112 		return 0;
113 #endif // __WIN32__
114 }
115 
116 #ifndef __WIN32__
117 #  include <sys/types.h>
118 #  include <sys/socket.h>
119 #  include <netinet/in.h>
120 #  include <netinet/tcp.h>
121 #endif
set_nodelay(int fd,unsigned char v)122 int set_nodelay(int fd, unsigned char v)
123 {
124 	int val = v;
125 	return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const char*)&val, sizeof(val));
126 }
127 
128 
129 #ifdef __WIN32__
130 #  include <ws2tcpip.h>
131 #endif
132 
get_bufsize(int fd,int dir,int * len)133 int get_bufsize(int fd, int dir, int* len)
134 {
135 	socklen_t optlen = sizeof(*len);
136 	return getsockopt(fd, SOL_SOCKET, (dir == 0 ? SO_RCVBUF : SO_SNDBUF),
137 			  (char*)len, &optlen);
138 }
set_bufsize(int fd,int dir,int len)139 int set_bufsize(int fd, int dir, int len)
140 {
141 	return setsockopt(fd, SOL_SOCKET, (dir == 0 ? SO_RCVBUF : SO_SNDBUF),
142 			  (const char*)&len, sizeof(len));
143 }
144 
145 #ifndef __WIN32__
146 #include <pthread.h>
147 #include <signal.h>
148 #ifndef NSIG
149 #  define NSIG 64
150 #endif
151 static size_t nsig = 0;
152 static struct sigaction* sigact = 0;
153 static pthread_mutex_t sigmutex = PTHREAD_MUTEX_INITIALIZER;
154 #endif
155 
save_signals(void)156 void save_signals(void)
157 {
158 #ifndef __WIN32__
159 	pthread_mutex_lock(&sigmutex);
160 	if (!sigact)
161 		sigact = new struct sigaction[NSIG];
162 	for (nsig = 1; nsig <= NSIG; nsig++)
163 		if (sigaction(nsig, NULL, &sigact[nsig-1]) == -1)
164 			break;
165 	pthread_mutex_unlock(&sigmutex);
166 #endif
167 }
168 
restore_signals(void)169 void restore_signals(void)
170 {
171 #ifndef __WIN32__
172 	pthread_mutex_lock(&sigmutex);
173 	for (size_t i = 1; i <= nsig; i++)
174 		sigaction(i, &sigact[i-1], NULL);
175 	delete [] sigact;
176 	sigact = 0;
177 	nsig = 0;
178 	pthread_mutex_unlock(&sigmutex);
179 #endif
180 }
181 
182 
simple_hash_data(const unsigned char * buf,size_t len,uint32_t code)183 uint32_t simple_hash_data(const unsigned char* buf, size_t len, uint32_t code)
184 {
185 	for (size_t i = 0; i < len; i++)
186 		code = ((code << 4) | (code >> (32 - 4))) ^ (uint32_t)buf[i];
187 
188 	return code;
189 }
simple_hash_str(const unsigned char * str,uint32_t code)190 uint32_t simple_hash_str(const unsigned char* str, uint32_t code)
191 {
192 	while (*str)
193 		code = ((code << 4) | (code >> (32 - 4))) ^ (uint32_t)*str++;
194 	return code;
195 }
196 
197 #include <vector>
198 #include <climits>
199 
200 static const char hexsym[] = "0123456789ABCDEF";
201 static std::vector<char>* hexbuf;
str2hex(const unsigned char * str,size_t len)202 const char* str2hex(const unsigned char* str, size_t len)
203 {
204 	if (unlikely(len == 0))
205 		return "";
206 	if (unlikely(!hexbuf)) {
207 		hexbuf = new std::vector<char>;
208 		hexbuf->reserve(192);
209 	}
210 	if (unlikely(hexbuf->size() < len * 3))
211 		hexbuf->resize(len * 3);
212 
213 	char* p = &(*hexbuf)[0];
214 	size_t i;
215 	for (i = 0; i < len; i++) {
216 		*p++ = hexsym[str[i] >> 4];
217 		*p++ = hexsym[str[i] & 0xF];
218 		*p++ = ' ';
219 	}
220 	*(p - 1) = '\0';
221 
222 	return &(*hexbuf)[0];
223 }
224 
str2hex(const char * str,size_t len)225 const char* str2hex(const char* str, size_t len)
226 {
227 	return str2hex((const unsigned char*)str, len ? len : strlen(str));
228 }
229 
230 static std::vector<char>* binbuf;
uint2bin(unsigned u,size_t len)231 const char* uint2bin(unsigned u, size_t len)
232 {
233 	if (unlikely(len == 0))
234 		len = sizeof(u) * CHAR_BIT;
235 
236 	if (unlikely(!binbuf)) {
237 		binbuf = new std::vector<char>;
238 		binbuf->reserve(sizeof(u) * CHAR_BIT);
239 	}
240 	if (unlikely(binbuf->size() < len + 1))
241 		binbuf->resize(len + 1);
242 
243 	for (size_t i = 0; i < len; i++) {
244 		(*binbuf)[len - i - 1] = '0' + (u & 1);
245 		u >>= 1;
246 	}
247 	(*binbuf)[len] = '\0';
248 
249 	return &(*binbuf)[0];
250 }
251 
MilliSleep(long msecs)252 void MilliSleep(long msecs)
253 {
254 #ifndef __WIN32__
255 	struct timespec tv;
256 	tv.tv_sec = msecs / 1000;
257 	tv.tv_nsec = (msecs - tv.tv_sec * 1000) * 1000000L;
258 	nanosleep(&tv, NULL);
259 #else
260 	Sleep(msecs);
261 #endif
262 
263 }
264 
265