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