util.cc 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707
  1. /* <!-- copyright */
  2. /*
  3. * aria2 - The high speed download utility
  4. *
  5. * Copyright (C) 2006 Tatsuhiro Tsujikawa
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. *
  21. * In addition, as a special exception, the copyright holders give
  22. * permission to link the code of portions of this program with the
  23. * OpenSSL library under certain conditions as described in each
  24. * individual source file, and distribute linked combinations
  25. * including the two.
  26. * You must obey the GNU General Public License in all respects
  27. * for all of the code used other than OpenSSL. If you modify
  28. * file(s) with this exception, you may extend this exception to your
  29. * version of the file(s), but you are not obligated to do so. If you
  30. * do not wish to do so, delete this exception statement from your
  31. * version. If you delete this exception statement from all source
  32. * files in the program, then also delete it here.
  33. */
  34. /* copyright --> */
  35. #include "util.h"
  36. #include <signal.h>
  37. #include <sys/types.h>
  38. #ifdef HAVE_PWD_H
  39. # include <pwd.h>
  40. #endif // HAVE_PWD_H
  41. #include <cerrno>
  42. #include <cassert>
  43. #include <cstring>
  44. #include <cstdio>
  45. #include <cstdlib>
  46. #include <sstream>
  47. #include <ostream>
  48. #include <algorithm>
  49. #include <fstream>
  50. #include <iomanip>
  51. #include "SimpleRandomizer.h"
  52. #include "File.h"
  53. #include "Randomizer.h"
  54. #include "a2netcompat.h"
  55. #include "BitfieldMan.h"
  56. #include "DefaultDiskWriter.h"
  57. #include "FatalException.h"
  58. #include "FileEntry.h"
  59. #include "A2STR.h"
  60. #include "array_fun.h"
  61. #include "bitfield.h"
  62. #include "DownloadHandlerConstants.h"
  63. #include "RequestGroup.h"
  64. #include "LogFactory.h"
  65. #include "Logger.h"
  66. #include "Option.h"
  67. #include "DownloadContext.h"
  68. #include "BufferedFile.h"
  69. #include "SocketCore.h"
  70. #include "prefs.h"
  71. #ifdef ENABLE_MESSAGE_DIGEST
  72. # include "MessageDigest.h"
  73. # include "message_digest_helper.h"
  74. #endif // ENABLE_MESSAGE_DIGEST
  75. // For libc6 which doesn't define ULLONG_MAX properly because of broken limits.h
  76. #ifndef ULLONG_MAX
  77. # define ULLONG_MAX 18446744073709551615ULL
  78. #endif // ULLONG_MAX
  79. namespace aria2 {
  80. #ifdef __MINGW32__
  81. namespace {
  82. int utf8ToWChar(wchar_t* out, size_t outLength, const char* src)
  83. {
  84. return MultiByteToWideChar(CP_UTF8, 0, src, -1, out, outLength);
  85. }
  86. } // namespace
  87. namespace {
  88. int ansiToWChar(wchar_t* out, size_t outLength, const char* src)
  89. {
  90. return MultiByteToWideChar(CP_ACP, 0, src, -1, out, outLength);
  91. }
  92. } // namespace
  93. namespace {
  94. int wCharToUtf8(char* out, size_t outLength, const wchar_t* src)
  95. {
  96. return WideCharToMultiByte(CP_UTF8, 0, src, -1, out, outLength, 0, 0);
  97. }
  98. } // namespace
  99. namespace {
  100. int wCharToAnsi(char* out, size_t outLength, const wchar_t* src)
  101. {
  102. return WideCharToMultiByte(CP_ACP, 0, src, -1, out, outLength, 0, 0);
  103. }
  104. } // namespace
  105. std::wstring utf8ToWChar(const char* src)
  106. {
  107. int len = utf8ToWChar(0, 0, src);
  108. if(len == 0) {
  109. abort();
  110. }
  111. array_ptr<wchar_t> buf(new wchar_t[len]);
  112. len = utf8ToWChar(buf, len, src);
  113. if(len == 0) {
  114. abort();
  115. } else {
  116. std::wstring dest(buf);
  117. return dest;
  118. }
  119. }
  120. std::wstring utf8ToWChar(const std::string& src)
  121. {
  122. return utf8ToWChar(src.c_str());
  123. }
  124. std::string utf8ToNative(const std::string& src)
  125. {
  126. std::wstring wsrc = utf8ToWChar(src);
  127. int len = wCharToAnsi(0, 0, wsrc.c_str());
  128. if(len == 0) {
  129. abort();
  130. }
  131. array_ptr<char> buf(new char[len]);
  132. len = wCharToAnsi(buf, len, wsrc.c_str());
  133. if(len == 0) {
  134. abort();
  135. } else {
  136. std::string dest(buf);
  137. return dest;
  138. }
  139. }
  140. std::string wCharToUtf8(const std::wstring& wsrc)
  141. {
  142. int len = wCharToUtf8(0, 0, wsrc.c_str());
  143. if(len == 0) {
  144. abort();
  145. }
  146. array_ptr<char> buf(new char[len]);
  147. len = wCharToUtf8(buf, len, wsrc.c_str());
  148. if(len == 0) {
  149. abort();
  150. } else {
  151. std::string dest(buf);
  152. return dest;
  153. }
  154. }
  155. std::string nativeToUtf8(const std::string& src)
  156. {
  157. int len = ansiToWChar(0, 0, src.c_str());
  158. if(len == 0) {
  159. abort();
  160. }
  161. array_ptr<wchar_t> buf(new wchar_t[len]);
  162. len = ansiToWChar(buf, len, src.c_str());
  163. if(len == 0) {
  164. abort();
  165. } else {
  166. return wCharToUtf8(std::wstring(buf));
  167. }
  168. }
  169. #endif // __MINGW32__
  170. namespace util {
  171. const char DEFAULT_STRIP_CHARSET[] = "\r\n\t ";
  172. std::string strip(const std::string& str, const char* chars)
  173. {
  174. std::pair<std::string::const_iterator,
  175. std::string::const_iterator> p =
  176. stripIter(str.begin(), str.end(), chars);
  177. return std::string(p.first, p.second);
  178. }
  179. std::string itos(int64_t value, bool comma)
  180. {
  181. bool flag = false;
  182. std::string str;
  183. if(value < 0) {
  184. if(value == INT64_MIN) {
  185. if(comma) {
  186. str = "-9,223,372,036,854,775,808";
  187. } else {
  188. str = "-9223372036854775808";
  189. }
  190. return str;
  191. }
  192. flag = true;
  193. value = -value;
  194. }
  195. str = uitos(value, comma);
  196. if(flag) {
  197. str.insert(str.begin(), '-');
  198. }
  199. return str;
  200. }
  201. int64_t difftv(struct timeval tv1, struct timeval tv2) {
  202. if((tv1.tv_sec < tv2.tv_sec) ||
  203. ((tv1.tv_sec == tv2.tv_sec) && (tv1.tv_usec < tv2.tv_usec))) {
  204. return 0;
  205. }
  206. return ((int64_t)(tv1.tv_sec-tv2.tv_sec)*1000000+
  207. tv1.tv_usec-tv2.tv_usec);
  208. }
  209. int32_t difftvsec(struct timeval tv1, struct timeval tv2) {
  210. if(tv1.tv_sec < tv2.tv_sec) {
  211. return 0;
  212. }
  213. return tv1.tv_sec-tv2.tv_sec;
  214. }
  215. std::string replace(const std::string& target, const std::string& oldstr, const std::string& newstr) {
  216. if(target.empty() || oldstr.empty()) {
  217. return target;
  218. }
  219. std::string result;
  220. std::string::size_type p = 0;
  221. std::string::size_type np = target.find(oldstr);
  222. while(np != std::string::npos) {
  223. result.append(target.begin()+p, target.begin()+np);
  224. result += newstr;
  225. p = np+oldstr.size();
  226. np = target.find(oldstr, p);
  227. }
  228. result.append(target.begin()+p, target.end());
  229. return result;
  230. }
  231. bool isAlpha(const char c)
  232. {
  233. return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
  234. }
  235. bool isDigit(const char c)
  236. {
  237. return '0' <= c && c <= '9';
  238. }
  239. bool isHexDigit(const char c)
  240. {
  241. return isDigit(c) || ('A' <= c && c <= 'F') || ('a' <= c && c <= 'f');
  242. }
  243. bool isHexDigit(const std::string& s)
  244. {
  245. for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) {
  246. if(!isHexDigit(*i)) {
  247. return false;
  248. }
  249. }
  250. return true;
  251. }
  252. bool inRFC3986ReservedChars(const char c)
  253. {
  254. static const char reserved[] = {
  255. ':' , '/' , '?' , '#' , '[' , ']' , '@',
  256. '!' , '$' , '&' , '\'' , '(' , ')',
  257. '*' , '+' , ',' , ';' , '=' };
  258. return std::find(vbegin(reserved), vend(reserved), c) != vend(reserved);
  259. }
  260. bool inRFC3986UnreservedChars(const char c)
  261. {
  262. static const char unreserved[] = { '-', '.', '_', '~' };
  263. return isAlpha(c) || isDigit(c) ||
  264. std::find(vbegin(unreserved), vend(unreserved), c) != vend(unreserved);
  265. }
  266. bool inRFC2978MIMECharset(const char c)
  267. {
  268. static const char chars[] = {
  269. '!', '#', '$', '%', '&',
  270. '\'', '+', '-', '^', '_',
  271. '`', '{', '}', '~'
  272. };
  273. return isAlpha(c) || isDigit(c) ||
  274. std::find(vbegin(chars), vend(chars), c) != vend(chars);
  275. }
  276. bool inRFC2616HttpToken(const char c)
  277. {
  278. static const char chars[] = {
  279. '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.',
  280. '^', '_', '`', '|', '~'
  281. };
  282. return isAlpha(c) || isDigit(c) ||
  283. std::find(vbegin(chars), vend(chars), c) != vend(chars);
  284. }
  285. bool isLws(const char c)
  286. {
  287. return c == ' ' || c == '\t';
  288. }
  289. bool isCRLF(const char c)
  290. {
  291. return c == '\r' || c == '\n';
  292. }
  293. namespace {
  294. bool isUtf8Tail(unsigned char ch)
  295. {
  296. return in(ch, 0x80u, 0xbfu);
  297. }
  298. } // namespace
  299. bool isUtf8(const std::string& str)
  300. {
  301. for(std::string::const_iterator s = str.begin(), eos = str.end(); s != eos;
  302. ++s) {
  303. unsigned char firstChar = *s;
  304. // See ABNF in http://tools.ietf.org/search/rfc3629#section-4
  305. if(in(firstChar, 0x20u, 0x7eu) ||
  306. firstChar == 0x08u || // \b
  307. firstChar == 0x09u || // \t
  308. firstChar == 0x0au || // \n
  309. firstChar == 0x0cu || // \f
  310. firstChar == 0x0du // \r
  311. ) {
  312. // UTF8-1 (without ctrl chars)
  313. } else if(in(firstChar, 0xc2u, 0xdfu)) {
  314. // UTF8-2
  315. if(++s == eos || !isUtf8Tail(*s)) {
  316. return false;
  317. }
  318. } else if(0xe0u == firstChar) {
  319. // UTF8-3
  320. if(++s == eos || !in(static_cast<unsigned char>(*s), 0xa0u, 0xbfu) ||
  321. ++s == eos || !isUtf8Tail(*s)) {
  322. return false;
  323. }
  324. } else if(in(firstChar, 0xe1u, 0xecu) || in(firstChar, 0xeeu, 0xefu)) {
  325. // UTF8-3
  326. if(++s == eos || !isUtf8Tail(*s) ||
  327. ++s == eos || !isUtf8Tail(*s)) {
  328. return false;
  329. }
  330. } else if(0xedu == firstChar) {
  331. // UTF8-3
  332. if(++s == eos || !in(static_cast<unsigned char>(*s), 0x80u, 0x9fu) ||
  333. ++s == eos || !isUtf8Tail(*s)) {
  334. return false;
  335. }
  336. } else if(0xf0u == firstChar) {
  337. // UTF8-4
  338. if(++s == eos || !in(static_cast<unsigned char>(*s), 0x90u, 0xbfu) ||
  339. ++s == eos || !isUtf8Tail(*s) ||
  340. ++s == eos || !isUtf8Tail(*s)) {
  341. return false;
  342. }
  343. } else if(in(firstChar, 0xf1u, 0xf3u)) {
  344. // UTF8-4
  345. if(++s == eos || !isUtf8Tail(*s) ||
  346. ++s == eos || !isUtf8Tail(*s) ||
  347. ++s == eos || !isUtf8Tail(*s)) {
  348. return false;
  349. }
  350. } else if(0xf4u == firstChar) {
  351. // UTF8-4
  352. if(++s == eos || !in(static_cast<unsigned char>(*s), 0x80u, 0x8fu) ||
  353. ++s == eos || !isUtf8Tail(*s) ||
  354. ++s == eos || !isUtf8Tail(*s)) {
  355. return false;
  356. }
  357. } else {
  358. return false;
  359. }
  360. }
  361. return true;
  362. }
  363. std::string percentEncode(const unsigned char* target, size_t len)
  364. {
  365. std::string dest;
  366. for(size_t i = 0; i < len; ++i) {
  367. if(inRFC3986UnreservedChars(target[i])) {
  368. dest += target[i];
  369. } else {
  370. dest.append(fmt("%%%02X", target[i]));
  371. }
  372. }
  373. return dest;
  374. }
  375. std::string percentEncode(const std::string& target)
  376. {
  377. return percentEncode(reinterpret_cast<const unsigned char*>(target.c_str()),
  378. target.size());
  379. }
  380. std::string percentEncodeMini(const std::string& src)
  381. {
  382. std::string result;
  383. for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi;
  384. ++i) {
  385. // Non-Printable ASCII and non-ASCII chars + some ASCII chars.
  386. unsigned char c = *i;
  387. if(in(c, 0x00u, 0x20u) || c >= 0x7fu ||
  388. // Chromium escapes following characters. Firefox4 escapes
  389. // more.
  390. c == '"' || c == '<' || c == '>') {
  391. result += fmt("%%%02X", c);
  392. } else {
  393. result += c;
  394. }
  395. }
  396. return result;
  397. }
  398. std::string torrentPercentEncode(const unsigned char* target, size_t len) {
  399. std::string dest;
  400. for(size_t i = 0; i < len; ++i) {
  401. if(isAlpha(target[i]) || isDigit(target[i])) {
  402. dest += target[i];
  403. } else {
  404. dest.append(fmt("%%%02X", target[i]));
  405. }
  406. }
  407. return dest;
  408. }
  409. std::string torrentPercentEncode(const std::string& target)
  410. {
  411. return torrentPercentEncode
  412. (reinterpret_cast<const unsigned char*>(target.c_str()), target.size());
  413. }
  414. std::string percentDecode
  415. (std::string::const_iterator first, std::string::const_iterator last)
  416. {
  417. std::string result;
  418. for(; first != last; ++first) {
  419. if(*first == '%') {
  420. if(first+1 != last && first+2 != last &&
  421. isHexDigit(*(first+1)) && isHexDigit(*(first+2))) {
  422. result += hexCharToUInt(*(first+1))*16+hexCharToUInt(*(first+2));
  423. first += 2;
  424. } else {
  425. result += *first;
  426. }
  427. } else {
  428. result += *first;
  429. }
  430. }
  431. return result;
  432. }
  433. std::string toHex(const unsigned char* src, size_t len) {
  434. std::string out(len*2, '\0');
  435. std::string::iterator o = out.begin();
  436. const unsigned char* last = src+len;
  437. for(const unsigned char* i = src; i != last; ++i) {
  438. *o = (*i >> 4);
  439. *(o+1) = (*i)&0x0fu;
  440. for(int j = 0; j < 2; ++j) {
  441. if(*o < 10) {
  442. *o += '0';
  443. } else {
  444. *o += 'a'-10;
  445. }
  446. ++o;
  447. }
  448. }
  449. return out;
  450. }
  451. std::string toHex(const char* src, size_t len)
  452. {
  453. return toHex(reinterpret_cast<const unsigned char*>(src), len);
  454. }
  455. std::string toHex(const std::string& src)
  456. {
  457. return toHex(reinterpret_cast<const unsigned char*>(src.c_str()), src.size());
  458. }
  459. unsigned int hexCharToUInt(unsigned char ch)
  460. {
  461. if('a' <= ch && ch <= 'f') {
  462. ch -= 'a';
  463. ch += 10;
  464. } else if('A' <= ch && ch <= 'F') {
  465. ch -= 'A';
  466. ch += 10;
  467. } else if('0' <= ch && ch <= '9') {
  468. ch -= '0';
  469. } else {
  470. ch = 255;
  471. }
  472. return ch;
  473. }
  474. FILE* openFile(const std::string& filename, const std::string& mode) {
  475. FILE* file = fopen(filename.c_str(), mode.c_str());
  476. return file;
  477. }
  478. bool isPowerOf(int num, int base) {
  479. if(base <= 0) { return false; }
  480. if(base == 1) { return true; }
  481. while(num%base == 0) {
  482. num /= base;
  483. if(num == 1) {
  484. return true;
  485. }
  486. }
  487. return false;
  488. }
  489. std::string secfmt(time_t sec) {
  490. time_t tsec = sec;
  491. std::string str;
  492. if(sec >= 3600) {
  493. str = fmt("%" PRId64 "h", static_cast<int64_t>(sec/3600));
  494. sec %= 3600;
  495. }
  496. if(sec >= 60) {
  497. str += fmt("%dm", static_cast<int>(sec/60));
  498. sec %= 60;
  499. }
  500. if(sec || tsec == 0) {
  501. str += fmt("%ds", static_cast<int>(sec));
  502. }
  503. return str;
  504. }
  505. int getNum(const char* buf, int offset, size_t length) {
  506. char* temp = new char[length+1];
  507. memcpy(temp, buf+offset, length);
  508. temp[length] = '\0';
  509. int x = strtol(temp, 0, 10);
  510. delete [] temp;
  511. return x;
  512. }
  513. namespace {
  514. template<typename T, typename F>
  515. bool parseLong(T& res, F f, const std::string& s, int base)
  516. {
  517. if(s.empty()) {
  518. return false;
  519. }
  520. char* endptr;
  521. errno = 0;
  522. res = f(s.c_str(), &endptr, base);
  523. if(errno == ERANGE) {
  524. return false;
  525. }
  526. if(*endptr != '\0') {
  527. for(const char* i = endptr, *eoi = s.c_str()+s.size(); i < eoi; ++i) {
  528. if(!isspace(*i)) {
  529. return false;
  530. }
  531. }
  532. }
  533. return true;
  534. }
  535. } // namespace
  536. bool parseIntNoThrow(int32_t& res, const std::string& s, int base)
  537. {
  538. long int t;
  539. if(parseLong(t, strtol, s, base) &&
  540. t >= std::numeric_limits<int32_t>::min() &&
  541. t <= std::numeric_limits<int32_t>::max()) {
  542. res = t;
  543. return true;
  544. } else {
  545. return false;
  546. }
  547. }
  548. bool parseUIntNoThrow(uint32_t& res, const std::string& s, int base)
  549. {
  550. long int t;
  551. if(parseLong(t, strtol, s, base) &&
  552. t >= 0 &&
  553. t <= std::numeric_limits<int32_t>::max()) {
  554. res = t;
  555. return true;
  556. } else {
  557. return false;
  558. }
  559. }
  560. bool parseLLIntNoThrow(int64_t& res, const std::string& s, int base)
  561. {
  562. long long int t;
  563. if(parseLong(t, strtoll, s, base) &&
  564. t >= std::numeric_limits<int64_t>::min() &&
  565. t <= std::numeric_limits<int64_t>::max()) {
  566. res = t;
  567. return true;
  568. } else {
  569. return false;
  570. }
  571. }
  572. void parseIntSegments(SegList<int>& sgl, const std::string& src)
  573. {
  574. for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi;) {
  575. std::string::const_iterator j = std::find(i, eoi, ',');
  576. if(j == i) {
  577. ++i;
  578. continue;
  579. }
  580. std::string::const_iterator p = std::find(i, j, '-');
  581. if(p == j) {
  582. int a;
  583. if(parseIntNoThrow(a, std::string(i, j))) {
  584. sgl.add(a, a+1);
  585. } else {
  586. throw DL_ABORT_EX(fmt("Bad range %s", std::string(i, j).c_str()));
  587. }
  588. } else if(p == i || p+1 == j) {
  589. throw DL_ABORT_EX(fmt(MSG_INCOMPLETE_RANGE, std::string(i, j).c_str()));
  590. } else {
  591. int a, b;
  592. if(parseIntNoThrow(a, std::string(i, p)) &&
  593. parseIntNoThrow(b, (std::string(p+1, j)))) {
  594. sgl.add(a, b+1);
  595. } else {
  596. throw DL_ABORT_EX(fmt("Bad range %s", std::string(i, j).c_str()));
  597. }
  598. }
  599. if(j == eoi) {
  600. break;
  601. }
  602. i = j+1;
  603. }
  604. }
  605. namespace {
  606. void computeHeadPieces
  607. (std::vector<size_t>& indexes,
  608. const std::vector<SharedHandle<FileEntry> >& fileEntries,
  609. size_t pieceLength,
  610. int64_t head)
  611. {
  612. if(head == 0) {
  613. return;
  614. }
  615. for(std::vector<SharedHandle<FileEntry> >::const_iterator fi =
  616. fileEntries.begin(), eoi = fileEntries.end(); fi != eoi; ++fi) {
  617. if((*fi)->getLength() == 0) {
  618. continue;
  619. }
  620. size_t lastIndex =
  621. ((*fi)->getOffset()+std::min(head, (*fi)->getLength())-1)/pieceLength;
  622. for(size_t index = (*fi)->getOffset()/pieceLength;
  623. index <= lastIndex; ++index) {
  624. indexes.push_back(index);
  625. }
  626. }
  627. }
  628. } // namespace
  629. namespace {
  630. void computeTailPieces
  631. (std::vector<size_t>& indexes,
  632. const std::vector<SharedHandle<FileEntry> >& fileEntries,
  633. size_t pieceLength,
  634. int64_t tail)
  635. {
  636. if(tail == 0) {
  637. return;
  638. }
  639. for(std::vector<SharedHandle<FileEntry> >::const_iterator fi =
  640. fileEntries.begin(), eoi = fileEntries.end(); fi != eoi; ++fi) {
  641. if((*fi)->getLength() == 0) {
  642. continue;
  643. }
  644. int64_t endOffset = (*fi)->getLastOffset();
  645. size_t fromIndex =
  646. (endOffset-1-(std::min(tail, (*fi)->getLength())-1))/pieceLength;
  647. for(size_t index = fromIndex; index <= (endOffset-1)/pieceLength;
  648. ++index) {
  649. indexes.push_back(index);
  650. }
  651. }
  652. }
  653. } // namespace
  654. void parsePrioritizePieceRange
  655. (std::vector<size_t>& result, const std::string& src,
  656. const std::vector<SharedHandle<FileEntry> >& fileEntries,
  657. size_t pieceLength,
  658. int64_t defaultSize)
  659. {
  660. std::vector<size_t> indexes;
  661. std::vector<Scip> parts;
  662. splitIter(src.begin(), src.end(), std::back_inserter(parts), ',', true);
  663. for(std::vector<Scip>::const_iterator i = parts.begin(),
  664. eoi = parts.end(); i != eoi; ++i) {
  665. if(util::streq((*i).first, (*i).second, "head")) {
  666. computeHeadPieces(indexes, fileEntries, pieceLength, defaultSize);
  667. } else if(util::startsWith((*i).first, (*i).second, "head=")) {
  668. std::string sizestr((*i).first+5, (*i).second);
  669. computeHeadPieces(indexes, fileEntries, pieceLength,
  670. std::max((int64_t)0, getRealSize(sizestr)));
  671. } else if(util::streq((*i).first, (*i).second, "tail")) {
  672. computeTailPieces(indexes, fileEntries, pieceLength, defaultSize);
  673. } else if(util::startsWith((*i).first, (*i).second, "tail=")) {
  674. std::string sizestr((*i).first+5, (*i).second);
  675. computeTailPieces(indexes, fileEntries, pieceLength,
  676. std::max((int64_t)0, getRealSize(sizestr)));
  677. } else {
  678. throw DL_ABORT_EX(fmt("Unrecognized token %s",
  679. std::string((*i).first, (*i).second).c_str()));
  680. }
  681. }
  682. std::sort(indexes.begin(), indexes.end());
  683. indexes.erase(std::unique(indexes.begin(), indexes.end()), indexes.end());
  684. result.insert(result.end(), indexes.begin(), indexes.end());
  685. }
  686. // Converts ISO/IEC 8859-1 string to UTF-8 string. If there is a
  687. // character not in ISO/IEC 8859-1, returns empty string.
  688. std::string iso8859ToUtf8(const std::string& src)
  689. {
  690. std::string dest;
  691. for(std::string::const_iterator itr = src.begin(), eoi = src.end();
  692. itr != eoi; ++itr) {
  693. unsigned char c = *itr;
  694. if(0xa0u <= c) {
  695. if(c <= 0xbfu) {
  696. dest += 0xc2u;
  697. } else {
  698. dest += 0xc3u;
  699. }
  700. dest += c&(~0x40u);
  701. } else if(0x80u <= c && c <= 0x9fu) {
  702. return A2STR::NIL;
  703. } else {
  704. dest += c;
  705. }
  706. }
  707. return dest;
  708. }
  709. namespace {
  710. template<typename OutputIterator>
  711. void parseParam(OutputIterator out, const std::string& header)
  712. {
  713. for(std::string::const_iterator i = header.begin(), eoi = header.end();
  714. i != eoi;) {
  715. std::string::const_iterator paramFirst = i;
  716. std::string::const_iterator paramLast = paramFirst;
  717. for(; paramLast != eoi && *paramLast != '=' && *paramLast != ';';
  718. ++paramLast);
  719. std::string param;
  720. if(paramLast == eoi || *paramLast == ';') {
  721. // No value, parmname only
  722. param.assign(paramFirst, paramLast);
  723. } else {
  724. for(; paramLast != eoi && *paramLast != '"' && *paramLast != ';';
  725. ++paramLast);
  726. if(paramLast != eoi && *paramLast == '"') {
  727. // quoted-string
  728. ++paramLast;
  729. for(; paramLast != eoi && *paramLast != '"'; ++paramLast);
  730. if(paramLast != eoi) {
  731. ++paramLast;
  732. }
  733. param.assign(paramFirst, paramLast);
  734. for(; paramLast != eoi && *paramLast != ';'; ++paramLast);
  735. } else {
  736. param.assign(paramFirst, paramLast);
  737. }
  738. }
  739. param = strip(param);
  740. *out++ = param;
  741. if(paramLast == eoi) {
  742. break;
  743. }
  744. i = paramLast;
  745. ++i;
  746. }
  747. }
  748. } // namespace
  749. std::string getContentDispositionFilename(const std::string& header)
  750. {
  751. static const char A2_KEYNAME[] = "filename";
  752. std::string filename;
  753. std::vector<std::string> params;
  754. parseParam(std::back_inserter(params), header);
  755. for(std::vector<std::string>::const_iterator i = params.begin(),
  756. eoi = params.end(); i != eoi; ++i) {
  757. const std::string& param = *i;
  758. if(!istartsWith(param, A2_KEYNAME) ||
  759. param.size() == sizeof(A2_KEYNAME)-1) {
  760. continue;
  761. }
  762. std::string::const_iterator markeritr = param.begin()+sizeof(A2_KEYNAME)-1;
  763. if(*markeritr == '*') {
  764. // See RFC2231 Section4 and draft-reschke-rfc2231-in-http.
  765. // Please note that this function doesn't do charset conversion
  766. // except that if iso-8859-1 is specified, it is converted to
  767. // utf-8.
  768. ++markeritr;
  769. for(; markeritr != param.end() && *markeritr == ' '; ++markeritr);
  770. if(markeritr == param.end() || *markeritr != '=') {
  771. continue;
  772. }
  773. std::vector<Scip> extValues;
  774. splitIter(markeritr+1, param.end(), std::back_inserter(extValues),
  775. '\'', true, true);
  776. if(extValues.size() != 3) {
  777. continue;
  778. }
  779. bool bad = false;
  780. for(std::string::const_iterator j = extValues[0].first,
  781. eoj = extValues[0].second; j != eoj; ++j) {
  782. // Since we first split parameter by ', we can safely assume
  783. // that ' is not included in charset.
  784. if(!inRFC2978MIMECharset(*j)) {
  785. bad = true;
  786. break;
  787. }
  788. }
  789. if(bad) {
  790. continue;
  791. }
  792. bad = false;
  793. for(std::string::const_iterator j = extValues[2].first,
  794. eoj = extValues[2].second; j != eoj; ++j){
  795. if(*j == '%') {
  796. if(j+1 != eoj && isHexDigit(*(j+1)) &&
  797. j+2 != eoj && isHexDigit(*(j+2))) {
  798. j += 2;
  799. } else {
  800. bad = true;
  801. break;
  802. }
  803. } else {
  804. if(*j == '*' || *j == '\'' || !inRFC2616HttpToken(*j)) {
  805. bad = true;
  806. break;
  807. }
  808. }
  809. }
  810. if(bad) {
  811. continue;
  812. }
  813. std::string value =
  814. percentDecode(extValues[2].first, extValues[2].second);
  815. if(util::strieq(extValues[0].first, extValues[0].second, "iso-8859-1")) {
  816. value = iso8859ToUtf8(value);
  817. }
  818. if(!detectDirTraversal(value) && value.find("/") == std::string::npos) {
  819. filename = value;
  820. }
  821. if(!filename.empty()) {
  822. break;
  823. }
  824. } else {
  825. for(; markeritr != param.end() && *markeritr == ' '; ++markeritr);
  826. if(markeritr == param.end() || markeritr+1 == param.end() ||
  827. *markeritr != '=') {
  828. continue;
  829. }
  830. Scip p = stripIter(markeritr+1, param.end());
  831. if(p.first == p.second) {
  832. continue;
  833. }
  834. std::string value(p.first, p.second);
  835. std::string::iterator filenameLast;
  836. if(value[0] == '\'' || value[0] == '"') {
  837. char qc = *value.begin();
  838. for(filenameLast = value.begin()+1;
  839. filenameLast != value.end() && *filenameLast != qc;
  840. ++filenameLast);
  841. } else {
  842. filenameLast = value.end();
  843. }
  844. std::pair<std::string::iterator, std::string::iterator> vi =
  845. util::stripIter(value.begin(), filenameLast, "\r\n\t '\"");
  846. value.assign(vi.first, vi.second);
  847. value.erase(std::remove(value.begin(), value.end(), '\\'), value.end());
  848. if(!detectDirTraversal(value) && value.find("/") == std::string::npos) {
  849. filename = value;
  850. }
  851. // continue because there is a chance we can find filename*=...
  852. }
  853. }
  854. return filename;
  855. }
  856. std::string randomAlpha(size_t length, const RandomizerHandle& randomizer) {
  857. static const char randomChars[] =
  858. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  859. std::string str;
  860. for(size_t i = 0; i < length; ++i) {
  861. size_t index = randomizer->getRandomNumber(sizeof(randomChars)-1);
  862. str += randomChars[index];
  863. }
  864. return str;
  865. }
  866. std::string toUpper(const std::string& src) {
  867. std::string temp = src;
  868. std::transform(temp.begin(), temp.end(), temp.begin(), toUpperChar);
  869. return temp;
  870. }
  871. std::string toLower(const std::string& src) {
  872. std::string temp = src;
  873. std::transform(temp.begin(), temp.end(), temp.begin(), toLowerChar);
  874. return temp;
  875. }
  876. void uppercase(std::string& s)
  877. {
  878. std::transform(s.begin(), s.end(), s.begin(), toUpperChar);
  879. }
  880. void lowercase(std::string& s)
  881. {
  882. std::transform(s.begin(), s.end(), s.begin(), toLowerChar);
  883. }
  884. char toUpperChar(char c)
  885. {
  886. if('a' <= c && c <= 'z') {
  887. c += 'A'-'a';
  888. }
  889. return c;
  890. }
  891. char toLowerChar(char c)
  892. {
  893. if('A' <= c && c <= 'Z') {
  894. c += 'a'-'A';
  895. }
  896. return c;
  897. }
  898. bool isNumericHost(const std::string& name)
  899. {
  900. struct addrinfo hints;
  901. struct addrinfo* res;
  902. memset(&hints, 0, sizeof(hints));
  903. hints.ai_family = AF_UNSPEC;
  904. hints.ai_flags = AI_NUMERICHOST;
  905. if(getaddrinfo(name.c_str(), 0, &hints, &res)) {
  906. return false;
  907. }
  908. freeaddrinfo(res);
  909. return true;
  910. }
  911. void setGlobalSignalHandler(int sig, void (*handler)(int), int flags) {
  912. #ifdef HAVE_SIGACTION
  913. struct sigaction sigact;
  914. sigact.sa_handler = handler;
  915. sigact.sa_flags = flags;
  916. sigemptyset(&sigact.sa_mask);
  917. sigaction(sig, &sigact, NULL);
  918. #else
  919. signal(sig, handler);
  920. #endif // HAVE_SIGACTION
  921. }
  922. std::string getHomeDir()
  923. {
  924. const char* p = getenv("HOME");
  925. if(p) {
  926. return p;
  927. } else {
  928. #ifdef __MINGW32__
  929. p = getenv("USERPROFILE");
  930. if(p) {
  931. return p;
  932. } else {
  933. p = getenv("HOMEDRIVE");
  934. if(p) {
  935. std::string homeDir = p;
  936. p = getenv("HOMEPATH");
  937. if(p) {
  938. homeDir += p;
  939. return homeDir;
  940. }
  941. }
  942. }
  943. #elif HAVE_PWD_H
  944. passwd* pw = getpwuid(geteuid());
  945. if(pw && pw->pw_dir) {
  946. return pw->pw_dir;
  947. }
  948. #endif // HAVE_PWD_H
  949. return A2STR::NIL;
  950. }
  951. }
  952. int64_t getRealSize(const std::string& sizeWithUnit)
  953. {
  954. std::string::size_type p = sizeWithUnit.find_first_of("KM");
  955. std::string size;
  956. int32_t mult = 1;
  957. if(p == std::string::npos) {
  958. size = sizeWithUnit;
  959. } else {
  960. if(sizeWithUnit[p] == 'K') {
  961. mult = 1024;
  962. } else if(sizeWithUnit[p] == 'M') {
  963. mult = 1024*1024;
  964. }
  965. size.assign(sizeWithUnit.begin(), sizeWithUnit.begin()+p);
  966. }
  967. int64_t v;
  968. if(!parseLLIntNoThrow(v, size) || v < 0) {
  969. throw DL_ABORT_EX(fmt("Bad or negative value detected: %s",
  970. sizeWithUnit.c_str()));
  971. } else if(INT64_MAX/mult < v) {
  972. throw DL_ABORT_EX(fmt(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  973. "overflow/underflow"));
  974. }
  975. return v*mult;
  976. }
  977. std::string abbrevSize(int64_t size)
  978. {
  979. if(size < 1024) {
  980. return itos(size, true);
  981. }
  982. static const char units[] = { 'K', 'M' };
  983. size_t i = 0;
  984. int r = size&0x3ffu;
  985. size >>= 10;
  986. for(; i < sizeof(units)-1 && size >= 1024; ++i) {
  987. r = size&0x3ffu;
  988. size >>= 10;
  989. }
  990. std::string result = itos(size, true);
  991. result += fmt(".%d%ci", r*10/1024, units[i]);
  992. return result;
  993. }
  994. void sleep(long seconds) {
  995. #if defined(HAVE_WINSOCK2_H)
  996. ::Sleep(seconds * 1000);
  997. #elif HAVE_SLEEP
  998. ::sleep(seconds);
  999. #elif defined(HAVE_USLEEP)
  1000. ::usleep(seconds * 1000000);
  1001. #else
  1002. # error no sleep function is available (nanosleep?)
  1003. #endif
  1004. }
  1005. void usleep(long microseconds) {
  1006. #ifdef HAVE_USLEEP
  1007. ::usleep(microseconds);
  1008. #elif defined(HAVE_WINSOCK2_H)
  1009. LARGE_INTEGER current, freq, end;
  1010. static enum {GET_FREQUENCY, GET_MICROSECONDS, SKIP_MICROSECONDS} state = GET_FREQUENCY;
  1011. if (state == GET_FREQUENCY) {
  1012. if (QueryPerformanceFrequency(&freq))
  1013. state = GET_MICROSECONDS;
  1014. else
  1015. state = SKIP_MICROSECONDS;
  1016. }
  1017. long msec = microseconds / 1000;
  1018. microseconds %= 1000;
  1019. if (state == GET_MICROSECONDS && microseconds) {
  1020. QueryPerformanceCounter(&end);
  1021. end.QuadPart += (freq.QuadPart * microseconds) / 1000000;
  1022. while (QueryPerformanceCounter(&current) && (current.QuadPart <= end.QuadPart))
  1023. /* noop */ ;
  1024. }
  1025. if (msec)
  1026. Sleep(msec);
  1027. #else
  1028. #error no usleep function is available (nanosleep?)
  1029. #endif
  1030. }
  1031. unsigned int alphaToNum(const std::string& alphabets)
  1032. {
  1033. if(alphabets.empty()) {
  1034. return 0;
  1035. }
  1036. char base;
  1037. if(islower(alphabets[0])) {
  1038. base = 'a';
  1039. } else {
  1040. base = 'A';
  1041. }
  1042. uint64_t num = 0;
  1043. for(size_t i = 0, eoi = alphabets.size(); i < eoi; ++i) {
  1044. unsigned int v = alphabets[i]-base;
  1045. num = num*26+v;
  1046. if(num > UINT32_MAX) {
  1047. return 0;
  1048. }
  1049. }
  1050. return num;
  1051. }
  1052. void mkdirs(const std::string& dirpath)
  1053. {
  1054. File dir(dirpath);
  1055. if(!dir.mkdirs()) {
  1056. int errNum = errno;
  1057. if(!dir.isDir()) {
  1058. throw DL_ABORT_EX3
  1059. (errNum,
  1060. fmt(EX_MAKE_DIR, dir.getPath().c_str(),
  1061. safeStrerror(errNum).c_str()),
  1062. error_code::DIR_CREATE_ERROR);
  1063. }
  1064. }
  1065. }
  1066. void convertBitfield(BitfieldMan* dest, const BitfieldMan* src)
  1067. {
  1068. size_t numBlock = dest->countBlock();
  1069. for(size_t index = 0; index < numBlock; ++index) {
  1070. if(src->isBitSetOffsetRange((int64_t)index*dest->getBlockLength(),
  1071. dest->getBlockLength())) {
  1072. dest->setBit(index);
  1073. }
  1074. }
  1075. }
  1076. std::string toString(const BinaryStreamHandle& binaryStream)
  1077. {
  1078. std::stringstream strm;
  1079. char data[2048];
  1080. while(1) {
  1081. int32_t dataLength = binaryStream->readData
  1082. (reinterpret_cast<unsigned char*>(data), sizeof(data), strm.tellp());
  1083. strm.write(data, dataLength);
  1084. if(dataLength == 0) {
  1085. break;
  1086. }
  1087. }
  1088. return strm.str();
  1089. }
  1090. #ifdef HAVE_POSIX_MEMALIGN
  1091. /**
  1092. * In linux 2.6, alignment and size should be a multiple of 512.
  1093. */
  1094. void* allocateAlignedMemory(size_t alignment, size_t size)
  1095. {
  1096. void* buffer;
  1097. int res;
  1098. if((res = posix_memalign(&buffer, alignment, size)) != 0) {
  1099. throw FATAL_EXCEPTION
  1100. (fmt("Error in posix_memalign: %s",
  1101. util::safeStrerror(res).c_str()));
  1102. }
  1103. return buffer;
  1104. }
  1105. #endif // HAVE_POSIX_MEMALIGN
  1106. std::pair<std::string, uint16_t>
  1107. getNumericNameInfo(const struct sockaddr* sockaddr, socklen_t len)
  1108. {
  1109. char host[NI_MAXHOST];
  1110. char service[NI_MAXSERV];
  1111. int s = getnameinfo(sockaddr, len, host, NI_MAXHOST, service, NI_MAXSERV,
  1112. NI_NUMERICHOST|NI_NUMERICSERV);
  1113. if(s != 0) {
  1114. throw DL_ABORT_EX(fmt("Failed to get hostname and port. cause: %s",
  1115. gai_strerror(s)));
  1116. }
  1117. return std::pair<std::string, uint16_t>(host, atoi(service)); // TODO
  1118. }
  1119. std::string htmlEscape(const std::string& src)
  1120. {
  1121. std::string dest;
  1122. for(std::string::const_iterator i = src.begin(), eoi = src.end();
  1123. i != eoi; ++i) {
  1124. char ch = *i;
  1125. if(ch == '<') {
  1126. dest += "&lt;";
  1127. } else if(ch == '>') {
  1128. dest += "&gt;";
  1129. } else if(ch == '&') {
  1130. dest += "&amp;";
  1131. } else if(ch == '\'') {
  1132. dest += "&#39;";
  1133. } else if(ch == '"') {
  1134. dest += "&quot;";
  1135. } else {
  1136. dest += ch;
  1137. }
  1138. }
  1139. return dest;
  1140. }
  1141. std::pair<size_t, std::string>
  1142. parseIndexPath(const std::string& line)
  1143. {
  1144. std::pair<Scip, Scip> p;
  1145. divide(p, line.begin(), line.end(), '=');
  1146. uint32_t index;
  1147. if(!parseUIntNoThrow(index, std::string(p.first.first, p.first.second))) {
  1148. throw DL_ABORT_EX("Bad path index");
  1149. }
  1150. if(p.second.first == p.second.second) {
  1151. throw DL_ABORT_EX(fmt("Path with index=%u is empty.", index));
  1152. }
  1153. return std::make_pair(index, std::string(p.second.first, p.second.second));
  1154. }
  1155. std::vector<std::pair<size_t, std::string> > createIndexPaths(std::istream& i)
  1156. {
  1157. std::vector<std::pair<size_t, std::string> > indexPaths;
  1158. std::string line;
  1159. while(getline(i, line)) {
  1160. indexPaths.push_back(parseIndexPath(line));
  1161. }
  1162. return indexPaths;
  1163. }
  1164. namespace {
  1165. void generateRandomDataRandom(unsigned char* data, size_t length)
  1166. {
  1167. const SharedHandle<SimpleRandomizer>& rd = SimpleRandomizer::getInstance();
  1168. for(size_t i = 0; i < length; ++i) {
  1169. data[i] = static_cast<unsigned long>(rd->getRandomNumber(256));
  1170. }
  1171. }
  1172. } // namespace
  1173. namespace {
  1174. void generateRandomDataUrandom
  1175. (unsigned char* data, size_t length, std::ifstream& devUrand)
  1176. {
  1177. devUrand.read(reinterpret_cast<char*>(data), length);
  1178. }
  1179. } // namespace
  1180. void generateRandomData(unsigned char* data, size_t length)
  1181. {
  1182. #ifdef __MINGW32__
  1183. generateRandomDataRandom(data, length);
  1184. #else // !__MINGW32__
  1185. static int method = -1;
  1186. static std::ifstream devUrand;
  1187. if(method == 0) {
  1188. generateRandomDataUrandom(data, length, devUrand);
  1189. } else if(method == 1) {
  1190. generateRandomDataRandom(data, length);
  1191. } else {
  1192. devUrand.open("/dev/urandom");
  1193. if(devUrand) {
  1194. method = 0;
  1195. } else {
  1196. method = 1;
  1197. }
  1198. generateRandomData(data, length);
  1199. }
  1200. #endif // !__MINGW32__
  1201. }
  1202. bool saveAs
  1203. (const std::string& filename, const std::string& data, bool overwrite)
  1204. {
  1205. if(!overwrite && File(filename).exists()) {
  1206. return false;
  1207. }
  1208. std::string tempFilename = filename;
  1209. tempFilename += "__temp";
  1210. {
  1211. BufferedFile fp(tempFilename.c_str(), BufferedFile::WRITE);
  1212. if(!fp) {
  1213. return false;
  1214. }
  1215. if(fp.write(data.data(), data.size()) != data.size()) {
  1216. return false;
  1217. }
  1218. if(fp.close() == EOF) {
  1219. return false;
  1220. }
  1221. }
  1222. return File(tempFilename).renameTo(filename);
  1223. }
  1224. std::string applyDir(const std::string& dir, const std::string& relPath)
  1225. {
  1226. std::string s;
  1227. if(dir.empty()) {
  1228. s = "./";
  1229. s += relPath;
  1230. } else {
  1231. s = dir;
  1232. if(dir == "/") {
  1233. s += relPath;
  1234. } else {
  1235. s += "/";
  1236. s += relPath;
  1237. }
  1238. }
  1239. #ifdef __MINGW32__
  1240. for(std::string::iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) {
  1241. if(*i == '\\') {
  1242. *i = '/';
  1243. }
  1244. }
  1245. #endif // __MINGW32__
  1246. return s;
  1247. }
  1248. std::string fixTaintedBasename(const std::string& src)
  1249. {
  1250. return escapePath(replace(src, "/", "%2F"));
  1251. }
  1252. void generateRandomKey(unsigned char* key)
  1253. {
  1254. #ifdef ENABLE_MESSAGE_DIGEST
  1255. unsigned char bytes[40];
  1256. generateRandomData(bytes, sizeof(bytes));
  1257. message_digest::digest(key, 20, MessageDigest::sha1(), bytes, sizeof(bytes));
  1258. #else // !ENABLE_MESSAGE_DIGEST
  1259. generateRandomData(key, 20);
  1260. #endif // !ENABLE_MESSAGE_DIGEST
  1261. }
  1262. // Returns true is given numeric ipv4addr is in Private Address Space.
  1263. //
  1264. // From Section.3 RFC1918
  1265. // 10.0.0.0 - 10.255.255.255 (10/8 prefix)
  1266. // 172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
  1267. // 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
  1268. bool inPrivateAddress(const std::string& ipv4addr)
  1269. {
  1270. if(util::startsWith(ipv4addr, "10.") ||
  1271. util::startsWith(ipv4addr, "192.168.")) {
  1272. return true;
  1273. }
  1274. if(util::startsWith(ipv4addr, "172.")) {
  1275. for(int i = 16; i <= 31; ++i) {
  1276. std::string t(fmt("%d.", i));
  1277. if(util::startsWith(ipv4addr.begin()+4, ipv4addr.end(),
  1278. t.begin(), t.end())) {
  1279. return true;
  1280. }
  1281. }
  1282. }
  1283. return false;
  1284. }
  1285. bool detectDirTraversal(const std::string& s)
  1286. {
  1287. if(s.empty()) {
  1288. return false;
  1289. }
  1290. for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) {
  1291. unsigned char c = *i;
  1292. if(in(c, 0x00u, 0x1fu) || c == 0x7fu) {
  1293. return true;
  1294. }
  1295. }
  1296. return s == "." || s == ".." || s[0] == '/' ||
  1297. util::startsWith(s, "./") || util::startsWith(s, "../") ||
  1298. s.find("/../") != std::string::npos ||
  1299. s.find("/./") != std::string::npos ||
  1300. s[s.size()-1] == '/' ||
  1301. util::endsWith(s, "/.") || util::endsWith(s, "/..");
  1302. }
  1303. std::string escapePath(const std::string& s)
  1304. {
  1305. // We don't escape '/' because we use it as a path separator.
  1306. #ifdef __MINGW32__
  1307. static const char WIN_INVALID_PATH_CHARS[] =
  1308. { '"', '*', ':', '<', '>', '?', '\\', '|' };
  1309. #endif // __MINGW32__
  1310. std::string d;
  1311. for(std::string::const_iterator i = s.begin(), eoi = s.end(); i != eoi; ++i) {
  1312. unsigned char c = *i;
  1313. if(in(c, 0x00u, 0x1fu) || c == 0x7fu
  1314. #ifdef __MINGW32__
  1315. || std::find(vbegin(WIN_INVALID_PATH_CHARS),
  1316. vend(WIN_INVALID_PATH_CHARS),
  1317. c) != vend(WIN_INVALID_PATH_CHARS)
  1318. #endif // __MINGW32__
  1319. ){
  1320. d += fmt("%%%02X", c);
  1321. } else {
  1322. d += *i;
  1323. }
  1324. }
  1325. return d;
  1326. }
  1327. bool inSameCidrBlock
  1328. (const std::string& ip1, const std::string& ip2, size_t bits)
  1329. {
  1330. unsigned char s1[16], s2[16];
  1331. size_t len1, len2;
  1332. if((len1 = net::getBinAddr(s1, ip1)) == 0 ||
  1333. (len2 = net::getBinAddr(s2, ip2)) == 0 ||
  1334. len1 != len2) {
  1335. return false;
  1336. }
  1337. if(bits == 0) {
  1338. return true;
  1339. }
  1340. if(bits > 8*len1) {
  1341. bits = 8*len1;
  1342. }
  1343. int last = (bits-1)/8;
  1344. for(int i = 0; i < last; ++i) {
  1345. if(s1[i] != s2[i]) {
  1346. return false;
  1347. }
  1348. }
  1349. unsigned char mask = bitfield::lastByteMask(bits);
  1350. return (s1[last] & mask) == (s2[last] & mask);
  1351. }
  1352. namespace {
  1353. void executeHook
  1354. (const std::string& command,
  1355. a2_gid_t gid,
  1356. size_t numFiles,
  1357. const std::string& firstFilename)
  1358. {
  1359. const std::string gidStr = util::itos(gid);
  1360. const std::string numFilesStr = util::uitos(numFiles);
  1361. #ifndef __MINGW32__
  1362. A2_LOG_INFO(fmt("Executing user command: %s %s %s %s",
  1363. command.c_str(),
  1364. gidStr.c_str(),
  1365. numFilesStr.c_str(),
  1366. firstFilename.c_str()));
  1367. pid_t cpid = fork();
  1368. if(cpid == -1) {
  1369. A2_LOG_ERROR("fork() failed. Cannot execute user command.");
  1370. } else if(cpid == 0) {
  1371. execlp(command.c_str(),
  1372. command.c_str(),
  1373. gidStr.c_str(),
  1374. numFilesStr.c_str(),
  1375. firstFilename.c_str(),
  1376. reinterpret_cast<char*>(0));
  1377. perror(("Could not execute user command: "+command).c_str());
  1378. exit(EXIT_FAILURE);
  1379. }
  1380. #else
  1381. PROCESS_INFORMATION pi;
  1382. STARTUPINFOW si;
  1383. memset(&si, 0, sizeof (si));
  1384. si.cb = sizeof(STARTUPINFO);
  1385. memset(&pi, 0, sizeof (pi));
  1386. bool batch = util::iendsWith(command, ".bat");
  1387. std::string cmdline;
  1388. std::string cmdexe;
  1389. if(batch) {
  1390. const char* p = getenv("windir");
  1391. if(p) {
  1392. cmdexe = p;
  1393. cmdexe += "\\system32\\cmd.exe";
  1394. } else {
  1395. A2_LOG_INFO("Failed to get windir environment variable."
  1396. " Executing batch file will fail.");
  1397. // TODO Might be useless.
  1398. cmdexe = "cmd.exe";
  1399. }
  1400. cmdline += "/C \"";
  1401. }
  1402. cmdline += "\"";
  1403. cmdline += command;
  1404. cmdline += "\"";
  1405. cmdline += " ";
  1406. cmdline += gidStr;
  1407. cmdline += " ";
  1408. cmdline += numFilesStr;
  1409. cmdline += " \"";
  1410. cmdline += firstFilename;
  1411. cmdline += "\"";
  1412. if(batch) {
  1413. cmdline += "\"";
  1414. }
  1415. int cmdlineLen = utf8ToWChar(0, 0, cmdline.c_str());
  1416. assert(cmdlineLen > 0);
  1417. array_ptr<wchar_t> wcharCmdline(new wchar_t[cmdlineLen]);
  1418. cmdlineLen = utf8ToWChar(wcharCmdline, cmdlineLen, cmdline.c_str());
  1419. assert(cmdlineLen > 0);
  1420. A2_LOG_INFO(fmt("Executing user command: %s", cmdline.c_str()));
  1421. DWORD rc = CreateProcessW(batch ? utf8ToWChar(cmdexe).c_str() : NULL,
  1422. wcharCmdline,
  1423. NULL,
  1424. NULL,
  1425. true,
  1426. 0,
  1427. NULL,
  1428. 0,
  1429. &si,
  1430. &pi);
  1431. if(!rc) {
  1432. A2_LOG_ERROR("CreateProcess() failed. Cannot execute user command.");
  1433. }
  1434. #endif
  1435. }
  1436. } // namespace
  1437. void executeHookByOptName
  1438. (const SharedHandle<RequestGroup>& group, const Option* option,
  1439. const Pref* pref)
  1440. {
  1441. executeHookByOptName(group.get(), option, pref);
  1442. }
  1443. void executeHookByOptName
  1444. (const RequestGroup* group, const Option* option, const Pref* pref)
  1445. {
  1446. const std::string& cmd = option->get(pref);
  1447. if(!cmd.empty()) {
  1448. const SharedHandle<DownloadContext> dctx = group->getDownloadContext();
  1449. std::string firstFilename;
  1450. size_t numFiles = 0;
  1451. if(!group->inMemoryDownload()) {
  1452. SharedHandle<FileEntry> file = dctx->getFirstRequestedFileEntry();
  1453. if(file) {
  1454. firstFilename = file->getPath();
  1455. }
  1456. numFiles = dctx->countRequestedFileEntry();
  1457. }
  1458. executeHook(cmd, group->getGID(), numFiles, firstFilename);
  1459. }
  1460. }
  1461. std::string createSafePath
  1462. (const std::string& dir, const std::string& filename)
  1463. {
  1464. return util::applyDir
  1465. (dir,
  1466. util::isUtf8(filename)?
  1467. util::fixTaintedBasename(filename):
  1468. util::escapePath(util::percentEncode(filename)));
  1469. }
  1470. std::string encodeNonUtf8(const std::string& s)
  1471. {
  1472. return util::isUtf8(s)?s:util::percentEncode(s);
  1473. }
  1474. std::string makeString(const char* str)
  1475. {
  1476. if(str) {
  1477. return str;
  1478. } else {
  1479. return A2STR::NIL;
  1480. }
  1481. }
  1482. std::string safeStrerror(int errNum)
  1483. {
  1484. return makeString(strerror(errNum));
  1485. }
  1486. bool noProxyDomainMatch
  1487. (const std::string& hostname,
  1488. const std::string& domain)
  1489. {
  1490. if(!domain.empty() && domain[0] == '.' && !util::isNumericHost(hostname)) {
  1491. return util::endsWith(hostname, domain);
  1492. } else {
  1493. return hostname == domain;
  1494. }
  1495. }
  1496. bool tlsHostnameMatch(const std::string& pattern, const std::string& hostname)
  1497. {
  1498. std::string::const_iterator ptWildcard = std::find(pattern.begin(),
  1499. pattern.end(),
  1500. '*');
  1501. if(ptWildcard == pattern.end()) {
  1502. return strieq(pattern.begin(), pattern.end(),
  1503. hostname.begin(), hostname.end());
  1504. }
  1505. std::string::const_iterator ptLeftLabelEnd = std::find(pattern.begin(),
  1506. pattern.end(),
  1507. '.');
  1508. bool wildcardEnabled = true;
  1509. // Do case-insensitive match. At least 2 dots are required to enable
  1510. // wildcard match. Also wildcard must be in the left-most label.
  1511. // Don't attempt to match a presented identifier where the wildcard
  1512. // character is embedded within an A-label.
  1513. if(ptLeftLabelEnd == pattern.end() ||
  1514. std::find(ptLeftLabelEnd+1, pattern.end(), '.') == pattern.end() ||
  1515. ptLeftLabelEnd < ptWildcard ||
  1516. istartsWith(pattern, "xn--")) {
  1517. wildcardEnabled = false;
  1518. }
  1519. if(!wildcardEnabled) {
  1520. return strieq(pattern.begin(), pattern.end(),
  1521. hostname.begin(), hostname.end());
  1522. }
  1523. std::string::const_iterator hnLeftLabelEnd = std::find(hostname.begin(),
  1524. hostname.end(),
  1525. '.');
  1526. if(!strieq(ptLeftLabelEnd, pattern.end(), hnLeftLabelEnd, hostname.end())) {
  1527. return false;
  1528. }
  1529. // Perform wildcard match. Here '*' must match at least one
  1530. // character.
  1531. if(hnLeftLabelEnd - hostname.begin() < ptLeftLabelEnd - pattern.begin()) {
  1532. return false;
  1533. }
  1534. return
  1535. istartsWith(hostname.begin(), hnLeftLabelEnd,
  1536. pattern.begin(), ptWildcard) &&
  1537. iendsWith(hostname.begin(), hnLeftLabelEnd,
  1538. ptWildcard+1, ptLeftLabelEnd);
  1539. }
  1540. bool strieq(const std::string& a, const char* b)
  1541. {
  1542. return strieq(a.begin(), a.end(), b);
  1543. }
  1544. bool strieq(const std::string& a, const std::string& b)
  1545. {
  1546. return strieq(a.begin(), a.end(), b.begin(), b.end());
  1547. }
  1548. bool startsWith(const std::string& a, const char* b)
  1549. {
  1550. return startsWith(a.begin(), a.end(), b);
  1551. }
  1552. bool startsWith(const std::string& a, const std::string& b)
  1553. {
  1554. return startsWith(a.begin(), a.end(), b.begin(), b.end());
  1555. }
  1556. bool istartsWith(const std::string& a, const char* b)
  1557. {
  1558. return istartsWith(a.begin(), a.end(), b);
  1559. }
  1560. bool endsWith(const std::string& a, const char* b)
  1561. {
  1562. return endsWith(a.begin(), a.end(), b, b+strlen(b));
  1563. }
  1564. bool endsWith(const std::string& a, const std::string& b)
  1565. {
  1566. return endsWith(a.begin(), a.end(), b.begin(), b.end());
  1567. }
  1568. bool iendsWith(const std::string& a, const char* b)
  1569. {
  1570. return iendsWith(a.begin(), a.end(), b, b+strlen(b));
  1571. }
  1572. bool iendsWith(const std::string& a, const std::string& b)
  1573. {
  1574. return iendsWith(a.begin(), a.end(), b.begin(), b.end());
  1575. }
  1576. bool strless(const char* a, const char* b)
  1577. {
  1578. return strcmp(a, b) < 0;
  1579. }
  1580. } // namespace util
  1581. } // namespace aria2