util.cc 27 KB

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