util.cc 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  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 <limits.h>
  38. #include <stdint.h>
  39. #include <cerrno>
  40. #include <cassert>
  41. #include <cstring>
  42. #include <cstdio>
  43. #include <cstdlib>
  44. #include <sstream>
  45. #include <ostream>
  46. #include <algorithm>
  47. #include <fstream>
  48. #include <iomanip>
  49. #ifndef HAVE_SLEEP
  50. # ifdef HAVE_WINSOCK_H
  51. # define WIN32_LEAN_AND_MEAN
  52. # include <windows.h>
  53. # endif // HAVE_WINSOCK_H
  54. #endif // HAVE_SLEEP
  55. #ifdef HAVE_LIBGCRYPT
  56. # include <gcrypt.h>
  57. #elif HAVE_LIBSSL
  58. # include <openssl/rand.h>
  59. # include "SimpleRandomizer.h"
  60. #endif // HAVE_LIBSSL
  61. #include "File.h"
  62. #include "message.h"
  63. #include "Randomizer.h"
  64. #include "a2netcompat.h"
  65. #include "DlAbortEx.h"
  66. #include "BitfieldMan.h"
  67. #include "DefaultDiskWriter.h"
  68. #include "FatalException.h"
  69. #include "FileEntry.h"
  70. #include "StringFormat.h"
  71. #include "A2STR.h"
  72. #include "array_fun.h"
  73. #include "a2functional.h"
  74. #ifdef ENABLE_MESSAGE_DIGEST
  75. # include "MessageDigestHelper.h"
  76. #endif // ENABLE_MESSAGE_DIGEST
  77. // For libc6 which doesn't define ULLONG_MAX properly because of broken limits.h
  78. #ifndef ULLONG_MAX
  79. # define ULLONG_MAX 18446744073709551615ULL
  80. #endif // ULLONG_MAX
  81. namespace aria2 {
  82. namespace util {
  83. const std::string DEFAULT_TRIM_CHARSET("\r\n\t ");
  84. std::string trim(const std::string& src, const std::string& trimCharset)
  85. {
  86. std::string temp(src);
  87. trimSelf(temp, trimCharset);
  88. return temp;
  89. }
  90. void trimSelf(std::string& str, const std::string& trimCharset)
  91. {
  92. std::string::size_type first = str.find_first_not_of(trimCharset);
  93. if(first == std::string::npos) {
  94. str.clear();
  95. } else {
  96. std::string::size_type last = str.find_last_not_of(trimCharset)+1;
  97. str.erase(last);
  98. str.erase(0, first);
  99. }
  100. }
  101. void split(std::pair<std::string, std::string>& hp, const std::string& src, char delim)
  102. {
  103. hp.first = A2STR::NIL;
  104. hp.second = A2STR::NIL;
  105. std::string::size_type p = src.find(delim);
  106. if(p == std::string::npos) {
  107. hp.first = src;
  108. hp.second = A2STR::NIL;
  109. } else {
  110. hp.first = trim(src.substr(0, p));
  111. hp.second = trim(src.substr(p+1));
  112. }
  113. }
  114. std::pair<std::string, std::string> split(const std::string& src, const std::string& delims)
  115. {
  116. std::pair<std::string, std::string> hp;
  117. hp.first = A2STR::NIL;
  118. hp.second = A2STR::NIL;
  119. std::string::size_type p = src.find_first_of(delims);
  120. if(p == std::string::npos) {
  121. hp.first = src;
  122. hp.second = A2STR::NIL;
  123. } else {
  124. hp.first = trim(src.substr(0, p));
  125. hp.second = trim(src.substr(p+1));
  126. }
  127. return hp;
  128. }
  129. int64_t difftv(struct timeval tv1, struct timeval tv2) {
  130. if((tv1.tv_sec < tv2.tv_sec) ||
  131. ((tv1.tv_sec == tv2.tv_sec) && (tv1.tv_usec < tv2.tv_usec))) {
  132. return 0;
  133. }
  134. return ((int64_t)(tv1.tv_sec-tv2.tv_sec)*1000000+
  135. tv1.tv_usec-tv2.tv_usec);
  136. }
  137. int32_t difftvsec(struct timeval tv1, struct timeval tv2) {
  138. if(tv1.tv_sec < tv2.tv_sec) {
  139. return 0;
  140. }
  141. return tv1.tv_sec-tv2.tv_sec;
  142. }
  143. bool startsWith(const std::string& target, const std::string& part) {
  144. if(target.size() < part.size()) {
  145. return false;
  146. }
  147. if(part.empty()) {
  148. return true;
  149. }
  150. if(target.find(part) == 0) {
  151. return true;
  152. } else {
  153. return false;
  154. }
  155. }
  156. bool endsWith(const std::string& target, const std::string& part) {
  157. if(target.size() < part.size()) {
  158. return false;
  159. }
  160. if(part.empty()) {
  161. return true;
  162. }
  163. if(target.rfind(part) == target.size()-part.size()) {
  164. return true;
  165. } else {
  166. return false;
  167. }
  168. }
  169. std::string replace(const std::string& target, const std::string& oldstr, const std::string& newstr) {
  170. if(target.empty() || oldstr.empty()) {
  171. return target;
  172. }
  173. std::string result;
  174. std::string::size_type p = 0;
  175. std::string::size_type np = target.find(oldstr);
  176. while(np != std::string::npos) {
  177. result += target.substr(p, np-p);
  178. result += newstr;
  179. p = np+oldstr.size();
  180. np = target.find(oldstr, p);
  181. }
  182. result += target.substr(p);
  183. return result;
  184. }
  185. bool inRFC3986ReservedChars(const char c)
  186. {
  187. static const char reserved[] = {
  188. ':' , '/' , '?' , '#' , '[' , ']' , '@',
  189. '!' , '$' , '&' , '\'' , '(' , ')',
  190. '*' , '+' , ',' , ';' , '=' };
  191. return std::find(&reserved[0], &reserved[arrayLength(reserved)], c) !=
  192. &reserved[arrayLength(reserved)];
  193. }
  194. bool inRFC3986UnreservedChars(const char c)
  195. {
  196. static const char unreserved[] = { '-', '.', '_', '~' };
  197. return
  198. // ALPHA
  199. ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') ||
  200. // DIGIT
  201. ('0' <= c && c <= '9') ||
  202. std::find(&unreserved[0], &unreserved[arrayLength(unreserved)], c) !=
  203. &unreserved[arrayLength(unreserved)];
  204. }
  205. std::string urlencode(const unsigned char* target, size_t len) {
  206. std::string dest;
  207. for(size_t i = 0; i < len; ++i) {
  208. if(!inRFC3986UnreservedChars(target[i])) {
  209. dest.append(StringFormat("%%%02X", target[i]).str());
  210. } else {
  211. dest += target[i];
  212. }
  213. }
  214. return dest;
  215. }
  216. std::string urlencode(const std::string& target)
  217. {
  218. return urlencode(reinterpret_cast<const unsigned char*>(target.c_str()),
  219. target.size());
  220. }
  221. std::string torrentUrlencode(const unsigned char* target, size_t len) {
  222. std::string dest;
  223. for(size_t i = 0; i < len; ++i) {
  224. if(('0' <= target[i] && target[i] <= '9') ||
  225. ('A' <= target[i] && target[i] <= 'Z') ||
  226. ('a' <= target[i] && target[i] <= 'z')) {
  227. dest += target[i];
  228. } else {
  229. dest.append(StringFormat("%%%02X", target[i]).str());
  230. }
  231. }
  232. return dest;
  233. }
  234. std::string torrentUrlencode(const std::string& target)
  235. {
  236. return torrentUrlencode
  237. (reinterpret_cast<const unsigned char*>(target.c_str()), target.size());
  238. }
  239. std::string urldecode(const std::string& target) {
  240. std::string result;
  241. for(std::string::const_iterator itr = target.begin();
  242. itr != target.end(); ++itr) {
  243. if(*itr == '%') {
  244. if(itr+1 != target.end() && itr+2 != target.end() &&
  245. isxdigit(*(itr+1)) && isxdigit(*(itr+2))) {
  246. result += parseInt(std::string(itr+1, itr+3), 16);
  247. itr += 2;
  248. } else {
  249. result += *itr;
  250. }
  251. } else {
  252. result += *itr;
  253. }
  254. }
  255. return result;
  256. }
  257. std::string toHex(const unsigned char* src, size_t len) {
  258. char* temp = new char[len*2+1];
  259. for(size_t i = 0; i < len; ++i) {
  260. sprintf(temp+i*2, "%02x", src[i]);
  261. }
  262. temp[len*2] = '\0';
  263. std::string hex = temp;
  264. delete [] temp;
  265. return hex;
  266. }
  267. std::string toHex(const char* src, size_t len)
  268. {
  269. return toHex(reinterpret_cast<const unsigned char*>(src), len);
  270. }
  271. std::string toHex(const std::string& src)
  272. {
  273. return toHex(reinterpret_cast<const unsigned char*>(src.c_str()), src.size());
  274. }
  275. static unsigned int hexCharToUInt(unsigned char ch)
  276. {
  277. if('a' <= ch && ch <= 'f') {
  278. ch -= 'a';
  279. ch += 10;
  280. } else if('A' <= ch && ch <= 'F') {
  281. ch -= 'A';
  282. ch += 10;
  283. } else if('0' <= ch && ch <= '9') {
  284. ch -= '0';
  285. } else {
  286. ch = 255;
  287. }
  288. return ch;
  289. }
  290. std::string fromHex(const std::string& src)
  291. {
  292. std::string dest;
  293. if(src.size()%2) {
  294. return dest;
  295. }
  296. for(size_t i = 0; i < src.size(); i += 2) {
  297. unsigned char high = hexCharToUInt(src[i]);
  298. unsigned char low = hexCharToUInt(src[i+1]);
  299. if(high == 255 || low == 255) {
  300. dest.clear();
  301. return dest;
  302. }
  303. dest += (high*16+low);
  304. }
  305. return dest;
  306. }
  307. FILE* openFile(const std::string& filename, const std::string& mode) {
  308. FILE* file = fopen(filename.c_str(), mode.c_str());
  309. return file;
  310. }
  311. bool isPowerOf(int num, int base) {
  312. if(base <= 0) { return false; }
  313. if(base == 1) { return true; }
  314. while(num%base == 0) {
  315. num /= base;
  316. if(num == 1) {
  317. return true;
  318. }
  319. }
  320. return false;
  321. }
  322. std::string secfmt(time_t sec) {
  323. std::string str;
  324. if(sec >= 3600) {
  325. str = itos(sec/3600);
  326. str += "h";
  327. sec %= 3600;
  328. }
  329. if(sec >= 60) {
  330. int min = sec/60;
  331. if(min < 10) {
  332. str += "0";
  333. }
  334. str += itos(min);
  335. str += "m";
  336. sec %= 60;
  337. }
  338. if(sec < 10) {
  339. str += "0";
  340. }
  341. str += itos(sec);
  342. str += "s";
  343. return str;
  344. }
  345. int getNum(const char* buf, int offset, size_t length) {
  346. char* temp = new char[length+1];
  347. memcpy(temp, buf+offset, length);
  348. temp[length] = '\0';
  349. int x = strtol(temp, 0, 10);
  350. delete [] temp;
  351. return x;
  352. }
  353. int32_t parseInt(const std::string& s, int32_t base)
  354. {
  355. std::string trimed = trim(s);
  356. if(trimed.empty()) {
  357. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  358. "empty string").str());
  359. }
  360. char* stop;
  361. errno = 0;
  362. long int v = strtol(trimed.c_str(), &stop, base);
  363. if(*stop != '\0') {
  364. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  365. trimed.c_str()).str());
  366. } else if((((v == LONG_MIN) || (v == LONG_MAX)) && (errno == ERANGE)) ||
  367. (v > INT32_MAX) ||
  368. (v < INT32_MIN)) {
  369. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  370. trimed.c_str()).str());
  371. }
  372. return v;
  373. }
  374. uint32_t parseUInt(const std::string& s, int base)
  375. {
  376. std::string trimed = trim(s);
  377. if(trimed.empty()) {
  378. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  379. "empty string").str());
  380. }
  381. // We don't allow negative number.
  382. if(trimed[0] == '-') {
  383. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  384. trimed.c_str()).str());
  385. }
  386. char* stop;
  387. errno = 0;
  388. unsigned long int v = strtoul(trimed.c_str(), &stop, base);
  389. if(*stop != '\0') {
  390. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  391. trimed.c_str()).str());
  392. } else if(((v == ULONG_MAX) && (errno == ERANGE)) || (v > UINT32_MAX)) {
  393. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  394. trimed.c_str()).str());
  395. }
  396. return v;
  397. }
  398. bool parseUIntNoThrow(uint32_t& result, const std::string& s, int base)
  399. {
  400. std::string trimed = trim(s);
  401. if(trimed.empty()) {
  402. return false;
  403. }
  404. // We don't allow negative number.
  405. if(trimed[0] == '-') {
  406. return false;
  407. }
  408. char* stop;
  409. errno = 0;
  410. unsigned long int v = strtoul(trimed.c_str(), &stop, base);
  411. if(*stop != '\0') {
  412. return false;
  413. } else if(((v == ULONG_MAX) && (errno == ERANGE)) || (v > UINT32_MAX)) {
  414. return false;
  415. }
  416. result = v;
  417. return true;
  418. }
  419. int64_t parseLLInt(const std::string& s, int32_t base)
  420. {
  421. std::string trimed = trim(s);
  422. if(trimed.empty()) {
  423. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  424. "empty string").str());
  425. }
  426. char* stop;
  427. errno = 0;
  428. int64_t v = strtoll(trimed.c_str(), &stop, base);
  429. if(*stop != '\0') {
  430. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  431. trimed.c_str()).str());
  432. } else if(((v == INT64_MIN) || (v == INT64_MAX)) && (errno == ERANGE)) {
  433. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  434. trimed.c_str()).str());
  435. }
  436. return v;
  437. }
  438. uint64_t parseULLInt(const std::string& s, int base)
  439. {
  440. std::string trimed = trim(s);
  441. if(trimed.empty()) {
  442. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  443. "empty string").str());
  444. }
  445. // We don't allow negative number.
  446. if(trimed[0] == '-') {
  447. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  448. trimed.c_str()).str());
  449. }
  450. char* stop;
  451. errno = 0;
  452. uint64_t v = strtoull(trimed.c_str(), &stop, base);
  453. if(*stop != '\0') {
  454. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  455. trimed.c_str()).str());
  456. } else if((v == ULLONG_MAX) && (errno == ERANGE)) {
  457. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  458. trimed.c_str()).str());
  459. }
  460. return v;
  461. }
  462. IntSequence parseIntRange(const std::string& src)
  463. {
  464. IntSequence::Values values;
  465. std::string temp = src;
  466. while(temp.size()) {
  467. std::pair<std::string, std::string> p = split(temp, ",");
  468. temp = p.second;
  469. if(p.first.empty()) {
  470. continue;
  471. }
  472. if(p.first.find("-") == std::string::npos) {
  473. int32_t v = parseInt(p.first.c_str());
  474. values.push_back(IntSequence::Value(v, v+1));
  475. } else {
  476. std::pair<std::string, std::string> vp = split(p.first.c_str(), "-");
  477. if(vp.first.empty() || vp.second.empty()) {
  478. throw DL_ABORT_EX
  479. (StringFormat(MSG_INCOMPLETE_RANGE, p.first.c_str()).str());
  480. }
  481. int32_t v1 = parseInt(vp.first.c_str());
  482. int32_t v2 = parseInt(vp.second.c_str());
  483. values.push_back(IntSequence::Value(v1, v2+1));
  484. }
  485. }
  486. return values;
  487. }
  488. static void computeHeadPieces
  489. (std::vector<size_t>& indexes,
  490. const std::vector<SharedHandle<FileEntry> >& fileEntries,
  491. size_t pieceLength,
  492. uint64_t head)
  493. {
  494. if(head == 0) {
  495. return;
  496. }
  497. for(std::vector<SharedHandle<FileEntry> >::const_iterator fi =
  498. fileEntries.begin(); fi != fileEntries.end(); ++fi) {
  499. if((*fi)->getLength() == 0) {
  500. continue;
  501. }
  502. size_t lastIndex =
  503. ((*fi)->getOffset()+std::min(head, (*fi)->getLength())-1)/pieceLength;
  504. for(size_t index = (*fi)->getOffset()/pieceLength;
  505. index <= lastIndex; ++index) {
  506. indexes.push_back(index);
  507. }
  508. }
  509. }
  510. static void computeTailPieces
  511. (std::vector<size_t>& indexes,
  512. const std::vector<SharedHandle<FileEntry> >& fileEntries,
  513. size_t pieceLength,
  514. uint64_t tail)
  515. {
  516. if(tail == 0) {
  517. return;
  518. }
  519. for(std::vector<SharedHandle<FileEntry> >::const_iterator fi =
  520. fileEntries.begin(); fi != fileEntries.end(); ++fi) {
  521. if((*fi)->getLength() == 0) {
  522. continue;
  523. }
  524. uint64_t endOffset = (*fi)->getLastOffset();
  525. size_t fromIndex =
  526. (endOffset-1-(std::min(tail, (*fi)->getLength())-1))/pieceLength;
  527. for(size_t index = fromIndex; index <= (endOffset-1)/pieceLength;
  528. ++index) {
  529. indexes.push_back(index);
  530. }
  531. }
  532. }
  533. void parsePrioritizePieceRange
  534. (std::vector<size_t>& result, const std::string& src,
  535. const std::vector<SharedHandle<FileEntry> >& fileEntries,
  536. size_t pieceLength,
  537. uint64_t defaultSize)
  538. {
  539. std::vector<size_t> indexes;
  540. std::vector<std::string> parts;
  541. split(src, std::back_inserter(parts), ",", true);
  542. for(std::vector<std::string>::const_iterator i = parts.begin();
  543. i != parts.end(); ++i) {
  544. if((*i) == "head") {
  545. computeHeadPieces(indexes, fileEntries, pieceLength, defaultSize);
  546. } else if(util::startsWith(*i, "head=")) {
  547. std::string sizestr = std::string((*i).begin()+(*i).find("=")+1,
  548. (*i).end());
  549. computeHeadPieces(indexes, fileEntries, pieceLength,
  550. std::max((int64_t)0, getRealSize(sizestr)));
  551. } else if((*i) == "tail") {
  552. computeTailPieces(indexes, fileEntries, pieceLength, defaultSize);
  553. } else if(util::startsWith(*i, "tail=")) {
  554. std::string sizestr = std::string((*i).begin()+(*i).find("=")+1,
  555. (*i).end());
  556. computeTailPieces(indexes, fileEntries, pieceLength,
  557. std::max((int64_t)0, getRealSize(sizestr)));
  558. } else {
  559. throw DL_ABORT_EX
  560. (StringFormat("Unrecognized token %s", (*i).c_str()).str());
  561. }
  562. }
  563. std::sort(indexes.begin(), indexes.end());
  564. indexes.erase(std::unique(indexes.begin(), indexes.end()), indexes.end());
  565. result.insert(result.end(), indexes.begin(), indexes.end());
  566. }
  567. std::string getContentDispositionFilename(const std::string& header) {
  568. static const std::string keyName = "filename=";
  569. std::string::size_type attributesp = header.find(keyName);
  570. if(attributesp == std::string::npos) {
  571. return A2STR::NIL;
  572. }
  573. std::string::size_type filenamesp = attributesp+keyName.size();
  574. std::string::size_type filenameep;
  575. if(filenamesp == header.size()) {
  576. return A2STR::NIL;
  577. }
  578. if(header[filenamesp] == '\'' || header[filenamesp] == '"') {
  579. char quoteChar = header[filenamesp];
  580. filenameep = header.find(quoteChar, filenamesp+1);
  581. } else {
  582. filenameep = header.find(';', filenamesp);
  583. }
  584. if(filenameep == std::string::npos) {
  585. filenameep = header.size();
  586. }
  587. static const std::string TRIMMED("\r\n '\"");
  588. std::string fn =
  589. File(trim(header.substr
  590. (filenamesp, filenameep-filenamesp), TRIMMED)).getBasename();
  591. if(fn == ".." || fn == A2STR::DOT_C) {
  592. return A2STR::NIL;
  593. } else {
  594. return fn;
  595. }
  596. }
  597. std::string randomAlpha(size_t length, const RandomizerHandle& randomizer) {
  598. static const char *random_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  599. std::string str;
  600. for(size_t i = 0; i < length; ++i) {
  601. size_t index = randomizer->getRandomNumber(strlen(random_chars));
  602. str += random_chars[index];
  603. }
  604. return str;
  605. }
  606. std::string toUpper(const std::string& src) {
  607. std::string temp = src;
  608. std::transform(temp.begin(), temp.end(), temp.begin(), ::toupper);
  609. return temp;
  610. }
  611. std::string toLower(const std::string& src) {
  612. std::string temp = src;
  613. std::transform(temp.begin(), temp.end(), temp.begin(), ::tolower);
  614. return temp;
  615. }
  616. bool isNumericHost(const std::string& name)
  617. {
  618. struct addrinfo hints;
  619. struct addrinfo* res;
  620. memset(&hints, 0, sizeof(hints));
  621. hints.ai_family = AF_UNSPEC;
  622. hints.ai_flags = AI_NUMERICHOST;
  623. if(getaddrinfo(name.c_str(), 0, &hints, &res)) {
  624. return false;
  625. }
  626. freeaddrinfo(res);
  627. return true;
  628. }
  629. void setGlobalSignalHandler(int sig, void (*handler)(int), int flags) {
  630. #ifdef HAVE_SIGACTION
  631. struct sigaction sigact;
  632. sigact.sa_handler = handler;
  633. sigact.sa_flags = flags;
  634. sigemptyset(&sigact.sa_mask);
  635. sigaction(sig, &sigact, NULL);
  636. #else
  637. signal(sig, handler);
  638. #endif // HAVE_SIGACTION
  639. }
  640. std::string getHomeDir()
  641. {
  642. const char* p = getenv("HOME");
  643. if(p) {
  644. return p;
  645. } else {
  646. return A2STR::NIL;
  647. }
  648. }
  649. int64_t getRealSize(const std::string& sizeWithUnit)
  650. {
  651. std::string::size_type p = sizeWithUnit.find_first_of("KM");
  652. std::string size;
  653. int32_t mult = 1;
  654. if(p == std::string::npos) {
  655. size = sizeWithUnit;
  656. } else {
  657. if(sizeWithUnit[p] == 'K') {
  658. mult = 1024;
  659. } else if(sizeWithUnit[p] == 'M') {
  660. mult = 1024*1024;
  661. }
  662. size = sizeWithUnit.substr(0, p);
  663. }
  664. int64_t v = parseLLInt(size);
  665. if(v < 0) {
  666. throw DL_ABORT_EX
  667. (StringFormat("Negative value detected: %s", sizeWithUnit.c_str()).str());
  668. } else if(INT64_MAX/mult < v) {
  669. throw DL_ABORT_EX(StringFormat(MSG_STRING_INTEGER_CONVERSION_FAILURE,
  670. "overflow/underflow").str());
  671. }
  672. return v*mult;
  673. }
  674. std::string abbrevSize(int64_t size)
  675. {
  676. if(size < 1024) {
  677. return itos(size, true);
  678. }
  679. char units[] = { 'K', 'M' };
  680. size_t numUnit = sizeof(units)/sizeof(char);
  681. size_t i = 0;
  682. int r = size&0x3ff;
  683. size >>= 10;
  684. for(; i < numUnit-1 && size >= 1024; ++i) {
  685. r = size&0x3ff;
  686. size >>= 10;
  687. }
  688. std::string result = itos(size, true);
  689. result += A2STR::DOT_C;
  690. result += itos(r*10/1024);
  691. result += units[i];
  692. result += "i";
  693. return result;
  694. }
  695. void sleep(long seconds) {
  696. #ifdef HAVE_SLEEP
  697. ::sleep(seconds);
  698. #elif defined(HAVE_USLEEP)
  699. ::usleep(seconds * 1000000);
  700. #elif defined(HAVE_WINSOCK2_H)
  701. ::Sleep(seconds * 1000);
  702. #else
  703. #error no sleep function is available (nanosleep?)
  704. #endif
  705. }
  706. void usleep(long microseconds) {
  707. #ifdef HAVE_USLEEP
  708. ::usleep(microseconds);
  709. #elif defined(HAVE_WINSOCK2_H)
  710. LARGE_INTEGER current, freq, end;
  711. static enum {GET_FREQUENCY, GET_MICROSECONDS, SKIP_MICROSECONDS} state = GET_FREQUENCY;
  712. if (state == GET_FREQUENCY) {
  713. if (QueryPerformanceFrequency(&freq))
  714. state = GET_MICROSECONDS;
  715. else
  716. state = SKIP_MICROSECONDS;
  717. }
  718. long msec = microseconds / 1000;
  719. microseconds %= 1000;
  720. if (state == GET_MICROSECONDS && microseconds) {
  721. QueryPerformanceCounter(&end);
  722. end.QuadPart += (freq.QuadPart * microseconds) / 1000000;
  723. while (QueryPerformanceCounter(&current) && (current.QuadPart <= end.QuadPart))
  724. /* noop */ ;
  725. }
  726. if (msec)
  727. Sleep(msec);
  728. #else
  729. #error no usleep function is available (nanosleep?)
  730. #endif
  731. }
  732. bool isNumber(const std::string& what)
  733. {
  734. if(what.empty()) {
  735. return false;
  736. }
  737. for(uint32_t i = 0; i < what.size(); ++i) {
  738. if(!isdigit(what[i])) {
  739. return false;
  740. }
  741. }
  742. return true;
  743. }
  744. bool isLowercase(const std::string& what)
  745. {
  746. if(what.empty()) {
  747. return false;
  748. }
  749. for(uint32_t i = 0; i < what.size(); ++i) {
  750. if(!('a' <= what[i] && what[i] <= 'z')) {
  751. return false;
  752. }
  753. }
  754. return true;
  755. }
  756. bool isUppercase(const std::string& what)
  757. {
  758. if(what.empty()) {
  759. return false;
  760. }
  761. for(uint32_t i = 0; i < what.size(); ++i) {
  762. if(!('A' <= what[i] && what[i] <= 'Z')) {
  763. return false;
  764. }
  765. }
  766. return true;
  767. }
  768. unsigned int alphaToNum(const std::string& alphabets)
  769. {
  770. if(alphabets.empty()) {
  771. return 0;
  772. }
  773. char base;
  774. if(islower(alphabets[0])) {
  775. base = 'a';
  776. } else {
  777. base = 'A';
  778. }
  779. uint64_t num = 0;
  780. for(size_t i = 0; i < alphabets.size(); ++i) {
  781. unsigned int v = alphabets[i]-base;
  782. num = num*26+v;
  783. if(num > UINT32_MAX) {
  784. return 0;
  785. }
  786. }
  787. return num;
  788. }
  789. void mkdirs(const std::string& dirpath)
  790. {
  791. File dir(dirpath);
  792. if(dir.isDir()) {
  793. // do nothing
  794. } else if(dir.exists()) {
  795. throw DL_ABORT_EX
  796. (StringFormat(EX_MAKE_DIR, dir.getPath().c_str(),
  797. "File already exists.").str());
  798. } else if(!dir.mkdirs()) {
  799. throw DL_ABORT_EX
  800. (StringFormat(EX_MAKE_DIR, dir.getPath().c_str(),
  801. strerror(errno)).str());
  802. }
  803. }
  804. void convertBitfield(BitfieldMan* dest, const BitfieldMan* src)
  805. {
  806. size_t numBlock = dest->countBlock();
  807. for(size_t index = 0; index < numBlock; ++index) {
  808. if(src->isBitSetOffsetRange((uint64_t)index*dest->getBlockLength(),
  809. dest->getBlockLength())) {
  810. dest->setBit(index);
  811. }
  812. }
  813. }
  814. std::string toString(const BinaryStreamHandle& binaryStream)
  815. {
  816. std::stringstream strm;
  817. char data[2048];
  818. while(1) {
  819. int32_t dataLength = binaryStream->readData
  820. (reinterpret_cast<unsigned char*>(data), sizeof(data), strm.tellp());
  821. strm.write(data, dataLength);
  822. if(dataLength == 0) {
  823. break;
  824. }
  825. }
  826. return strm.str();
  827. }
  828. #ifdef HAVE_POSIX_MEMALIGN
  829. /**
  830. * In linux 2.6, alignment and size should be a multiple of 512.
  831. */
  832. void* allocateAlignedMemory(size_t alignment, size_t size)
  833. {
  834. void* buffer;
  835. int res;
  836. if((res = posix_memalign(&buffer, alignment, size)) != 0) {
  837. throw FATAL_EXCEPTION
  838. (StringFormat("Error in posix_memalign: %s", strerror(res)).str());
  839. }
  840. return buffer;
  841. }
  842. #endif // HAVE_POSIX_MEMALIGN
  843. std::pair<std::string, uint16_t>
  844. getNumericNameInfo(const struct sockaddr* sockaddr, socklen_t len)
  845. {
  846. char host[NI_MAXHOST];
  847. char service[NI_MAXSERV];
  848. int s = getnameinfo(sockaddr, len, host, NI_MAXHOST, service, NI_MAXSERV,
  849. NI_NUMERICHOST|NI_NUMERICSERV);
  850. if(s != 0) {
  851. throw DL_ABORT_EX(StringFormat("Failed to get hostname and port. cause: %s",
  852. gai_strerror(s)).str());
  853. }
  854. return std::pair<std::string, uint16_t>(host, atoi(service)); // TODO
  855. }
  856. std::string htmlEscape(const std::string& src)
  857. {
  858. std::string dest;
  859. for(std::string::const_iterator i = src.begin(); i != src.end(); ++i) {
  860. char ch = *i;
  861. if(ch == '<') {
  862. dest += "&lt;";
  863. } else if(ch == '>') {
  864. dest += "&gt;";
  865. } else if(ch == '&') {
  866. dest += "&amp;";
  867. } else if(ch == '\'') {
  868. dest += "&#39;";
  869. } else if(ch == '"') {
  870. dest += "&quot;";
  871. } else {
  872. dest += ch;
  873. }
  874. }
  875. return dest;
  876. }
  877. std::map<size_t, std::string>::value_type
  878. parseIndexPath(const std::string& line)
  879. {
  880. std::pair<std::string, std::string> p = split(line, "=");
  881. size_t index = parseUInt(p.first);
  882. if(p.second.empty()) {
  883. throw DL_ABORT_EX(StringFormat("Path with index=%u is empty.",
  884. static_cast<unsigned int>(index)).str());
  885. }
  886. return std::map<size_t, std::string>::value_type(index, p.second);
  887. }
  888. std::map<size_t, std::string> createIndexPathMap(std::istream& i)
  889. {
  890. std::map<size_t, std::string> indexPathMap;
  891. std::string line;
  892. while(getline(i, line)) {
  893. indexPathMap.insert(indexPathMap.begin(), parseIndexPath(line));
  894. }
  895. return indexPathMap;
  896. }
  897. void generateRandomData(unsigned char* data, size_t length)
  898. {
  899. #ifdef HAVE_LIBGCRYPT
  900. gcry_randomize(data, length, GCRY_STRONG_RANDOM);
  901. #elif HAVE_LIBSSL
  902. if(RAND_bytes(data, length) != 1) {
  903. for(size_t i = 0; i < length; ++i) {
  904. data[i] = SimpleRandomizer::getInstance()->getRandomNumber(UINT8_MAX+1);
  905. }
  906. }
  907. #else
  908. std::ifstream i("/dev/urandom", std::ios::binary);
  909. i.read(reinterpret_cast<char*>(data), length);
  910. #endif // HAVE_LIBSSL
  911. }
  912. bool saveAs
  913. (const std::string& filename, const std::string& data, bool overwrite)
  914. {
  915. if(!overwrite && File(filename).exists()) {
  916. return false;
  917. }
  918. std::string tempFilename = strconcat(filename, "__temp");
  919. std::ofstream out(tempFilename.c_str(), std::ios::binary);
  920. if(!out) {
  921. return false;
  922. }
  923. out << data;
  924. out.flush();
  925. if(!out) {
  926. return false;
  927. }
  928. return File(tempFilename).renameTo(filename);
  929. }
  930. std::string applyDir(const std::string& dir, const std::string& relPath)
  931. {
  932. if(dir.empty()) {
  933. return strconcat(A2STR::DOT_C, A2STR::SLASH_C, relPath);
  934. } else if(dir == A2STR::SLASH_C) {
  935. return strconcat(A2STR::SLASH_C, relPath);
  936. } else {
  937. return strconcat(dir, A2STR::SLASH_C, relPath);
  938. }
  939. }
  940. std::string fixTaintedBasename(const std::string& src)
  941. {
  942. return replace(replace(src, A2STR::SLASH_C, A2STR::UNDERSCORE_C),
  943. A2STR::BACK_SLASH_C, A2STR::UNDERSCORE_C);
  944. }
  945. void generateRandomKey(unsigned char* key)
  946. {
  947. #ifdef ENABLE_MESSAGE_DIGEST
  948. unsigned char bytes[40];
  949. generateRandomData(bytes, sizeof(bytes));
  950. MessageDigestHelper::digest
  951. (key, 20, MessageDigestContext::SHA1, bytes, sizeof(bytes));
  952. #else // !ENABLE_MESSAGE_DIGEST
  953. generateRandomData(key, 20);
  954. #endif // !ENABLE_MESSAGE_DIGEST
  955. }
  956. } // namespace util
  957. } // namespace aria2