diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2016-03-26 17:12:52 +0900 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2016-03-26 17:20:27 +0900 |
| commit | d64089632e82a2548752c7a6baaa68365a795a74 (patch) | |
| tree | 57fc7b85a8c1290975d58fa4761b04a7695bf7e3 /src/util.cc | |
| parent | c81b1321122e8509b55c94c0cbca0d8d6d319f0c (diff) | |
| parent | a7cd943a06b1a5ff4515b57060b84037f8d01f9f (diff) | |
Merge branch 'master' into random-webseeding
Diffstat (limited to 'src/util.cc')
| -rw-r--r-- | src/util.cc | 1264 |
1 files changed, 671 insertions, 593 deletions
diff --git a/src/util.cc b/src/util.cc index a49547ca..1d9d8bbf 100644 --- a/src/util.cc +++ b/src/util.cc @@ -37,20 +37,20 @@ #ifdef __sun // For opensolaris, just include signal.h which includes sys/signal.h #ifdef HAVE_SIGNAL_H -# include <signal.h> +#include <signal.h> #endif // HAVE_SIGNAL_H -#else // !__sun +#else // !__sun #ifdef HAVE_SYS_SIGNAL_H -# include <sys/signal.h> +#include <sys/signal.h> #endif // HAVE_SYS_SIGNAL_H #ifdef HAVE_SIGNAL_H -# include <signal.h> +#include <signal.h> #endif // HAVE_SIGNAL_H #endif // !__sun #include <sys/types.h> #ifdef HAVE_PWD_H -# include <pwd.h> +#include <pwd.h> #endif // HAVE_PWD_H #include <array> @@ -91,7 +91,7 @@ // For libc6 which doesn't define ULLONG_MAX properly because of broken limits.h #ifndef ULLONG_MAX -# define ULLONG_MAX 18446744073709551615ULL +#define ULLONG_MAX 18446744073709551615ULL #endif // ULLONG_MAX namespace aria2 { @@ -107,22 +107,23 @@ int utf8ToWChar(wchar_t* out, size_t outLength, const char* src) namespace { int wCharToUtf8(char* out, size_t outLength, const wchar_t* src) { - return WideCharToMultiByte(CP_UTF8, 0, src, -1, out, outLength, - nullptr, nullptr); + return WideCharToMultiByte(CP_UTF8, 0, src, -1, out, outLength, nullptr, + nullptr); } } // namespace std::wstring utf8ToWChar(const char* src) { int len = utf8ToWChar(nullptr, 0, src); - if(len <= 0) { + if (len <= 0) { abort(); } auto buf = make_unique<wchar_t[]>((size_t)len); len = utf8ToWChar(buf.get(), len, src); - if(len <= 0) { + if (len <= 0) { abort(); - } else { + } + else { return buf.get(); } } @@ -135,19 +136,21 @@ std::wstring utf8ToWChar(const std::string& src) std::string wCharToUtf8(const std::wstring& wsrc) { int len = wCharToUtf8(nullptr, 0, wsrc.c_str()); - if(len <= 0) { + if (len <= 0) { abort(); } auto buf = make_unique<char[]>((size_t)len); len = wCharToUtf8(buf.get(), len, wsrc.c_str()); - if(len <= 0) { + if (len <= 0) { abort(); - } else { + } + else { return buf.get(); } } -std::string toForwardSlash(const std::string &src) { +std::string toForwardSlash(const std::string& src) +{ auto dst = src; std::transform(std::begin(dst), std::end(dst), std::begin(dst), [](char c) { return c == '\\' ? '/' : c; }); @@ -162,9 +165,8 @@ const char DEFAULT_STRIP_CHARSET[] = "\r\n\t "; std::string strip(const std::string& str, const char* chars) { - std::pair<std::string::const_iterator, - std::string::const_iterator> p = - stripIter(str.begin(), str.end(), chars); + std::pair<std::string::const_iterator, std::string::const_iterator> p = + stripIter(str.begin(), str.end(), chars); return std::string(p.first, p.second); } @@ -172,11 +174,12 @@ std::string itos(int64_t value, bool comma) { bool flag = false; std::string str; - if(value < 0) { - if(value == INT64_MIN) { - if(comma) { + if (value < 0) { + if (value == INT64_MIN) { + if (comma) { str = "-9,223,372,036,854,775,808"; - } else { + } + else { str = "-9223372036854775808"; } return str; @@ -185,42 +188,46 @@ std::string itos(int64_t value, bool comma) value = -value; } str = uitos(value, comma); - if(flag) { + if (flag) { str.insert(str.begin(), '-'); } return str; } -int64_t difftv(struct timeval tv1, struct timeval tv2) { - if((tv1.tv_sec < tv2.tv_sec) || - ((tv1.tv_sec == tv2.tv_sec) && (tv1.tv_usec < tv2.tv_usec))) { +int64_t difftv(struct timeval tv1, struct timeval tv2) +{ + if ((tv1.tv_sec < tv2.tv_sec) || + ((tv1.tv_sec == tv2.tv_sec) && (tv1.tv_usec < tv2.tv_usec))) { return 0; } - return ((int64_t)(tv1.tv_sec-tv2.tv_sec)*1000000+ - tv1.tv_usec-tv2.tv_usec); + return ((int64_t)(tv1.tv_sec - tv2.tv_sec) * 1000000 + tv1.tv_usec - + tv2.tv_usec); } -int32_t difftvsec(struct timeval tv1, struct timeval tv2) { - if(tv1.tv_sec < tv2.tv_sec) { +int32_t difftvsec(struct timeval tv1, struct timeval tv2) +{ + if (tv1.tv_sec < tv2.tv_sec) { return 0; } - return tv1.tv_sec-tv2.tv_sec; + return tv1.tv_sec - tv2.tv_sec; } -std::string replace(const std::string& target, const std::string& oldstr, const std::string& newstr) { - if(target.empty() || oldstr.empty()) { +std::string replace(const std::string& target, const std::string& oldstr, + const std::string& newstr) +{ + if (target.empty() || oldstr.empty()) { return target; } std::string result; std::string::size_type p = 0; std::string::size_type np = target.find(oldstr); - while(np != std::string::npos) { - result.append(target.begin()+p, target.begin()+np); + while (np != std::string::npos) { + result.append(target.begin() + p, target.begin() + np); result += newstr; - p = np+oldstr.size(); + p = np + oldstr.size(); np = target.find(oldstr, p); } - result.append(target.begin()+p, target.end()); + result.append(target.begin() + p, target.end()); return result; } @@ -229,10 +236,7 @@ bool isAlpha(const char c) return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'); } -bool isDigit(const char c) -{ - return '0' <= c && c <= '9'; -} +bool isDigit(const char c) { return '0' <= c && c <= '9'; } bool isHexDigit(const char c) { @@ -242,7 +246,7 @@ bool isHexDigit(const char c) bool isHexDigit(const std::string& s) { for (const auto& c : s) { - if(!isHexDigit(c)) { + if (!isHexDigit(c)) { return false; } } @@ -251,41 +255,34 @@ bool isHexDigit(const std::string& s) bool inRFC3986ReservedChars(const char c) { - static const char reserved[] = { - ':' , '/' , '?' , '#' , '[' , ']' , '@', - '!' , '$' , '&' , '\'' , '(' , ')', - '*' , '+' , ',' , ';' , '=' }; - return std::find(std::begin(reserved), std::end(reserved), c) - != std::end(reserved); + static const char reserved[] = {':', '/', '?', '#', '[', ']', '@', '!', '$', + '&', '\'', '(', ')', '*', '+', ',', ';', '='}; + return std::find(std::begin(reserved), std::end(reserved), c) != + std::end(reserved); } bool inRFC3986UnreservedChars(const char c) { - static const char unreserved[] = { '-', '.', '_', '~' }; + static const char unreserved[] = {'-', '.', '_', '~'}; return isAlpha(c) || isDigit(c) || - std::find(std::begin(unreserved), std::end(unreserved), c) - != std::end(unreserved); + std::find(std::begin(unreserved), std::end(unreserved), c) != + std::end(unreserved); } bool inRFC2978MIMECharset(const char c) { - static const char chars[] = { - '!', '#', '$', '%', '&', - '\'', '+', '-', '^', '_', - '`', '{', '}', '~' - }; + static const char chars[] = {'!', '#', '$', '%', '&', '\'', '+', + '-', '^', '_', '`', '{', '}', '~'}; return isAlpha(c) || isDigit(c) || - std::find(std::begin(chars), std::end(chars), c) != std::end(chars); + std::find(std::begin(chars), std::end(chars), c) != std::end(chars); } bool inRFC2616HttpToken(const char c) { - static const char chars[] = { - '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', - '^', '_', '`', '|', '~' - }; + static const char chars[] = {'!', '#', '$', '%', '&', '\'', '*', '+', + '-', '.', '^', '_', '`', '|', '~'}; return isAlpha(c) || isDigit(c) || - std::find(std::begin(chars), std::end(chars), c) != std::end(chars); + std::find(std::begin(chars), std::end(chars), c) != std::end(chars); } bool inRFC5987AttrChar(const char c) @@ -299,90 +296,84 @@ bool isIso8859p1(unsigned char c) return (0x20u <= c && c <= 0x7eu) || 0xa0u <= c; } -bool isLws(const char c) -{ - return c == ' ' || c == '\t'; -} -bool isCRLF(const char c) -{ - return c == '\r' || c == '\n'; -} +bool isLws(const char c) { return c == ' ' || c == '\t'; } +bool isCRLF(const char c) { return c == '\r' || c == '\n'; } namespace { -bool isUtf8Tail(unsigned char ch) -{ - return in(ch, 0x80u, 0xbfu); -} +bool isUtf8Tail(unsigned char ch) { return in(ch, 0x80u, 0xbfu); } bool inPercentEncodeMini(const unsigned char c) { return c > 0x20 && c < 0x7fu && - // Chromium escapes following characters. Firefox4 escapes more. - c != '"' && c != '<' && c != '>'; + // Chromium escapes following characters. Firefox4 escapes more. + c != '"' && c != '<' && c != '>'; } } // namespace bool isUtf8(const std::string& str) { - for(std::string::const_iterator s = str.begin(), eos = str.end(); s != eos; - ++s) { + for (std::string::const_iterator s = str.begin(), eos = str.end(); s != eos; + ++s) { unsigned char firstChar = *s; // See ABNF in http://tools.ietf.org/search/rfc3629#section-4 - if(in(firstChar, 0x20u, 0x7eu) || - firstChar == 0x08u || // \b - firstChar == 0x09u || // \t - firstChar == 0x0au || // \n - firstChar == 0x0cu || // \f - firstChar == 0x0du // \r - ) { + if (in(firstChar, 0x20u, 0x7eu) || firstChar == 0x08u || // \b + firstChar == 0x09u || // \t + firstChar == 0x0au || // \n + firstChar == 0x0cu || // \f + firstChar == 0x0du // \r + ) { // UTF8-1 (without ctrl chars) - } else if(in(firstChar, 0xc2u, 0xdfu)) { + } + else if (in(firstChar, 0xc2u, 0xdfu)) { // UTF8-2 - if(++s == eos || !isUtf8Tail(*s)) { + if (++s == eos || !isUtf8Tail(*s)) { return false; } - } else if(0xe0u == firstChar) { + } + else if (0xe0u == firstChar) { // UTF8-3 - if(++s == eos || !in(static_cast<unsigned char>(*s), 0xa0u, 0xbfu) || - ++s == eos || !isUtf8Tail(*s)) { + if (++s == eos || !in(static_cast<unsigned char>(*s), 0xa0u, 0xbfu) || + ++s == eos || !isUtf8Tail(*s)) { return false; } - } else if(in(firstChar, 0xe1u, 0xecu) || in(firstChar, 0xeeu, 0xefu)) { + } + else if (in(firstChar, 0xe1u, 0xecu) || in(firstChar, 0xeeu, 0xefu)) { // UTF8-3 - if(++s == eos || !isUtf8Tail(*s) || - ++s == eos || !isUtf8Tail(*s)) { + if (++s == eos || !isUtf8Tail(*s) || ++s == eos || !isUtf8Tail(*s)) { return false; } - } else if(0xedu == firstChar) { + } + else if (0xedu == firstChar) { // UTF8-3 - if(++s == eos || !in(static_cast<unsigned char>(*s), 0x80u, 0x9fu) || - ++s == eos || !isUtf8Tail(*s)) { + if (++s == eos || !in(static_cast<unsigned char>(*s), 0x80u, 0x9fu) || + ++s == eos || !isUtf8Tail(*s)) { return false; } - } else if(0xf0u == firstChar) { + } + else if (0xf0u == firstChar) { // UTF8-4 - if(++s == eos || !in(static_cast<unsigned char>(*s), 0x90u, 0xbfu) || - ++s == eos || !isUtf8Tail(*s) || - ++s == eos || !isUtf8Tail(*s)) { + if (++s == eos || !in(static_cast<unsigned char>(*s), 0x90u, 0xbfu) || + ++s == eos || !isUtf8Tail(*s) || ++s == eos || !isUtf8Tail(*s)) { return false; } - } else if(in(firstChar, 0xf1u, 0xf3u)) { + } + else if (in(firstChar, 0xf1u, 0xf3u)) { // UTF8-4 - if(++s == eos || !isUtf8Tail(*s) || - ++s == eos || !isUtf8Tail(*s) || - ++s == eos || !isUtf8Tail(*s)) { + if (++s == eos || !isUtf8Tail(*s) || ++s == eos || !isUtf8Tail(*s) || + ++s == eos || !isUtf8Tail(*s)) { return false; } - } else if(0xf4u == firstChar) { + } + else if (0xf4u == firstChar) { // UTF8-4 - if(++s == eos || !in(static_cast<unsigned char>(*s), 0x80u, 0x8fu) || - ++s == eos || !isUtf8Tail(*s) || - ++s == eos || !isUtf8Tail(*s)) { + if (++s == eos || !in(static_cast<unsigned char>(*s), 0x80u, 0x8fu) || + ++s == eos || !isUtf8Tail(*s) || ++s == eos || !isUtf8Tail(*s)) { return false; } - } else { + } + else { return false; } } @@ -392,10 +383,11 @@ bool isUtf8(const std::string& str) std::string percentEncode(const unsigned char* target, size_t len) { std::string dest; - for(size_t i = 0; i < len; ++i) { - if(inRFC3986UnreservedChars(target[i])) { + for (size_t i = 0; i < len; ++i) { + if (inRFC3986UnreservedChars(target[i])) { dest += target[i]; - } else { + } + else { dest.append(fmt("%%%02X", target[i])); } } @@ -419,22 +411,25 @@ std::string percentEncodeMini(const std::string& src) return src; } std::string result; - for (auto c: src) { - if(!inPercentEncodeMini(c)) { + for (auto c : src) { + if (!inPercentEncodeMini(c)) { result += fmt("%%%02X", static_cast<unsigned char>(c)); - } else { + } + else { result += c; } } return result; } -std::string torrentPercentEncode(const unsigned char* target, size_t len) { +std::string torrentPercentEncode(const unsigned char* target, size_t len) +{ std::string dest; - for(size_t i = 0; i < len; ++i) { - if(isAlpha(target[i]) || isDigit(target[i])) { + for (size_t i = 0; i < len; ++i) { + if (isAlpha(target[i]) || isDigit(target[i])) { dest += target[i]; - } else { + } + else { dest.append(fmt("%%%02X", target[i])); } } @@ -443,42 +438,47 @@ std::string torrentPercentEncode(const unsigned char* target, size_t len) { std::string torrentPercentEncode(const std::string& target) { - return torrentPercentEncode - (reinterpret_cast<const unsigned char*>(target.c_str()), target.size()); + return torrentPercentEncode( + reinterpret_cast<const unsigned char*>(target.c_str()), target.size()); } -std::string percentDecode -(std::string::const_iterator first, std::string::const_iterator last) +std::string percentDecode(std::string::const_iterator first, + std::string::const_iterator last) { std::string result; - for(; first != last; ++first) { - if(*first == '%') { - if(first+1 != last && first+2 != last && - isHexDigit(*(first+1)) && isHexDigit(*(first+2))) { - result += hexCharToUInt(*(first+1))*16+hexCharToUInt(*(first+2)); + for (; first != last; ++first) { + if (*first == '%') { + if (first + 1 != last && first + 2 != last && isHexDigit(*(first + 1)) && + isHexDigit(*(first + 2))) { + result += + hexCharToUInt(*(first + 1)) * 16 + hexCharToUInt(*(first + 2)); first += 2; - } else { + } + else { result += *first; } - } else { + } + else { result += *first; } } return result; } -std::string toHex(const unsigned char* src, size_t len) { - std::string out(len*2, '\0'); +std::string toHex(const unsigned char* src, size_t len) +{ + std::string out(len * 2, '\0'); std::string::iterator o = out.begin(); - const unsigned char* last = src+len; - for(const unsigned char* i = src; i != last; ++i) { + const unsigned char* last = src + len; + for (const unsigned char* i = src; i != last; ++i) { *o = (*i >> 4); - *(o+1) = (*i)&0x0fu; - for(int j = 0; j < 2; ++j) { - if(*o < 10) { + *(o + 1) = (*i) & 0x0fu; + for (int j = 0; j < 2; ++j) { + if (*o < 10) { *o += '0'; - } else { - *o += 'a'-10; + } + else { + *o += 'a' - 10; } ++o; } @@ -498,53 +498,57 @@ std::string toHex(const std::string& src) unsigned int hexCharToUInt(unsigned char ch) { - if('a' <= ch && ch <= 'f') { + if ('a' <= ch && ch <= 'f') { ch -= 'a'; ch += 10; - } else if('A' <= ch && ch <= 'F') { + } + else if ('A' <= ch && ch <= 'F') { ch -= 'A'; ch += 10; - } else if('0' <= ch && ch <= '9') { + } + else if ('0' <= ch && ch <= '9') { ch -= '0'; - } else { + } + else { ch = 255; } return ch; } -std::string secfmt(time_t sec) { +std::string secfmt(time_t sec) +{ time_t tsec = sec; std::string str; - if(sec >= 3600) { - str = fmt("%" PRId64 "h", static_cast<int64_t>(sec/3600)); + if (sec >= 3600) { + str = fmt("%" PRId64 "h", static_cast<int64_t>(sec / 3600)); sec %= 3600; } - if(sec >= 60) { - str += fmt("%dm", static_cast<int>(sec/60)); + if (sec >= 60) { + str += fmt("%dm", static_cast<int>(sec / 60)); sec %= 60; } - if(sec || tsec == 0) { + if (sec || tsec == 0) { str += fmt("%ds", static_cast<int>(sec)); } return str; } namespace { -template<typename T, typename F> +template <typename T, typename F> bool parseLong(T& res, F f, const std::string& s, int base) { - if(s.empty()) { + if (s.empty()) { return false; } char* endptr; errno = 0; res = f(s.c_str(), &endptr, base); - if(errno == ERANGE) { + if (errno == ERANGE) { return false; } - if(*endptr != '\0') { - for(const char* i = endptr, *eoi = s.c_str()+s.size(); i < eoi; ++i) { - if(!isspace(*i)) { + if (*endptr != '\0') { + for (const char* i = endptr, * eoi = s.c_str() + s.size(); i < eoi; ++i) { + if (!isspace(*i)) { return false; } } @@ -556,12 +560,13 @@ bool parseLong(T& res, F f, const std::string& s, int base) bool parseIntNoThrow(int32_t& res, const std::string& s, int base) { long int t; - if(parseLong(t, strtol, s, base) && - t >= std::numeric_limits<int32_t>::min() && - t <= std::numeric_limits<int32_t>::max()) { + if (parseLong(t, strtol, s, base) && + t >= std::numeric_limits<int32_t>::min() && + t <= std::numeric_limits<int32_t>::max()) { res = t; return true; - } else { + } + else { return false; } } @@ -569,12 +574,12 @@ bool parseIntNoThrow(int32_t& res, const std::string& s, int base) bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base) { long int t; - if(parseLong(t, strtol, s, base) && - t >= 0 && - t <= std::numeric_limits<int32_t>::max()) { + if (parseLong(t, strtol, s, base) && t >= 0 && + t <= std::numeric_limits<int32_t>::max()) { res = t; return true; - } else { + } + else { return false; } } @@ -582,12 +587,13 @@ bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base) bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base) { long long int t; - if(parseLong(t, strtoll, s, base) && - t >= std::numeric_limits<int64_t>::min() && - t <= std::numeric_limits<int64_t>::max()) { + if (parseLong(t, strtoll, s, base) && + t >= std::numeric_limits<int64_t>::min() && + t <= std::numeric_limits<int64_t>::max()) { res = t; return true; - } else { + } + else { return false; } } @@ -595,57 +601,60 @@ bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base) SegList<int> parseIntSegments(const std::string& src) { SegList<int> sgl; - for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi;) { + for (std::string::const_iterator i = src.begin(), eoi = src.end(); + i != eoi;) { std::string::const_iterator j = std::find(i, eoi, ','); - if(j == i) { + if (j == i) { ++i; continue; } std::string::const_iterator p = std::find(i, j, '-'); - if(p == j) { + if (p == j) { int a; - if(parseIntNoThrow(a, std::string(i, j))) { - sgl.add(a, a+1); - } else { + if (parseIntNoThrow(a, std::string(i, j))) { + sgl.add(a, a + 1); + } + else { throw DL_ABORT_EX(fmt("Bad range %s", std::string(i, j).c_str())); } - } else if(p == i || p+1 == j) { + } + else if (p == i || p + 1 == j) { throw DL_ABORT_EX(fmt(MSG_INCOMPLETE_RANGE, std::string(i, j).c_str())); - } else { + } + else { int a, b; - if(parseIntNoThrow(a, std::string(i, p)) && - parseIntNoThrow(b, (std::string(p+1, j)))) { - sgl.add(a, b+1); - } else { + if (parseIntNoThrow(a, std::string(i, p)) && + parseIntNoThrow(b, (std::string(p + 1, j)))) { + sgl.add(a, b + 1); + } + else { throw DL_ABORT_EX(fmt("Bad range %s", std::string(i, j).c_str())); } } - if(j == eoi) { + if (j == eoi) { break; } - i = j+1; + i = j + 1; } return sgl; } namespace { -void computeHeadPieces -(std::vector<size_t>& indexes, - const std::vector<std::shared_ptr<FileEntry> >& fileEntries, - size_t pieceLength, - int64_t head) +void computeHeadPieces( + std::vector<size_t>& indexes, + const std::vector<std::shared_ptr<FileEntry>>& fileEntries, + size_t pieceLength, int64_t head) { - if(head == 0) { + if (head == 0) { return; } - for (const auto& fi: fileEntries) { - if(fi->getLength() == 0) { + for (const auto& fi : fileEntries) { + if (fi->getLength() == 0) { continue; } - const size_t lastIndex = (fi->getOffset() + - std::min(head, fi->getLength()) - 1 - ) / pieceLength; - for(size_t idx = fi->getOffset() / pieceLength; idx <= lastIndex; ++idx) { + const size_t lastIndex = + (fi->getOffset() + std::min(head, fi->getLength()) - 1) / pieceLength; + for (size_t idx = fi->getOffset() / pieceLength; idx <= lastIndex; ++idx) { indexes.push_back(idx); } } @@ -653,22 +662,21 @@ void computeHeadPieces } // namespace namespace { -void computeTailPieces -(std::vector<size_t>& indexes, - const std::vector<std::shared_ptr<FileEntry> >& fileEntries, - size_t pieceLength, - int64_t tail) +void computeTailPieces( + std::vector<size_t>& indexes, + const std::vector<std::shared_ptr<FileEntry>>& fileEntries, + size_t pieceLength, int64_t tail) { - if(tail == 0) { + if (tail == 0) { return; } - for (const auto& fi: fileEntries) { - if(fi->getLength() == 0) { + for (const auto& fi : fileEntries) { + if (fi->getLength() == 0) { continue; } int64_t endOffset = fi->getLastOffset(); - size_t fromIndex = (endOffset - 1 - (std::min(tail, fi->getLength()) - 1)) / - pieceLength; + size_t fromIndex = + (endOffset - 1 - (std::min(tail, fi->getLength()) - 1)) / pieceLength; const size_t toIndex = (endOffset - 1) / pieceLength; while (fromIndex <= toIndex) { indexes.push_back(fromIndex++); @@ -677,35 +685,34 @@ void computeTailPieces } } // namespace -void parsePrioritizePieceRange -(std::vector<size_t>& result, const std::string& src, - const std::vector<std::shared_ptr<FileEntry> >& fileEntries, - size_t pieceLength, - int64_t defaultSize) +void parsePrioritizePieceRange( + std::vector<size_t>& result, const std::string& src, + const std::vector<std::shared_ptr<FileEntry>>& fileEntries, + size_t pieceLength, int64_t defaultSize) { std::vector<size_t> indexes; std::vector<Scip> parts; splitIter(src.begin(), src.end(), std::back_inserter(parts), ',', true); - for (const auto& i: parts) { - if(util::streq(i.first, i.second, "head")) { + for (const auto& i : parts) { + if (util::streq(i.first, i.second, "head")) { computeHeadPieces(indexes, fileEntries, pieceLength, defaultSize); } - else if(util::startsWith(i.first, i.second, "head=")) { + else if (util::startsWith(i.first, i.second, "head=")) { std::string sizestr(i.first + 5, i.second); computeHeadPieces(indexes, fileEntries, pieceLength, std::max((int64_t)0, getRealSize(sizestr))); } - else if(util::streq(i.first, i.second, "tail")) { + else if (util::streq(i.first, i.second, "tail")) { computeTailPieces(indexes, fileEntries, pieceLength, defaultSize); } - else if(util::startsWith(i.first, i.second, "tail=")) { + else if (util::startsWith(i.first, i.second, "tail=")) { std::string sizestr(i.first + 5, i.second); computeTailPieces(indexes, fileEntries, pieceLength, std::max((int64_t)0, getRealSize(sizestr))); } else { - throw DL_ABORT_EX(fmt("Unrecognized token %s", - std::string(i.first, i.second).c_str())); + throw DL_ABORT_EX( + fmt("Unrecognized token %s", std::string(i.first, i.second).c_str())); } } std::sort(indexes.begin(), indexes.end()); @@ -718,18 +725,21 @@ void parsePrioritizePieceRange std::string iso8859p1ToUtf8(const char* src, size_t len) { std::string dest; - for(const char* p = src, *last = src+len; p != last; ++p) { + for (const char* p = src, * last = src + len; p != last; ++p) { unsigned char c = *p; - if(0xa0u <= c) { - if(c <= 0xbfu) { + if (0xa0u <= c) { + if (c <= 0xbfu) { dest += 0xc2u; - } else { + } + else { dest += 0xc3u; } - dest += c&(~0x40u); - } else if(0x80u <= c && c <= 0x9fu) { + dest += c & (~0x40u); + } + else if (0x80u <= c && c <= 0x9fu) { return ""; - } else { + } + else { dest += c; } } @@ -771,37 +781,43 @@ std::string iso8859p1ToUtf8(const std::string& src) #define UTF8_REJECT 12 static const uint8_t utf8d[] = { - /* - * The first part of the table maps bytes to character classes that - * to reduce the size of the transition table and create bitmasks. - */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, - 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, - - /* - * The second part is a transition table that maps a combination - * of a state of the automaton and a character class to a state. - */ - 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, - 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, - 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, - 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, - 12,36,12,12,12,12,12,12,12,12,12,12, + /* + * The first part of the table maps bytes to character classes that + * to reduce the size of the transition table and create bitmasks. + */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 11, 6, 6, 6, 5, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, + + /* + * The second part is a transition table that maps a combination + * of a state of the automaton and a character class to a state. + */ + 0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, + 12, 12, 12, 12, 12, 24, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 24, 12, + 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 36, 12, 36, 12, + 12, 12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, }; -static uint32_t -utf8dfa(uint32_t* state, uint32_t* codep, uint32_t byte) { +static uint32_t utf8dfa(uint32_t* state, uint32_t* codep, uint32_t byte) +{ uint32_t type = utf8d[byte]; - *codep = (*state != UTF8_ACCEPT) ? - (byte & 0x3fu) | (*codep << 6) : - (0xff >> type) & (byte); + *codep = (*state != UTF8_ACCEPT) ? (byte & 0x3fu) | (*codep << 6) + : (0xff >> type) & (byte); *state = utf8d[256 + *state + type]; return *state; @@ -839,18 +855,19 @@ typedef enum { CD_ENC_ISO_8859_1 } content_disposition_charset; -ssize_t parse_content_disposition(char *dest, size_t destlen, - const char **charsetp, size_t *charsetlenp, - const char *in, size_t len) +ssize_t parse_content_disposition(char* dest, size_t destlen, + const char** charsetp, size_t* charsetlenp, + const char* in, size_t len) { - const char *p = in, *eop = in + len, *mark_first = nullptr, *mark_last = nullptr; + const char* p = in, * eop = in + len, * mark_first = nullptr, + * mark_last = nullptr; int state = CD_BEFORE_DISPOSITION_TYPE; int in_file_parm = 0; int flags = 0; int quoted_seen = 0; int charset = 0; /* To suppress warnings */ - char *dp = dest; + char* dp = dest; size_t dlen = destlen; uint32_t dfa_state = 0; uint32_t dfa_code = 0; @@ -859,120 +876,136 @@ ssize_t parse_content_disposition(char *dest, size_t destlen, *charsetp = nullptr; *charsetlenp = 0; - for(; p != eop; ++p) { - switch(state) { + for (; p != eop; ++p) { + switch (state) { case CD_BEFORE_DISPOSITION_TYPE: - if(inRFC2616HttpToken(*p)) { + if (inRFC2616HttpToken(*p)) { state = CD_DISPOSITION_TYPE; - } else if(!isLws(*p)) { + } + else if (!isLws(*p)) { return -1; } break; case CD_AFTER_DISPOSITION_TYPE: case CD_DISPOSITION_TYPE: - if(*p == ';') { + if (*p == ';') { state = CD_BEFORE_DISPOSITION_PARM_NAME; - } else if(isLws(*p)) { + } + else if (isLws(*p)) { state = CD_AFTER_DISPOSITION_TYPE; - } else if(state == CD_AFTER_DISPOSITION_TYPE || - !inRFC2616HttpToken(*p)) { + } + else if (state == CD_AFTER_DISPOSITION_TYPE || !inRFC2616HttpToken(*p)) { return -1; } break; case CD_BEFORE_DISPOSITION_PARM_NAME: - if(inRFC2616HttpToken(*p)) { + if (inRFC2616HttpToken(*p)) { mark_first = p; state = CD_DISPOSITION_PARM_NAME; - } else if(!isLws(*p)) { + } + else if (!isLws(*p)) { return -1; } break; case CD_AFTER_DISPOSITION_PARM_NAME: case CD_DISPOSITION_PARM_NAME: - if(*p == '=') { - if(state == CD_DISPOSITION_PARM_NAME) { + if (*p == '=') { + if (state == CD_DISPOSITION_PARM_NAME) { mark_last = p; } in_file_parm = 0; - if(strieq(mark_first, mark_last, "filename*")) { - if((flags & CD_EXT_FILENAME_FOUND) == 0) { + if (strieq(mark_first, mark_last, "filename*")) { + if ((flags & CD_EXT_FILENAME_FOUND) == 0) { in_file_parm = 1; - } else { + } + else { return -1; } state = CD_BEFORE_EXT_VALUE; - } else if(strieq(mark_first, mark_last, "filename")) { - if(flags & CD_FILENAME_FOUND) { + } + else if (strieq(mark_first, mark_last, "filename")) { + if (flags & CD_FILENAME_FOUND) { return -1; } - if((flags & CD_EXT_FILENAME_FOUND) == 0) { + if ((flags & CD_EXT_FILENAME_FOUND) == 0) { in_file_parm = 1; } state = CD_BEFORE_VALUE; - } else { + } + else { /* ext-token must be characters in token, followed by "*" */ - if(mark_first != mark_last-1 && *(mark_last-1) == '*') { + if (mark_first != mark_last - 1 && *(mark_last - 1) == '*') { state = CD_BEFORE_EXT_VALUE; - } else { + } + else { state = CD_BEFORE_VALUE; } } - if(in_file_parm) { + if (in_file_parm) { dp = dest; dlen = destlen; } - } else if(isLws(*p)) { + } + else if (isLws(*p)) { mark_last = p; state = CD_AFTER_DISPOSITION_PARM_NAME; - } else if(state == CD_AFTER_DISPOSITION_PARM_NAME || - !inRFC2616HttpToken(*p)) { + } + else if (state == CD_AFTER_DISPOSITION_PARM_NAME || + !inRFC2616HttpToken(*p)) { return -1; } break; case CD_BEFORE_VALUE: - if(*p == '"') { + if (*p == '"') { quoted_seen = 0; state = CD_QUOTED_STRING; - } else if(inRFC2616HttpToken(*p)) { - if(in_file_parm) { - if(dlen == 0) { + } + else if (inRFC2616HttpToken(*p)) { + if (in_file_parm) { + if (dlen == 0) { return -1; - } else { + } + else { *dp++ = *p; --dlen; } } state = CD_TOKEN; - } else if(!isLws(*p)) { + } + else if (!isLws(*p)) { return -1; } break; case CD_AFTER_VALUE: - if(*p == ';') { + if (*p == ';') { state = CD_BEFORE_DISPOSITION_PARM_NAME; - } else if(!isLws(*p)) { + } + else if (!isLws(*p)) { return -1; } break; case CD_QUOTED_STRING: - if(*p == '\\' && quoted_seen == 0) { + if (*p == '\\' && quoted_seen == 0) { quoted_seen = 1; - } else if(*p == '"' && quoted_seen == 0) { - if(in_file_parm) { + } + else if (*p == '"' && quoted_seen == 0) { + if (in_file_parm) { flags |= CD_FILENAME_FOUND; } state = CD_AFTER_VALUE; - } else { + } + else { /* TEXT which is OCTET except CTLs, but including LWS. We only accept ISO-8859-1 chars. */ quoted_seen = 0; - if(!isIso8859p1(*p)) { + if (!isIso8859p1(*p)) { return -1; } - if(in_file_parm) { - if(dlen == 0) { + if (in_file_parm) { + if (dlen == 0) { return -1; - } else { + } + else { *dp++ = *p; --dlen; } @@ -980,149 +1013,167 @@ ssize_t parse_content_disposition(char *dest, size_t destlen, } break; case CD_TOKEN: - if(inRFC2616HttpToken(*p)) { - if(in_file_parm) { - if(dlen == 0) { + if (inRFC2616HttpToken(*p)) { + if (in_file_parm) { + if (dlen == 0) { return -1; - } else { + } + else { *dp++ = *p; --dlen; } } - } else if(*p == ';') { - if(in_file_parm) { + } + else if (*p == ';') { + if (in_file_parm) { flags |= CD_FILENAME_FOUND; } state = CD_BEFORE_DISPOSITION_PARM_NAME; - } else if(isLws(*p)) { - if(in_file_parm) { + } + else if (isLws(*p)) { + if (in_file_parm) { flags |= CD_FILENAME_FOUND; } state = CD_AFTER_VALUE; - } else { + } + else { return -1; } break; case CD_BEFORE_EXT_VALUE: - if(*p == '\'') { + if (*p == '\'') { /* Empty charset is not allowed */ return -1; - } else if(inRFC2978MIMECharset(*p)) { + } + else if (inRFC2978MIMECharset(*p)) { mark_first = p; state = CD_CHARSET; - } else if(!isLws(*p)) { + } + else if (!isLws(*p)) { return -1; } break; case CD_CHARSET: - if(*p == '\'') { + if (*p == '\'') { mark_last = p; *charsetp = mark_first; *charsetlenp = mark_last - mark_first; - if(strieq(mark_first, mark_last, "utf-8")) { + if (strieq(mark_first, mark_last, "utf-8")) { charset = CD_ENC_UTF8; dfa_state = UTF8_ACCEPT; dfa_code = 0; - } else if(strieq(mark_first, mark_last, "iso-8859-1")) { + } + else if (strieq(mark_first, mark_last, "iso-8859-1")) { charset = CD_ENC_ISO_8859_1; - } else { + } + else { charset = CD_ENC_UNKNOWN; } state = CD_LANGUAGE; - } else if(!inRFC2978MIMECharset(*p)) { + } + else if (!inRFC2978MIMECharset(*p)) { return -1; } break; case CD_LANGUAGE: - if(*p == '\'') { - if(in_file_parm) { + if (*p == '\'') { + if (in_file_parm) { dp = dest; dlen = destlen; } state = CD_VALUE_CHARS; - } else if(*p != '-' && !isAlpha(*p) && !isDigit(*p)) { + } + else if (*p != '-' && !isAlpha(*p) && !isDigit(*p)) { return -1; } break; case CD_VALUE_CHARS: - if(inRFC5987AttrChar(*p)) { - if(charset == CD_ENC_UTF8) { - if(utf8dfa(&dfa_state, &dfa_code, *p) == UTF8_REJECT) { + if (inRFC5987AttrChar(*p)) { + if (charset == CD_ENC_UTF8) { + if (utf8dfa(&dfa_state, &dfa_code, *p) == UTF8_REJECT) { return -1; } } - if(in_file_parm) { - if(dlen == 0) { + if (in_file_parm) { + if (dlen == 0) { return -1; - } else { + } + else { *dp++ = *p; --dlen; } } - } else if(*p == '%') { - if(in_file_parm) { - if(dlen == 0) { + } + else if (*p == '%') { + if (in_file_parm) { + if (dlen == 0) { return -1; } } pctval = 0; state = CD_VALUE_CHARS_PCT_ENCODED1; - } else if(*p == ';' || isLws(*p)) { - if(charset == CD_ENC_UTF8 && dfa_state != UTF8_ACCEPT) { + } + else if (*p == ';' || isLws(*p)) { + if (charset == CD_ENC_UTF8 && dfa_state != UTF8_ACCEPT) { return -1; } - if(in_file_parm) { + if (in_file_parm) { flags |= CD_EXT_FILENAME_FOUND; } - if(*p == ';') { + if (*p == ';') { state = CD_BEFORE_DISPOSITION_PARM_NAME; - } else { + } + else { state = CD_AFTER_VALUE; } - } else if(!inRFC5987AttrChar(*p)) { + } + else if (!inRFC5987AttrChar(*p)) { return -1; } break; case CD_VALUE_CHARS_PCT_ENCODED1: - if(isHexDigit(*p)) { + if (isHexDigit(*p)) { pctval |= hexCharToUInt(*p) << 4; state = CD_VALUE_CHARS_PCT_ENCODED2; - } else { + } + else { return -1; } break; case CD_VALUE_CHARS_PCT_ENCODED2: - if(isHexDigit(*p)) { + if (isHexDigit(*p)) { pctval |= hexCharToUInt(*p); - if(charset == CD_ENC_UTF8) { - if(utf8dfa(&dfa_state, &dfa_code, pctval) == UTF8_REJECT) { + if (charset == CD_ENC_UTF8) { + if (utf8dfa(&dfa_state, &dfa_code, pctval) == UTF8_REJECT) { return -1; } - } else if(charset == CD_ENC_ISO_8859_1) { - if(!isIso8859p1(pctval)) { + } + else if (charset == CD_ENC_ISO_8859_1) { + if (!isIso8859p1(pctval)) { return -1; } } - if(in_file_parm) { + if (in_file_parm) { *dp++ = pctval; --dlen; } state = CD_VALUE_CHARS; - } else { + } + else { return -1; } break; } } - switch(state) { + switch (state) { case CD_BEFORE_DISPOSITION_TYPE: case CD_AFTER_DISPOSITION_TYPE: case CD_DISPOSITION_TYPE: case CD_AFTER_VALUE: case CD_TOKEN: - return destlen-dlen; + return destlen - dlen; case CD_VALUE_CHARS: - if(charset == CD_ENC_UTF8 && dfa_state != UTF8_ACCEPT) { + if (charset == CD_ENC_UTF8 && dfa_state != UTF8_ACCEPT) { return -1; } return destlen - dlen; @@ -1137,20 +1188,21 @@ std::string getContentDispositionFilename(const std::string& header) size_t cdvallen = cdval.size(); const char* charset; size_t charsetlen; - ssize_t rv = parse_content_disposition(cdval.data(), cdvallen, - &charset, &charsetlen, - header.c_str(), header.size()); - if(rv == -1) { + ssize_t rv = + parse_content_disposition(cdval.data(), cdvallen, &charset, &charsetlen, + header.c_str(), header.size()); + if (rv == -1) { return ""; } std::string res; - if(!charset || strieq(charset, charset+charsetlen, "iso-8859-1")) { + if (!charset || strieq(charset, charset + charsetlen, "iso-8859-1")) { res = iso8859p1ToUtf8(cdval.data(), rv); - } else { + } + else { res.assign(cdval.data(), rv); } - if(!detectDirTraversal(res) && + if (!detectDirTraversal(res) && res.find_first_of("/\\") == std::string::npos) { return res; } @@ -1163,7 +1215,8 @@ std::string toUpper(std::string src) return src; } -std::string toLower(std::string src) { +std::string toLower(std::string src) +{ lowercase(src); return src; } @@ -1180,16 +1233,16 @@ void lowercase(std::string& s) char toUpperChar(char c) { - if('a' <= c && c <= 'z') { - c += 'A'-'a'; + if ('a' <= c && c <= 'z') { + c += 'A' - 'a'; } return c; } char toLowerChar(char c) { - if('A' <= c && c <= 'Z') { - c += 'a'-'A'; + if ('A' <= c && c <= 'Z') { + c += 'a' - 'A'; } return c; } @@ -1201,7 +1254,7 @@ bool isNumericHost(const std::string& name) memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_NUMERICHOST; - if(getaddrinfo(name.c_str(), nullptr, &hints, &res)) { + if (getaddrinfo(name.c_str(), nullptr, &hints, &res)) { return false; } freeaddrinfo(res); @@ -1210,52 +1263,52 @@ bool isNumericHost(const std::string& name) #if _WIN32 namespace { - static Lock win_signal_lock; +static Lock win_signal_lock; - static signal_handler_t win_int_handler = nullptr; - static signal_handler_t win_term_handler = nullptr; +static signal_handler_t win_int_handler = nullptr; +static signal_handler_t win_term_handler = nullptr; - static void win_ign_handler(int) {} +static void win_ign_handler(int) {} - static BOOL WINAPI HandlerRoutine(DWORD ctrlType) - { - void(*handler)(int) = nullptr; - switch (ctrlType) { - case CTRL_C_EVENT: - case CTRL_BREAK_EVENT: - { - // Handler will be called on a new/different thread. - LockGuard lg(win_signal_lock); - handler = win_int_handler; - } +static BOOL WINAPI HandlerRoutine(DWORD ctrlType) +{ + void (*handler)(int) = nullptr; + switch (ctrlType) { + case CTRL_C_EVENT: + case CTRL_BREAK_EVENT: { + // Handler will be called on a new/different thread. + LockGuard lg(win_signal_lock); + handler = win_int_handler; + } - if (handler) { - handler(SIGINT); - return TRUE; - } - return FALSE; - - case CTRL_LOGOFF_EVENT: - case CTRL_CLOSE_EVENT: - case CTRL_SHUTDOWN_EVENT: - { - // Handler will be called on a new/different thread. - LockGuard lg(win_signal_lock); - handler = win_term_handler;; - } - if (handler) { - handler(SIGTERM); - return TRUE; - } - return FALSE; + if (handler) { + handler(SIGINT); + return TRUE; } return FALSE; + + case CTRL_LOGOFF_EVENT: + case CTRL_CLOSE_EVENT: + case CTRL_SHUTDOWN_EVENT: { + // Handler will be called on a new/different thread. + LockGuard lg(win_signal_lock); + handler = win_term_handler; + ; } + if (handler) { + handler(SIGTERM); + return TRUE; + } + return FALSE; + } + return FALSE; +} } #endif void setGlobalSignalHandler(int sig, sigset_t* mask, signal_handler_t handler, - int flags) { + int flags) +{ #if _WIN32 if (sig == SIGINT || sig == SIGTERM) { // Handler will be called on a new/different thread. @@ -1312,7 +1365,7 @@ std::string getHomeDir() return A2STR::NIL; } -#else // __MINGW32__ +#else // __MINGW32__ std::string getHomeDir() { @@ -1344,26 +1397,30 @@ std::string getXDGDir(const std::string& environmentVariable, const char* p = getenv(environmentVariable.c_str()); if (p && p[0] == '/') { filename = p; - } else { + } + else { filename = fallbackDirectory; } return filename; } -std::string getConfigFile() { +std::string getConfigFile() +{ std::string filename = getHomeDir() + "/.aria2/aria2.conf"; if (!File(filename).exists()) { - filename = getXDGDir("XDG_CONFIG_HOME", getHomeDir()+"/.config") + - "/aria2/aria2.conf"; + filename = getXDGDir("XDG_CONFIG_HOME", getHomeDir() + "/.config") + + "/aria2/aria2.conf"; } return filename; } -std::string getDHTFile(bool ipv6) { - std::string filename = getHomeDir() + (ipv6 ? "/.aria2/dht6.dat" : "/.aria2/dht.dat"); +std::string getDHTFile(bool ipv6) +{ + std::string filename = + getHomeDir() + (ipv6 ? "/.aria2/dht6.dat" : "/.aria2/dht.dat"); if (!File(filename).exists()) { - filename = getXDGDir("XDG_CACHE_HOME", getHomeDir()+"/.cache") + - (ipv6 ? "/aria2/dht6.dat" : "/aria2/dht.dat"); + filename = getXDGDir("XDG_CACHE_HOME", getHomeDir() + "/.cache") + + (ipv6 ? "/aria2/dht6.dat" : "/aria2/dht.dat"); } return filename; } @@ -1373,10 +1430,11 @@ int64_t getRealSize(const std::string& sizeWithUnit) std::string::size_type p = sizeWithUnit.find_first_of("KMkm"); std::string size; int32_t mult = 1; - if(p == std::string::npos) { + if (p == std::string::npos) { size = sizeWithUnit; - } else { - switch(sizeWithUnit[p]) { + } + else { + switch (sizeWithUnit[p]) { case 'K': case 'k': mult = 1_k; @@ -1386,41 +1444,41 @@ int64_t getRealSize(const std::string& sizeWithUnit) mult = 1_m; break; } - size.assign(sizeWithUnit.begin(), sizeWithUnit.begin()+p); + size.assign(sizeWithUnit.begin(), sizeWithUnit.begin() + p); } int64_t v; - if(!parseLLIntNoThrow(v, size) || v < 0) { - throw DL_ABORT_EX(fmt("Bad or negative value detected: %s", - sizeWithUnit.c_str())); + if (!parseLLIntNoThrow(v, size) || v < 0) { + throw DL_ABORT_EX( + fmt("Bad or negative value detected: %s", sizeWithUnit.c_str())); } - if(INT64_MAX/mult < v) { - throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE, - "overflow/underflow")); + if (INT64_MAX / mult < v) { + throw DL_ABORT_EX( + fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE, "overflow/underflow")); } - return v*mult; + return v * mult; } std::string abbrevSize(int64_t size) { - static const char* UNITS[] = { "", "Ki", "Mi", "Gi" }; + static const char* UNITS[] = {"", "Ki", "Mi", "Gi"}; int64_t t = size; size_t uidx = 0; int r = 0; - while(t >= static_cast<int64_t>(1_k) && - uidx + 1 < sizeof(UNITS) / sizeof(UNITS[0])) { + while (t >= static_cast<int64_t>(1_k) && + uidx + 1 < sizeof(UNITS) / sizeof(UNITS[0])) { lldiv_t d = lldiv(t, 1_k); t = d.quot; r = d.rem; ++uidx; } - if(uidx+1 < sizeof(UNITS)/sizeof(UNITS[0]) && t >= 922) { + if (uidx + 1 < sizeof(UNITS) / sizeof(UNITS[0]) && t >= 922) { ++uidx; r = t; t = 0; } std::string res; res += itos(t, true); - if(t < 10 && uidx > 0) { + if (t < 10 && uidx > 0) { res += "."; res += itos(r * 10 / 1_k); } @@ -1428,7 +1486,8 @@ std::string abbrevSize(int64_t size) return res; } -void sleep(long seconds) { +void sleep(long seconds) +{ #if defined(HAVE_WINSOCK2_H) ::Sleep(seconds * 1000); #elif HAVE_SLEEP @@ -1436,18 +1495,23 @@ void sleep(long seconds) { #elif defined(HAVE_USLEEP) ::usleep(seconds * 1000000); #else -# error no sleep function is available (nanosleep?) +#error no sleep function is available (nanosleep?) #endif } -void usleep(long microseconds) { +void usleep(long microseconds) +{ #ifdef HAVE_USLEEP ::usleep(microseconds); #elif defined(HAVE_WINSOCK2_H) LARGE_INTEGER current, freq, end; - static enum {GET_FREQUENCY, GET_MICROSECONDS, SKIP_MICROSECONDS} state = GET_FREQUENCY; + static enum { + GET_FREQUENCY, + GET_MICROSECONDS, + SKIP_MICROSECONDS + } state = GET_FREQUENCY; if (state == GET_FREQUENCY) { if (QueryPerformanceFrequency(&freq)) @@ -1464,8 +1528,9 @@ void usleep(long microseconds) { end.QuadPart += (freq.QuadPart * microseconds) / 1000000; - while (QueryPerformanceCounter(¤t) && (current.QuadPart <= end.QuadPart)) - /* noop */ ; + while (QueryPerformanceCounter(¤t) && + (current.QuadPart <= end.QuadPart)) + /* noop */; } if (msec) @@ -1478,9 +1543,9 @@ void usleep(long microseconds) { void mkdirs(const std::string& dirpath) { File dir(dirpath); - if(!dir.mkdirs()) { + if (!dir.mkdirs()) { int errNum = errno; - if(!dir.isDir()) { + if (!dir.isDir()) { throw DL_ABORT_EX3(errNum, fmt(EX_MAKE_DIR, dir.getPath().c_str(), safeStrerror(errNum).c_str()), error_code::DIR_CREATE_ERROR); @@ -1491,9 +1556,9 @@ void mkdirs(const std::string& dirpath) void convertBitfield(BitfieldMan* dest, const BitfieldMan* src) { size_t numBlock = dest->countBlock(); - for(size_t index = 0; index < numBlock; ++index) { - if(src->isBitSetOffsetRange((int64_t)index*dest->getBlockLength(), - dest->getBlockLength())) { + for (size_t index = 0; index < numBlock; ++index) { + if (src->isBitSetOffsetRange((int64_t)index * dest->getBlockLength(), + dest->getBlockLength())) { dest->setBit(index); } } @@ -1503,11 +1568,11 @@ std::string toString(const std::shared_ptr<BinaryStream>& binaryStream) { std::stringstream strm; char data[2048]; - while(1) { - int32_t dataLength = binaryStream->readData - (reinterpret_cast<unsigned char*>(data), sizeof(data), strm.tellp()); + while (1) { + int32_t dataLength = binaryStream->readData( + reinterpret_cast<unsigned char*>(data), sizeof(data), strm.tellp()); strm.write(data, dataLength); - if(dataLength == 0) { + if (dataLength == 0) { break; } } @@ -1522,26 +1587,26 @@ void* allocateAlignedMemory(size_t alignment, size_t size) { void* buffer; int res; - if((res = posix_memalign(&buffer, alignment, size)) != 0) { - throw FATAL_EXCEPTION(fmt("Error in posix_memalign: %s", - util::safeStrerror(res).c_str())); + if ((res = posix_memalign(&buffer, alignment, size)) != 0) { + throw FATAL_EXCEPTION( + fmt("Error in posix_memalign: %s", util::safeStrerror(res).c_str())); } return buffer; } #endif // HAVE_POSIX_MEMALIGN -std::pair<std::string, uint16_t> -getNumericNameInfo(const struct sockaddr* sockaddr, socklen_t len) +Endpoint getNumericNameInfo(const struct sockaddr* sockaddr, socklen_t len) { char host[NI_MAXHOST]; char service[NI_MAXSERV]; int s = getnameinfo(sockaddr, len, host, NI_MAXHOST, service, NI_MAXSERV, - NI_NUMERICHOST|NI_NUMERICSERV); - if(s != 0) { - throw DL_ABORT_EX(fmt("Failed to get hostname and port. cause: %s", - gai_strerror(s))); + NI_NUMERICHOST | NI_NUMERICSERV); + if (s != 0) { + throw DL_ABORT_EX( + fmt("Failed to get hostname and port. cause: %s", gai_strerror(s))); } - return std::pair<std::string, uint16_t>(host, atoi(service)); // TODO + return {host, sockaddr->sa_family, + static_cast<uint16_t>(strtoul(service, nullptr, 10))}; } std::string htmlEscape(const std::string& src) @@ -1549,20 +1614,25 @@ std::string htmlEscape(const std::string& src) std::string dest; dest.reserve(src.size()); auto j = std::begin(src); - for(auto i = std::begin(src); i != std::end(src); ++i) { + for (auto i = std::begin(src); i != std::end(src); ++i) { char ch = *i; - const char *repl; - if(ch == '<') { + const char* repl; + if (ch == '<') { repl = "<"; - } else if(ch == '>') { + } + else if (ch == '>') { repl = ">"; - } else if(ch == '&') { + } + else if (ch == '&') { repl = "&"; - } else if(ch == '\'') { + } + else if (ch == '\'') { repl = "'"; - } else if(ch == '"') { + } + else if (ch == '"') { repl = """; - } else { + } + else { continue; } dest.append(j, i); @@ -1573,25 +1643,24 @@ std::string htmlEscape(const std::string& src) return dest; } -std::pair<size_t, std::string> -parseIndexPath(const std::string& line) +std::pair<size_t, std::string> parseIndexPath(const std::string& line) { auto p = divide(std::begin(line), std::end(line), '='); uint32_t index; - if(!parseUIntNoThrow(index, std::string(p.first.first, p.first.second))) { + if (!parseUIntNoThrow(index, std::string(p.first.first, p.first.second))) { throw DL_ABORT_EX("Bad path index"); } - if(p.second.first == p.second.second) { + if (p.second.first == p.second.second) { throw DL_ABORT_EX(fmt("Path with index=%u is empty.", index)); } return std::make_pair(index, std::string(p.second.first, p.second.second)); } -std::vector<std::pair<size_t, std::string> > createIndexPaths(std::istream& i) +std::vector<std::pair<size_t, std::string>> createIndexPaths(std::istream& i) { - std::vector<std::pair<size_t, std::string> > indexPaths; + std::vector<std::pair<size_t, std::string>> indexPaths; std::string line; - while(getline(i, line)) { + while (getline(i, line)) { indexPaths.push_back(parseIndexPath(line)); } return indexPaths; @@ -1603,23 +1672,23 @@ void generateRandomData(unsigned char* data, size_t length) return rd->getRandomBytes(data, length); } -bool saveAs -(const std::string& filename, const std::string& data, bool overwrite) +bool saveAs(const std::string& filename, const std::string& data, + bool overwrite) { - if(!overwrite && File(filename).exists()) { + if (!overwrite && File(filename).exists()) { return false; } std::string tempFilename = filename; tempFilename += "__temp"; { BufferedFile fp(tempFilename.c_str(), BufferedFile::WRITE); - if(!fp) { + if (!fp) { return false; } - if(fp.write(data.data(), data.size()) != data.size()) { + if (fp.write(data.data(), data.size()) != data.size()) { return false; } - if(fp.close() == EOF) { + if (fp.close() == EOF) { return false; } } @@ -1629,13 +1698,13 @@ bool saveAs std::string applyDir(const std::string& dir, const std::string& relPath) { std::string s; - if(dir.empty()) { + if (dir.empty()) { s = "./"; s += relPath; } else { s = dir; - if(dir == "/") { + if (dir == "/") { s += relPath; } else { @@ -1644,8 +1713,8 @@ std::string applyDir(const std::string& dir, const std::string& relPath) } } #ifdef __MINGW32__ - for(std::string::iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) { - if(*i == '\\') { + for (std::string::iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) { + if (*i == '\\') { *i = '/'; } } @@ -1674,15 +1743,15 @@ void generateRandomKey(unsigned char* key) // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix) bool inPrivateAddress(const std::string& ipv4addr) { - if(util::startsWith(ipv4addr, "10.") || - util::startsWith(ipv4addr, "192.168.")) { + if (util::startsWith(ipv4addr, "10.") || + util::startsWith(ipv4addr, "192.168.")) { return true; } - if(util::startsWith(ipv4addr, "172.")) { - for(int i = 16; i <= 31; ++i) { + if (util::startsWith(ipv4addr, "172.")) { + for (int i = 16; i <= 31; ++i) { std::string t(fmt("%d.", i)); - if(util::startsWith(ipv4addr.begin()+4, ipv4addr.end(), - t.begin(), t.end())) { + if (util::startsWith(ipv4addr.begin() + 4, ipv4addr.end(), t.begin(), + t.end())) { return true; } } @@ -1692,7 +1761,7 @@ bool inPrivateAddress(const std::string& ipv4addr) bool detectDirTraversal(const std::string& s) { - if(s.empty()) { + if (s.empty()) { return false; } for (auto c : s) { @@ -1701,60 +1770,57 @@ bool detectDirTraversal(const std::string& s) return true; } } - return s == "." || s == ".." || s[0] == '/' || - util::startsWith(s, "./") || - util::startsWith(s, "../") || - s.find("/../") != std::string::npos || - s.find("/./") != std::string::npos || - s[s.size()-1] == '/' || - util::endsWith(s, "/.") || - util::endsWith(s, "/.."); + return s == "." || s == ".." || s[0] == '/' || util::startsWith(s, "./") || + util::startsWith(s, "../") || s.find("/../") != std::string::npos || + s.find("/./") != std::string::npos || s[s.size() - 1] == '/' || + util::endsWith(s, "/.") || util::endsWith(s, "/.."); } std::string escapePath(const std::string& s) { - // We don't escape '/' because we use it as a path separator. +// We don't escape '/' because we use it as a path separator. #ifdef __MINGW32__ - static const char WIN_INVALID_PATH_CHARS[] = - { '"', '*', ':', '<', '>', '?', '\\', '|' }; + static const char WIN_INVALID_PATH_CHARS[] = {'"', '*', ':', '<', + '>', '?', '\\', '|'}; #endif // __MINGW32__ std::string d; - for(auto cc: s) { + for (auto cc : s) { unsigned char c = cc; - if(in(c, 0x00u, 0x1fu) || c == 0x7fu + if (in(c, 0x00u, 0x1fu) || c == 0x7fu #ifdef __MINGW32__ - || std::find(std::begin(WIN_INVALID_PATH_CHARS), - std::end(WIN_INVALID_PATH_CHARS), - c) != std::end(WIN_INVALID_PATH_CHARS) + || + std::find(std::begin(WIN_INVALID_PATH_CHARS), + std::end(WIN_INVALID_PATH_CHARS), + c) != std::end(WIN_INVALID_PATH_CHARS) #endif // __MINGW32__ - ){ + ) { d += fmt("%%%02X", c); - } else { + } + else { d += c; } } return d; } -bool inSameCidrBlock -(const std::string& ip1, const std::string& ip2, size_t bits) +bool inSameCidrBlock(const std::string& ip1, const std::string& ip2, + size_t bits) { unsigned char s1[16], s2[16]; size_t len1, len2; - if((len1 = net::getBinAddr(s1, ip1)) == 0 || - (len2 = net::getBinAddr(s2, ip2)) == 0 || - len1 != len2) { + if ((len1 = net::getBinAddr(s1, ip1)) == 0 || + (len2 = net::getBinAddr(s2, ip2)) == 0 || len1 != len2) { return false; } - if(bits == 0) { + if (bits == 0) { return true; } - if(bits > 8*len1) { - bits = 8*len1; + if (bits > 8 * len1) { + bits = 8 * len1; } - int last = (bits-1)/8; - for(int i = 0; i < last; ++i) { - if(s1[i] != s2[i]) { + int last = (bits - 1) / 8; + for (int i = 0; i < last; ++i) { + if (s1[i] != s2[i]) { return false; } } @@ -1764,35 +1830,26 @@ bool inSameCidrBlock namespace { -void executeHook -(const std::string& command, - a2_gid_t gid, - size_t numFiles, - const std::string& firstFilename) +void executeHook(const std::string& command, a2_gid_t gid, size_t numFiles, + const std::string& firstFilename) { const std::string gidStr = GroupId::toHex(gid); const std::string numFilesStr = util::uitos(numFiles); #ifndef __MINGW32__ - A2_LOG_INFO(fmt("Executing user command: %s %s %s %s", - command.c_str(), - gidStr.c_str(), - numFilesStr.c_str(), - firstFilename.c_str())); + A2_LOG_INFO(fmt("Executing user command: %s %s %s %s", command.c_str(), + gidStr.c_str(), numFilesStr.c_str(), firstFilename.c_str())); pid_t cpid = fork(); if (cpid == 0) { // child! - execlp(command.c_str(), - command.c_str(), - gidStr.c_str(), - numFilesStr.c_str(), - firstFilename.c_str(), + execlp(command.c_str(), command.c_str(), gidStr.c_str(), + numFilesStr.c_str(), firstFilename.c_str(), reinterpret_cast<char*>(0)); - perror(("Could not execute user command: "+command).c_str()); + perror(("Could not execute user command: " + command).c_str()); _exit(EXIT_FAILURE); return; } - if(cpid == -1) { + if (cpid == -1) { A2_LOG_ERROR("fork() failed. Cannot execute user command."); } return; @@ -1801,20 +1858,21 @@ void executeHook PROCESS_INFORMATION pi; STARTUPINFOW si; - memset(&si, 0, sizeof (si)); + memset(&si, 0, sizeof(si)); si.cb = sizeof(STARTUPINFO); - memset(&pi, 0, sizeof (pi)); + memset(&pi, 0, sizeof(pi)); bool batch = util::iendsWith(command, ".bat"); std::string cmdline; std::string cmdexe; // XXX batch handling, in particular quoting, correct? - if(batch) { + if (batch) { const char* p = getenv("windir"); - if(p) { + if (p) { cmdexe = p; cmdexe += "\\system32\\cmd.exe"; - } else { + } + else { A2_LOG_INFO("Failed to get windir environment variable." " Executing batch file will fail."); // TODO Might be useless. @@ -1832,7 +1890,7 @@ void executeHook cmdline += " \""; cmdline += firstFilename; cmdline += "\""; - if(batch) { + if (batch) { cmdline += "\""; } int cmdlineLen = utf8ToWChar(nullptr, 0, cmdline.c_str()); @@ -1842,17 +1900,10 @@ void executeHook assert(cmdlineLen > 0); A2_LOG_INFO(fmt("Executing user command: %s", cmdline.c_str())); DWORD rc = CreateProcessW(batch ? utf8ToWChar(cmdexe).c_str() : nullptr, - wcharCmdline.get(), - nullptr, - nullptr, - true, - 0, - nullptr, - 0, - &si, - &pi); - - if(!rc) { + wcharCmdline.get(), nullptr, nullptr, false, 0, + nullptr, 0, &si, &pi); + + if (!rc) { A2_LOG_ERROR("CreateProcess() failed. Cannot execute user command."); } return; @@ -1862,24 +1913,23 @@ void executeHook } // namespace -void executeHookByOptName -(const std::shared_ptr<RequestGroup>& group, const Option* option, - PrefPtr pref) +void executeHookByOptName(const std::shared_ptr<RequestGroup>& group, + const Option* option, PrefPtr pref) { executeHookByOptName(group.get(), option, pref); } -void executeHookByOptName -(const RequestGroup* group, const Option* option, PrefPtr pref) +void executeHookByOptName(const RequestGroup* group, const Option* option, + PrefPtr pref) { const std::string& cmd = option->get(pref); - if(!cmd.empty()) { + if (!cmd.empty()) { const std::shared_ptr<DownloadContext> dctx = group->getDownloadContext(); std::string firstFilename; size_t numFiles = 0; - if(!group->inMemoryDownload()) { + if (!group->inMemoryDownload()) { std::shared_ptr<FileEntry> file = dctx->getFirstRequestedFileEntry(); - if(file) { + if (file) { firstFilename = file->getPath(); } numFiles = dctx->countRequestedFileEntry(); @@ -1888,45 +1938,39 @@ void executeHookByOptName } } -std::string createSafePath -(const std::string& dir, const std::string& filename) +std::string createSafePath(const std::string& dir, const std::string& filename) { - return util::applyDir(dir, util::isUtf8(filename) ? - util::fixTaintedBasename(filename) : - util::escapePath(util::percentEncode(filename)) - ); + return util::applyDir(dir, + util::isUtf8(filename) + ? util::fixTaintedBasename(filename) + : util::escapePath(util::percentEncode(filename))); } std::string createSafePath(const std::string& filename) { - return util::isUtf8(filename) ? - util::fixTaintedBasename(filename) : - util::escapePath(util::percentEncode(filename)); + return util::isUtf8(filename) + ? util::fixTaintedBasename(filename) + : util::escapePath(util::percentEncode(filename)); } std::string encodeNonUtf8(const std::string& s) { - return util::isUtf8(s)?s:util::percentEncode(s); + return util::isUtf8(s) ? s : util::percentEncode(s); } std::string makeString(const char* str) { - if(!str) { + if (!str) { return A2STR::NIL; } return str; } -std::string safeStrerror(int errNum) -{ - return makeString(strerror(errNum)); -} +std::string safeStrerror(int errNum) { return makeString(strerror(errNum)); } -bool noProxyDomainMatch -(const std::string& hostname, - const std::string& domain) +bool noProxyDomainMatch(const std::string& hostname, const std::string& domain) { - if(!domain.empty() && domain[0] == '.' && !util::isNumericHost(hostname)) { + if (!domain.empty() && domain[0] == '.' && !util::isNumericHost(hostname)) { return util::endsWith(hostname, domain); } return hostname == domain; @@ -1934,40 +1978,36 @@ bool noProxyDomainMatch bool tlsHostnameMatch(const std::string& pattern, const std::string& hostname) { - std::string::const_iterator ptWildcard = std::find(pattern.begin(), - pattern.end(), - '*'); - if(ptWildcard == pattern.end()) { - return strieq(pattern.begin(), pattern.end(), - hostname.begin(), hostname.end()); + std::string::const_iterator ptWildcard = + std::find(pattern.begin(), pattern.end(), '*'); + if (ptWildcard == pattern.end()) { + return strieq(pattern.begin(), pattern.end(), hostname.begin(), + hostname.end()); } - std::string::const_iterator ptLeftLabelEnd = std::find(pattern.begin(), - pattern.end(), - '.'); + std::string::const_iterator ptLeftLabelEnd = + std::find(pattern.begin(), pattern.end(), '.'); bool wildcardEnabled = true; // Do case-insensitive match. At least 2 dots are required to enable // wildcard match. Also wildcard must be in the left-most label. // Don't attempt to match a presented identifier where the wildcard // character is embedded within an A-label. - if(ptLeftLabelEnd == pattern.end() || - std::find(ptLeftLabelEnd+1, pattern.end(), '.') == pattern.end() || - ptLeftLabelEnd < ptWildcard || - istartsWith(pattern, "xn--")) { + if (ptLeftLabelEnd == pattern.end() || + std::find(ptLeftLabelEnd + 1, pattern.end(), '.') == pattern.end() || + ptLeftLabelEnd < ptWildcard || istartsWith(pattern, "xn--")) { wildcardEnabled = false; } - if(!wildcardEnabled) { - return strieq(pattern.begin(), pattern.end(), - hostname.begin(), hostname.end()); + if (!wildcardEnabled) { + return strieq(pattern.begin(), pattern.end(), hostname.begin(), + hostname.end()); } - std::string::const_iterator hnLeftLabelEnd = std::find(hostname.begin(), - hostname.end(), - '.'); - if(!strieq(ptLeftLabelEnd, pattern.end(), hnLeftLabelEnd, hostname.end())) { + std::string::const_iterator hnLeftLabelEnd = + std::find(hostname.begin(), hostname.end(), '.'); + if (!strieq(ptLeftLabelEnd, pattern.end(), hnLeftLabelEnd, hostname.end())) { return false; } // Perform wildcard match. Here '*' must match at least one // character. - if(hnLeftLabelEnd - hostname.begin() < ptLeftLabelEnd - pattern.begin()) { + if (hnLeftLabelEnd - hostname.begin() < ptLeftLabelEnd - pattern.begin()) { return false; } return istartsWith(hostname.begin(), hnLeftLabelEnd, pattern.begin(), @@ -2001,9 +2041,14 @@ bool istartsWith(const std::string& a, const char* b) return istartsWith(a.begin(), a.end(), b); } +bool istartsWith(const std::string& a, const std::string& b) +{ + return istartsWith(std::begin(a), std::end(a), std::begin(b), std::end(b)); +} + bool endsWith(const std::string& a, const char* b) { - return endsWith(a.begin(), a.end(), b, b+strlen(b)); + return endsWith(a.begin(), a.end(), b, b + strlen(b)); } bool endsWith(const std::string& a, const std::string& b) @@ -2013,7 +2058,7 @@ bool endsWith(const std::string& a, const std::string& b) bool iendsWith(const std::string& a, const char* b) { - return iendsWith(a.begin(), a.end(), b, b+strlen(b)); + return iendsWith(a.begin(), a.end(), b, b + strlen(b)); } bool iendsWith(const std::string& a, const std::string& b) @@ -2021,30 +2066,63 @@ bool iendsWith(const std::string& a, const std::string& b) return iendsWith(a.begin(), a.end(), b.begin(), b.end()); } -bool strless(const char* a, const char* b) -{ - return strcmp(a, b) < 0; -} +bool strless(const char* a, const char* b) { return strcmp(a, b) < 0; } #ifdef ENABLE_SSL TLSVersion toTLSVersion(const std::string& ver) { - if(ver == A2_V_SSL3) { + if (ver == A2_V_SSL3) { return TLS_PROTO_SSL3; } - if(ver == A2_V_TLS10) { + if (ver == A2_V_TLS10) { return TLS_PROTO_TLS10; } - if(ver == A2_V_TLS11) { + if (ver == A2_V_TLS11) { return TLS_PROTO_TLS11; } - if(ver == A2_V_TLS12) { + if (ver == A2_V_TLS12) { return TLS_PROTO_TLS12; } return TLS_PROTO_TLS10; } #endif // ENABLE_SSL +#ifdef __MINGW32__ +std::string formatLastError(int errNum) +{ + std::array<char, 4_k> buf; + if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, errNum, + // Default language + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + static_cast<LPTSTR>(buf.data()), buf.size(), + nullptr) == 0) { + return ""; + } + + return buf.data(); +} +#endif // __MINGW32__ + +void make_fd_cloexec(int fd) +{ +#ifndef __MINGW32__ + int flags; + + // TODO from linux man page, fcntl() with F_GETFD or F_SETFD does + // not return -1 with errno == EINTR. Historically, aria2 code base + // checks this case. Probably, it is not needed. + while ((flags = fcntl(fd, F_GETFD)) == -1 && errno == EINTR) + ; + if (flags == -1) { + return; + } + + while (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1 && errno == EINTR) + ; +#endif // !__MINGW32__ +} + } // namespace util } // namespace aria2 |
