forked from sipa/bitcoin-seeder
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
371 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright (c) 2009-2010 Satoshi Nakamoto | ||
// Copyright (c) 2009-2012 The Bitcoin developers | ||
// Distributed under the MIT/X11 software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
#ifndef _BITCOIN_COMPAT_H | ||
#define _BITCOIN_COMPAT_H 1 | ||
|
||
#ifdef WIN32 | ||
#define _WIN32_WINNT 0x0501 | ||
#define WIN32_LEAN_AND_MEAN 1 | ||
#ifndef NOMINMAX | ||
#define NOMINMAX | ||
#endif | ||
#include <winsock2.h> | ||
#include <mswsock.h> | ||
#include <ws2tcpip.h> | ||
#else | ||
#include <sys/types.h> | ||
#include <sys/socket.h> | ||
#include <sys/fcntl.h> | ||
#include <arpa/inet.h> | ||
#include <netdb.h> | ||
#include <net/if.h> | ||
#include <netinet/in.h> | ||
#include <ifaddrs.h> | ||
#endif | ||
|
||
typedef u_int SOCKET; | ||
#ifdef WIN32 | ||
#define MSG_NOSIGNAL 0 | ||
#define MSG_DONTWAIT 0 | ||
typedef int socklen_t; | ||
#else | ||
#include "errno.h" | ||
#define WSAGetLastError() errno | ||
#define WSAEINVAL EINVAL | ||
#define WSAEALREADY EALREADY | ||
#define WSAEWOULDBLOCK EWOULDBLOCK | ||
#define WSAEMSGSIZE EMSGSIZE | ||
#define WSAEINTR EINTR | ||
#define WSAEINPROGRESS EINPROGRESS | ||
#define WSAEADDRINUSE EADDRINUSE | ||
#define WSAENOTSOCK EBADF | ||
#define INVALID_SOCKET (SOCKET)(~0) | ||
#define SOCKET_ERROR -1 | ||
#endif | ||
|
||
inline int myclosesocket(SOCKET& hSocket) | ||
{ | ||
if (hSocket == INVALID_SOCKET) | ||
return WSAENOTSOCK; | ||
#ifdef WIN32 | ||
int ret = closesocket(hSocket); | ||
#else | ||
int ret = close(hSocket); | ||
#endif | ||
hSocket = INVALID_SOCKET; | ||
return ret; | ||
} | ||
#define closesocket(s) myclosesocket(s) | ||
|
||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> | ||
* | ||
* Permission to use, copy, modify, and distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | ||
* copyright notice and this permission notice appear in all copies. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
#ifndef BITCOIN_STRLCPY_H | ||
#define BITCOIN_STRLCPY_H | ||
|
||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
/* | ||
* Copy src to string dst of size siz. At most siz-1 characters | ||
* will be copied. Always NUL terminates (unless siz == 0). | ||
* Returns strlen(src); if retval >= siz, truncation occurred. | ||
*/ | ||
inline size_t strlcpy(char *dst, const char *src, size_t siz) | ||
{ | ||
char *d = dst; | ||
const char *s = src; | ||
size_t n = siz; | ||
|
||
/* Copy as many bytes as will fit */ | ||
if (n != 0) | ||
{ | ||
while (--n != 0) | ||
{ | ||
if ((*d++ = *s++) == '\0') | ||
break; | ||
} | ||
} | ||
|
||
/* Not enough room in dst, add NUL and traverse rest of src */ | ||
if (n == 0) | ||
{ | ||
if (siz != 0) | ||
*d = '\0'; /* NUL-terminate dst */ | ||
while (*s++) | ||
; | ||
} | ||
|
||
return(s - src - 1); /* count does not include NUL */ | ||
} | ||
|
||
/* | ||
* Appends src to string dst of size siz (unlike strncat, siz is the | ||
* full size of dst, not space left). At most siz-1 characters | ||
* will be copied. Always NUL terminates (unless siz <= strlen(dst)). | ||
* Returns strlen(src) + MIN(siz, strlen(initial dst)). | ||
* If retval >= siz, truncation occurred. | ||
*/ | ||
inline size_t strlcat(char *dst, const char *src, size_t siz) | ||
{ | ||
char *d = dst; | ||
const char *s = src; | ||
size_t n = siz; | ||
size_t dlen; | ||
|
||
/* Find the end of dst and adjust bytes left but don't go past end */ | ||
while (n-- != 0 && *d != '\0') | ||
d++; | ||
dlen = d - dst; | ||
n = siz - dlen; | ||
|
||
if (n == 0) | ||
return(dlen + strlen(s)); | ||
while (*s != '\0') | ||
{ | ||
if (n != 1) | ||
{ | ||
*d++ = *s; | ||
n--; | ||
} | ||
s++; | ||
} | ||
*d = '\0'; | ||
|
||
return(dlen + (s - src)); /* count does not include NUL */ | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
#include <stdio.h> | ||
#include "util.h" | ||
|
||
using namespace std; | ||
|
||
string vstrprintf(const std::string &format, va_list ap) | ||
{ | ||
char buffer[50000]; | ||
char* p = buffer; | ||
int limit = sizeof(buffer); | ||
int ret; | ||
loop | ||
{ | ||
va_list arg_ptr; | ||
va_copy(arg_ptr, ap); | ||
ret = vsnprintf(p, limit, format.c_str(), arg_ptr); | ||
va_end(arg_ptr); | ||
if (ret >= 0 && ret < limit) | ||
break; | ||
if (p != buffer) | ||
delete[] p; | ||
limit *= 2; | ||
p = new char[limit]; | ||
if (p == NULL) | ||
throw std::bad_alloc(); | ||
} | ||
string str(p, p+ret); | ||
if (p != buffer) | ||
delete[] p; | ||
return str; | ||
} | ||
|
||
string EncodeBase32(const unsigned char* pch, size_t len) | ||
{ | ||
static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567"; | ||
|
||
string strRet=""; | ||
strRet.reserve((len+4)/5*8); | ||
|
||
int mode=0, left=0; | ||
const unsigned char *pchEnd = pch+len; | ||
|
||
while (pch<pchEnd) | ||
{ | ||
int enc = *(pch++); | ||
switch (mode) | ||
{ | ||
case 0: // we have no bits | ||
strRet += pbase32[enc >> 3]; | ||
left = (enc & 7) << 2; | ||
mode = 1; | ||
break; | ||
|
||
case 1: // we have three bits | ||
strRet += pbase32[left | (enc >> 6)]; | ||
strRet += pbase32[(enc >> 1) & 31]; | ||
left = (enc & 1) << 4; | ||
mode = 2; | ||
break; | ||
|
||
case 2: // we have one bit | ||
strRet += pbase32[left | (enc >> 4)]; | ||
left = (enc & 15) << 1; | ||
mode = 3; | ||
break; | ||
|
||
case 3: // we have four bits | ||
strRet += pbase32[left | (enc >> 7)]; | ||
strRet += pbase32[(enc >> 2) & 31]; | ||
left = (enc & 3) << 3; | ||
mode = 4; | ||
break; | ||
|
||
case 4: // we have two bits | ||
strRet += pbase32[left | (enc >> 5)]; | ||
strRet += pbase32[enc & 31]; | ||
mode = 0; | ||
} | ||
} | ||
|
||
static const int nPadding[5] = {0, 6, 4, 3, 1}; | ||
if (mode) | ||
{ | ||
strRet += pbase32[left]; | ||
for (int n=0; n<nPadding[mode]; n++) | ||
strRet += '='; | ||
} | ||
|
||
return strRet; | ||
} | ||
|
||
string EncodeBase32(const string& str) | ||
{ | ||
return EncodeBase32((const unsigned char*)str.c_str(), str.size()); | ||
} | ||
|
||
vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid) | ||
{ | ||
static const int decode32_table[256] = | ||
{ | ||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, | ||
-1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, | ||
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2, | ||
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, | ||
23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, | ||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 | ||
}; | ||
|
||
if (pfInvalid) | ||
*pfInvalid = false; | ||
|
||
vector<unsigned char> vchRet; | ||
vchRet.reserve((strlen(p))*5/8); | ||
|
||
int mode = 0; | ||
int left = 0; | ||
|
||
while (1) | ||
{ | ||
int dec = decode32_table[(unsigned char)*p]; | ||
if (dec == -1) break; | ||
p++; | ||
switch (mode) | ||
{ | ||
case 0: // we have no bits and get 5 | ||
left = dec; | ||
mode = 1; | ||
break; | ||
|
||
case 1: // we have 5 bits and keep 2 | ||
vchRet.push_back((left<<3) | (dec>>2)); | ||
left = dec & 3; | ||
mode = 2; | ||
break; | ||
|
||
case 2: // we have 2 bits and keep 7 | ||
left = left << 5 | dec; | ||
mode = 3; | ||
break; | ||
|
||
case 3: // we have 7 bits and keep 4 | ||
vchRet.push_back((left<<1) | (dec>>4)); | ||
left = dec & 15; | ||
mode = 4; | ||
break; | ||
|
||
case 4: // we have 4 bits, and keep 1 | ||
vchRet.push_back((left<<4) | (dec>>1)); | ||
left = dec & 1; | ||
mode = 5; | ||
break; | ||
|
||
case 5: // we have 1 bit, and keep 6 | ||
left = left << 5 | dec; | ||
mode = 6; | ||
break; | ||
|
||
case 6: // we have 6 bits, and keep 3 | ||
vchRet.push_back((left<<2) | (dec>>3)); | ||
left = dec & 7; | ||
mode = 7; | ||
break; | ||
|
||
case 7: // we have 3 bits, and keep 0 | ||
vchRet.push_back((left<<5) | dec); | ||
mode = 0; | ||
break; | ||
} | ||
} | ||
|
||
if (pfInvalid) | ||
switch (mode) | ||
{ | ||
case 0: // 8n base32 characters processed: ok | ||
break; | ||
|
||
case 1: // 8n+1 base32 characters processed: impossible | ||
case 3: // +3 | ||
case 6: // +6 | ||
*pfInvalid = true; | ||
break; | ||
|
||
case 2: // 8n+2 base32 characters processed: require '======' | ||
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1) | ||
*pfInvalid = true; | ||
break; | ||
|
||
case 4: // 8n+4 base32 characters processed: require '====' | ||
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1) | ||
*pfInvalid = true; | ||
break; | ||
|
||
case 5: // 8n+5 base32 characters processed: require '===' | ||
if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1) | ||
*pfInvalid = true; | ||
break; | ||
|
||
case 7: // 8n+7 base32 characters processed: require '=' | ||
if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1) | ||
*pfInvalid = true; | ||
break; | ||
} | ||
|
||
return vchRet; | ||
} | ||
|
||
string DecodeBase32(const string& str) | ||
{ | ||
vector<unsigned char> vchRet = DecodeBase32(str.c_str()); | ||
return string((const char*)&vchRet[0], vchRet.size()); | ||
} |