1 // ==============================================================
2 //This file is part of Glest Shared Library (www.glest.org)
3 //Copyright (C) 2005 Matthias Braun <matze@braunis.de>
4
5 //You can redistribute this code and/or modify it under
6 //the terms of the GNU General Public License as published by the Free Software
7 //Foundation; either version 2 of the License, or (at your option) any later
8 //version.
9
10 #ifdef WIN32
11 #include <winsock2.h>
12 #include <winsock.h>
13 #endif
14
15 #include "platform_common.h"
16 #include "cache_manager.h"
17
18 #ifdef WIN32
19
20 #include <io.h>
21 #include <dbghelp.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <direct.h>
25
26 #else
27
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31
32 #endif
33
34 #if __cplusplus > 199711L
35 #include <chrono>
36 #else
37 #include <time.h>
38 #endif
39
40 #ifdef WIN32
41 #define S_ISDIR(mode) (((mode) & _S_IFDIR) == _S_IFDIR)
42 #elif defined(__GNUC__)
43
44 #else
45 #error "Your compiler needs to support S_IFDIR!"
46 #endif
47
48 #include <iostream>
49 #include <sstream>
50 #include <cassert>
51
52 #include <glob.h>
53 #include <errno.h>
54 #include <string.h>
55
56 #include <SDL.h>
57
58 #include "util.h"
59 #include "conversion.h"
60 #include "leak_dumper.h"
61 #include "sdl_private.h"
62 #include "window.h"
63 #include "noimpl.h"
64
65 #include "checksum.h"
66 #include "socket.h"
67 #include <algorithm>
68 #include <map>
69 #include "randomgen.h"
70 #include <algorithm>
71 #include "platform_util.h"
72 #include "utf8.h"
73 #include "byte_order.h"
74
75 #if _BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
76 #include <unistd.h>
77 #include <sys/types.h>
78 #include <pwd.h>
79 #endif
80
81 #ifdef __APPLE__
82 #include <mach-o/dyld.h>
83 #include <sys/param.h>
84 #endif
85
86 #include "leak_dumper.h"
87
88
89 using namespace Shared::Platform;
90 using namespace Shared::Util;
91 using namespace std;
92
93 #define _DISABLE_MEMORY_VAULT_CHECKS 1
94
95 namespace Shared { namespace PlatformCommon {
96
97 const time_t REFRESH_CRC_DAY_SECONDS = 60 * 60 * 24;
98 static string crcCachePath = "";
99
100 static string gameVersion = "";
101 static string gameGITVersion = "";
102
103 namespace Private {
104
105 bool shouldBeFullscreen = false;
106 int ScreenWidth = 800;
107 int ScreenHeight = 600;
108
109 }
110
111 /*
112 A thread safe localtime proxy
113 */
threadsafe_localtime(const time_t & time)114 tm threadsafe_localtime(const time_t &time) {
115 tm tm_snapshot;
116 #if (defined(WIN32) || defined(_WIN32) || defined(__WIN32__))
117 localtime_s(&tm_snapshot, &time);
118 #else
119 localtime_r(&time, &tm_snapshot); // POSIX
120 #endif
121 return tm_snapshot;
122 }
123
124 // extracting std::time_t from std:chrono for "now"
systemtime_now()125 time_t systemtime_now() {
126 #if __cplusplus > 199711L
127 // typedef std::chrono::time_point<std::chrono::system_clock> system_time_point;
128 typedef std::chrono::time_point<std::chrono::system_clock> system_time_point_x;
129 system_time_point_x system_now = std::chrono::system_clock::now();
130 return std::chrono::system_clock::to_time_t(system_now);
131 #else
132 return time(NULL);
133 #endif
134 }
135
136
137 // =====================================
138 // PerformanceTimer
139 // =====================================
140
init(float fps,int maxTimes)141 void PerformanceTimer::init(float fps, int maxTimes) {
142 this->times = 0;
143 this->maxTimes = maxTimes;
144 this->lastTicks = SDL_GetTicks();
145 this->updateTicks = static_cast<int>(1000.0f / fps);
146 }
147
isTime()148 bool PerformanceTimer::isTime() {
149 Uint32 thisTicks = SDL_GetTicks();
150
151 if((thisTicks - lastTicks) >= updateTicks &&
152 times < maxTimes) {
153
154 lastTicks += updateTicks;
155 times++;
156 return true;
157 }
158 times = 0;
159 return false;
160 }
161
reset()162 void PerformanceTimer::reset() {
163 lastTicks = SDL_GetTicks();
164 }
165
166 // =====================================
167 // Chrono
168 // =====================================
169
Chrono(bool autoStart)170 Chrono::Chrono(bool autoStart) {
171 freq = 1000;
172 stopped = true;
173 accumCount = 0;
174
175 lastStartCount = 0;
176 lastTickCount = 0;
177 lastResult = 0;
178 lastMultiplier = 0;
179 lastStopped = false;
180 startCount = 0;
181
182 if(autoStart == true) {
183 start();
184 }
185 }
186
isStarted() const187 bool Chrono::isStarted() const {
188 return (stopped == false);
189 }
190
start()191 void Chrono::start() {
192 stopped = false;
193 startCount = SDL_GetTicks();
194 }
195
stop()196 void Chrono::stop() {
197 Uint32 endCount = SDL_GetTicks();
198 accumCount += endCount - startCount;
199 stopped = true;
200 }
201
reset()202 void Chrono::reset() {
203 accumCount = 0;
204 lastStartCount = 0;
205 lastTickCount = 0;
206 lastResult = 0;
207 lastMultiplier = 0;
208
209 startCount = SDL_GetTicks();
210 }
211
getMicros()212 int64 Chrono::getMicros() {
213 return queryCounter(1000000);
214 }
215
getMillis()216 int64 Chrono::getMillis() {
217 return queryCounter(1000);
218 }
219
getSeconds()220 int64 Chrono::getSeconds() {
221 return queryCounter(1);
222 }
223
queryCounter(int64 multiplier)224 int64 Chrono::queryCounter(int64 multiplier) {
225
226 if( multiplier == lastMultiplier &&
227 stopped == lastStopped &&
228 lastStartCount == startCount) {
229
230 if(stopped == true) {
231 return lastResult;
232 }
233 else {
234 Uint32 endCount = SDL_GetTicks();
235 if(lastTickCount == endCount) {
236 return lastResult;
237 }
238 }
239 }
240
241 int64 result = 0;
242 if(stopped == true) {
243 result = multiplier * accumCount / freq;
244 }
245 else {
246 Uint32 endCount = SDL_GetTicks();
247 result = multiplier * (accumCount + endCount - startCount) / freq;
248 lastTickCount = endCount;
249 }
250
251 lastStartCount = startCount;
252 lastResult = result;
253 lastMultiplier = multiplier;
254 lastStopped = stopped;
255
256 return result;
257 }
258
getCurMillis()259 int64 Chrono::getCurMillis() {
260 return SDL_GetTicks();
261 }
getCurTicks()262 int64 Chrono::getCurTicks() {
263 return SDL_GetTicks();
264 }
265
266
267
268 // =====================================
269 // Misc
270 // =====================================
271
Tokenize(const string & str,vector<string> & tokens,const string & delimiters)272 void Tokenize(const string& str,vector<string>& tokens,const string& delimiters) {
273
274 /*
275 // Skip delimiters at beginning.
276 string::size_type lastPos = str.find_first_not_of(delimiters, 0);
277 // Find first "non-delimiter".
278 string::size_type pos = str.find_first_of(delimiters, lastPos);
279
280 while (string::npos != pos || string::npos != lastPos) {
281 // Found a token, add it to the vector.
282 tokens.push_back(str.substr(lastPos, pos - lastPos));
283 // Skip delimiters. Note the "not_of"
284 lastPos = str.find_first_not_of(delimiters, pos);
285 // Find next "non-delimiter"
286 pos = str.find_first_of(delimiters, lastPos);
287 }
288 */
289
290 // Assume textLine contains the line of text to parse.
291 string textLine = str;
292
293 size_t pos = 0;
294 while( true ) {
295 size_t nextPos = textLine.find( delimiters, pos );
296 if( nextPos == textLine.npos ) {
297 tokens.push_back(textLine.substr(pos, textLine.length( )));
298 break;
299 }
300 tokens.push_back( string( textLine.substr( pos, nextPos - pos ) ) );
301 pos = nextPos + delimiters.size();
302 }
303
304 }
305
findDirs(string path,vector<string> & results,bool errorOnNotFound,bool keepDuplicates)306 void findDirs(string path, vector<string> &results, bool errorOnNotFound,bool keepDuplicates) {
307 results.clear();
308 string currentPath = path;
309 endPathWithSlash(currentPath);
310
311 string searchpath = currentPath + "*.";
312 vector<string> current_results;
313 findAll(searchpath, current_results, false, errorOnNotFound);
314 if(current_results.empty() == false) {
315 for(unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) {
316 const string current_folder = current_results[folder_index];
317 const string current_folder_path = currentPath + current_folder;
318
319 if(isdir(current_folder_path.c_str()) == true) {
320 if(keepDuplicates == true || std::find(results.begin(),results.end(),current_folder) == results.end()) {
321 results.push_back(current_folder);
322 }
323 }
324 }
325 }
326
327 std::sort(results.begin(),results.end());
328 }
329
findDirs(const vector<string> & paths,vector<string> & results,bool errorOnNotFound,bool keepDuplicates)330 void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound,bool keepDuplicates) {
331 results.clear();
332 size_t pathCount = paths.size();
333 for(unsigned int idx = 0; idx < pathCount; idx++) {
334 string currentPath = paths[idx];
335 endPathWithSlash(currentPath);
336 string path = currentPath + "*.";
337 vector<string> current_results;
338 findAll(path, current_results, false, errorOnNotFound);
339 if(current_results.empty() == false) {
340 for(unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) {
341 const string current_folder = current_results[folder_index];
342 const string current_folder_path = currentPath + current_folder;
343
344 if(isdir(current_folder_path.c_str()) == true) {
345 if(keepDuplicates == true || std::find(results.begin(),results.end(),current_folder) == results.end()) {
346 results.push_back(current_folder);
347 }
348 }
349 }
350 }
351 }
352
353 std::sort(results.begin(),results.end());
354 }
355
findAll(const vector<string> & paths,const string & fileFilter,vector<string> & results,bool cutExtension,bool errorOnNotFound,bool keepDuplicates)356 void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension, bool errorOnNotFound, bool keepDuplicates) {
357 results.clear();
358 size_t pathCount = paths.size();
359 for(unsigned int idx = 0; idx < pathCount; idx++) {
360 string currentPath = paths[idx];
361 endPathWithSlash(currentPath);
362
363 string path = currentPath + fileFilter;
364 vector<string> current_results;
365 findAll(path, current_results, cutExtension, errorOnNotFound);
366 if(current_results.empty() == false) {
367 for(unsigned int folder_index = 0; folder_index < current_results.size(); folder_index++) {
368 string current_file = current_results[folder_index];
369 if(keepDuplicates == true || std::find(results.begin(),results.end(),current_file) == results.end()) {
370 results.push_back(current_file);
371 }
372 }
373 }
374 }
375
376 std::sort(results.begin(),results.end());
377 }
378
379 //finds all filenames like path and stores them in results
findAll(const string & path,vector<string> & results,bool cutExtension,bool errorOnNotFound)380 void findAll(const string &path, vector<string> &results, bool cutExtension, bool errorOnNotFound) {
381 results.clear();
382
383 std::string mypath = path;
384 /** Stupid win32 is searching for all files without extension when *. is
385 * specified as wildcard
386 */
387 if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) {
388 mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2));
389 mypath += "*";
390 }
391
392 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,mypath.c_str());
393
394 glob_t globbuf;
395
396 int res = glob(mypath.c_str(), 0, 0, &globbuf);
397 if(res < 0 && errorOnNotFound == true) {
398 if(errorOnNotFound) {
399 std::stringstream msg;
400 msg << "#1 Couldn't scan directory '" << mypath << "': " << strerror(errno);
401 throw megaglest_runtime_error(msg.str());
402 }
403 }
404 else {
405 for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
406 const char* p = globbuf.gl_pathv[i];
407 const char* begin = p;
408 for( ; *p != 0; ++p) {
409 // strip the path component
410 if(*p == '/')
411 begin = p+1;
412 }
413 if(!(strcmp(".", begin)==0 || strcmp("..", begin)==0 || strcmp(".git", begin)==0)) {
414 results.push_back(begin);
415 }
416 else {
417 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] SKIPPED SPECIAL FILENAME [%s]\n",__FILE__,__FUNCTION__,__LINE__,begin);
418 }
419 }
420
421 globfree(&globbuf);
422
423 if(results.empty() == true && errorOnNotFound == true) {
424 throw megaglest_runtime_error("No files found in: " + mypath);
425 }
426
427 if(cutExtension) {
428 for (size_t i=0; i<results.size(); ++i){
429 results.at(i)=cutLastExt(results.at(i));
430 }
431 }
432 }
433 }
434
isdir(const char * path)435 bool isdir(const char *path)
436 {
437 string friendly_path = path;
438
439 #ifdef WIN32
440 replaceAll(friendly_path, "/", "\\");
441 if(EndsWith(friendly_path, "\\") == true) {
442 friendly_path.erase(friendly_path.begin() + friendly_path.length() -1);
443 }
444 #endif
445
446 #ifdef WIN32
447 #if defined(__MINGW32__)
448 struct _stat stats;
449 #else
450 struct _stat64i32 stats;
451 #endif
452 int result = _wstat(utf8_decode(friendly_path).c_str(), &stats);
453 #else
454 struct stat stats;
455 int result = stat(friendly_path.c_str(), &stats);
456 #endif
457 bool ret = (result == 0);
458 if(ret == true) {
459 ret = S_ISDIR(stats.st_mode); // #define S_ISDIR(mode) ((mode) & _S_IFDIR)
460
461 if(ret == false) {
462 //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] ret = %d\n",__FILE__,__FUNCTION__,__LINE__,friendly_path.c_str(),ret);
463 }
464 }
465 else {
466 //SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] ret = %d, result = %d, errno = %d\n",__FILE__,__FUNCTION__,__LINE__,friendly_path.c_str(),ret,result,errno);
467 }
468 //if(ret == false) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] NOT a path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path);
469
470 return ret;
471 }
472
fileExists(const string & path)473 bool fileExists(const string &path) {
474 if (path.size() == 0) return false;
475
476 #ifdef WIN32
477 wstring wstr = utf8_decode(path);
478 FILE* file= _wfopen(wstr.c_str(), L"rb");
479 #else
480 FILE* file= fopen(path.c_str(), "rb");
481 #endif
482 if(file != NULL) {
483 fclose(file);
484 return true;
485 }
486 // else {
487 //int fileErrno = errno;
488 //#ifdef WIN32
489 //int fileErrno = errno;
490 //DWORD error = GetLastError();
491 //string strError = "[#6] Could not open file, result: " + intToStr(error) + " - " + intToStr(fileErrno) + " " + strerror(fileErrno) + " [" + path + "]";
492 //#endif
493 // }
494 return false;
495 }
496
removeFolder(const string & path)497 void removeFolder(const string &path) {
498 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str());
499
500 string deletePath = path;
501 endPathWithSlash(deletePath);
502 deletePath += "{,.}*";
503 vector<string> results = getFolderTreeContentsListRecursively(deletePath, "", true);
504 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] results.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),results.size());
505
506 // First delete files
507 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DELETE FILES\n",__FILE__,__FUNCTION__,__LINE__);
508
509 for(int i = (int)results.size() -1; i >= 0; --i) {
510 string item = results[i];
511
512 //if(item.find(".git") != string::npos) {
513 // printf("!!!!!!!!!!!!!!!!!! FOUND SPECIAL FOLDER [%s] in [%s]\n",item.c_str(),path.c_str());
514 //}
515
516 if(isdir(item.c_str()) == false) {
517 bool result = removeFile(item);
518 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(),result);
519 }
520 }
521 // Now delete folders
522 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DELETE FOLDERS\n",__FILE__,__FUNCTION__,__LINE__);
523
524 for(int i = (int)results.size() -1; i >= 0; --i) {
525 string item = results[i];
526 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] item [%s] isdir(item.c_str()) = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(), isdir(item.c_str()));
527 if(isdir(item.c_str()) == true) {
528
529 //printf("~~~~~ REMOVE FOLDER [%s] in [%s]\n",item.c_str(),path.c_str());
530
531 #ifdef WIN32
532 //int result = _rmdir(item.c_str());
533 int result = _wrmdir(utf8_decode(item).c_str());
534 #else
535 int result = rmdir(item.c_str());
536 #endif
537 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] item [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,item.c_str(),result);
538
539 if(result != 0 && item != path) {
540 printf("CANNOT REMOVE FOLDER [%s] in [%s]\n",item.c_str(),path.c_str());
541 removeFolder(item);
542 }
543 }
544 }
545
546 #ifdef WIN32
547 //int result = _rmdir(path.c_str());
548 int result = _wrmdir(utf8_decode(path).c_str());
549 #else
550 int result = rmdir(path.c_str());
551 #endif
552
553 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] path [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),result);
554 }
555
StartsWith(const std::string & str,const std::string & key)556 bool StartsWith(const std::string &str, const std::string &key) {
557 return str.find(key) == 0;
558 }
559
EndsWith(const string & str,const string & key)560 bool EndsWith(const string &str, const string& key)
561 {
562 bool result = false;
563 if (str.length() >= key.length()) {
564 result = (0 == str.compare(max((int)0,(int)str.length() - (int)key.length()), key.length(), key));
565 }
566
567 return result;
568 }
569
endPathWithSlash(string & path,bool requireOSSlash)570 void endPathWithSlash(string &path,bool requireOSSlash) {
571 if(EndsWith(path, "/") == false && EndsWith(path, "\\") == false) {
572 string seperator = "/";
573 if(requireOSSlash == true) {
574 #if defined(WIN32)
575 seperator = "\\";
576 #endif
577 }
578 path += seperator;
579 }
580 }
581
formatPath(string path)582 string formatPath(string path) {
583 replaceAll(path, "\"", "");
584 replaceAll(path, "//", "/");
585
586 return path;
587 }
588
trimPathWithStartingSlash(string & path)589 void trimPathWithStartingSlash(string &path) {
590 if(StartsWith(path, "/") == true || StartsWith(path, "\\") == true) {
591 path.erase(path.begin(),path.begin()+1);
592 //printf("************* trimPathWithStartingSlash changed path [%s]\n",path.c_str());
593 }
594 }
595
updatePathClimbingParts(string & path,bool processPreviousDirTokenCheck)596 void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck) {
597 // Update paths with /./
598 string::size_type pos = path.find("/./");
599 if(pos != string::npos && pos != 0) {
600 string orig = path;
601 path.erase(pos,2);
602 //pos--;
603
604 //printf("#1 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
605
606 pos = path.find("/./");
607 if(pos != string::npos && pos != 0) {
608 updatePathClimbingParts(path, processPreviousDirTokenCheck);
609 }
610
611 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
612 }
613 pos = path.find("\\.\\");
614 if(pos != string::npos && pos != 0) {
615 string orig = path;
616 path.erase(pos,2);
617 //pos--;
618 //printf("#w CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
619
620 pos = path.find("\\.\\");
621 if(pos != string::npos && pos != 0) {
622 updatePathClimbingParts(path, processPreviousDirTokenCheck);
623 }
624
625 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
626 }
627
628 // Update paths with ..
629 if(processPreviousDirTokenCheck) {
630 pos = path.find("..");
631 if(pos != string::npos && pos != 0) {
632
633 string orig = path;
634 if(path[pos-1] != ' ' || (path.length() > 2 && path[pos+2] != ' ')) {
635 path.erase(pos,2);
636
637 //printf("#3 [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,orig.c_str(),path.c_str());
638
639 pos--;
640 //pos = pos -1;
641
642 //printf("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #3b [%d]\n",(int)pos);
643
644 if(path[pos] == '/' || path[pos] == '\\') {
645 path.erase(pos,1);
646
647 //printf("#4 CHANGE relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
648 }
649
650 for(int x = (int)pos; x >= 0; --x) {
651 //printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str());
652
653 if((path[x] == '/' || path[x] == '\\') && x != (int)pos) {
654 //string origLoop = path;
655 path.erase(x,(int)pos-x);
656
657 //printf("#5 [%d] [%d] [%d] CHANGE relative path from [%s] to [%s]\n",(int)pos,(int)x,(int)origLoop.length(),origLoop.c_str(),path.c_str());
658 break;
659 }
660 }
661 pos = path.find("..");
662 }
663 else {
664 //printf("#6a [%d]\n",(int)pos);
665
666 //pos = path.find("..",pos+1);
667 pos = string::npos;
668
669 //printf("#6b [%d]\n",(int)pos);
670 }
671 if(pos != string::npos && pos != 0) {
672 updatePathClimbingParts(path,processPreviousDirTokenCheck);
673 }
674
675 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
676 }
677 }
678
679 /*
680 string::size_type pos = path.rfind("..");
681 if(pos != string::npos && pos != 0) {
682 string orig = path;
683 path.erase(pos,2);
684 pos--;
685 if(path[pos] == '/' || path[pos] == '\\') {
686 path.erase(pos,1);
687 }
688
689 for(int x = pos; x >= 0; --x) {
690 //printf("x [%d][%c] pos [%ld][%c] [%s]\n",x,path[x],(long int)pos,path[pos],path.substr(0,x+1).c_str());
691
692 if((path[x] == '/' || path[x] == '\\') && x != pos) {
693 path.erase(x,pos-x);
694 break;
695 }
696 }
697
698 printf("CHANGED relative path from [%s] to [%s]\n",orig.c_str(),path.c_str());
699 }
700 */
701 }
702
getCRCCacheFilePath()703 string getCRCCacheFilePath() {
704 return crcCachePath;
705 }
706
setCRCCacheFilePath(string path)707 void setCRCCacheFilePath(string path) {
708 crcCachePath = path;
709 }
710
getGameVersion()711 string getGameVersion() {
712 return gameVersion;
713 }
getGameGITVersion()714 string getGameGITVersion() {
715 return gameGITVersion;
716 }
setGameVersion(string version)717 void setGameVersion(string version) {
718 gameVersion = version;
719 }
setGameGITVersion(string git)720 void setGameGITVersion(string git) {
721 gameGITVersion = git;
722 }
723
getCRCCacheFileName(std::pair<string,string> cacheKeys)724 string getCRCCacheFileName(std::pair<string,string> cacheKeys) {
725 string crcCacheFile = cacheKeys.first + cacheKeys.second;
726 return crcCacheFile;
727 }
getFormattedCRCCacheFileName(std::pair<string,string> cacheKeys)728 string getFormattedCRCCacheFileName(std::pair<string,string> cacheKeys) {
729 string crcCacheFile = getCRCCacheFileName(cacheKeys);
730
731 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] cacheKeys.first = [%s] cacheKeys.second [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,cacheKeys.first.c_str(),cacheKeys.second.c_str());
732
733 Checksum checksum;
734 checksum.addString(crcCacheFile);
735 string result = getCRCCacheFilePath() + "CRC_CACHE_" + uIntToStr(checksum.getSum());
736 return result;
737 }
getFolderTreeContentsCheckSumCacheKey(vector<string> paths,string pathSearchString,const string & filterFileExt)738 std::pair<string,string> getFolderTreeContentsCheckSumCacheKey(vector<string> paths, string pathSearchString, const string &filterFileExt) {
739 string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey1;
740
741 string cacheKey = "";
742 for(unsigned int idx = 0; idx < paths.size(); ++idx) {
743 string path = paths[idx] + pathSearchString;
744 cacheKey += path + "_" + filterFileExt + "_";
745 }
746 return make_pair(cacheLookupId,cacheKey);
747 }
748
hasCachedFileCRCValue(string crcCacheFile,uint32 & value)749 pair<bool,time_t> hasCachedFileCRCValue(string crcCacheFile, uint32 &value) {
750 //bool result = false;
751
752 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
753 SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d for Cache file [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str());
754 }
755
756 pair<bool,time_t> result = make_pair(false,0);
757 if(fileExists(crcCacheFile) == true) {
758 #ifdef WIN32
759 FILE *fp = _wfopen(utf8_decode(crcCacheFile).c_str(), L"r");
760 #else
761 FILE *fp = fopen(crcCacheFile.c_str(),"r");
762 #endif
763 if(fp != NULL) {
764 time_t refreshDate = 0;
765 uint32 crcValue = 0;
766 time_t lastUpdateDate = 0;
767
768 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
769 SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d for Cache file [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str());
770 }
771
772 char gameVer[500]="";
773 char gitVer[500]="";
774 char actualFilePath[8096]="";
775 int readbytes = fscanf(fp,"%20ld,%20u,%20ld\n%499s\n%499s\n%8095s",
776 &refreshDate,
777 &crcValue,
778 &lastUpdateDate,
779 &gameVer[0],
780 &gitVer[0],
781 &actualFilePath[0]);
782 refreshDate = Shared::PlatformByteOrder::fromCommonEndian(refreshDate);
783 crcValue = Shared::PlatformByteOrder::fromCommonEndian(crcValue);
784 lastUpdateDate = Shared::PlatformByteOrder::fromCommonEndian(lastUpdateDate);
785 string readGameVer = Shared::PlatformByteOrder::fromCommonEndian(string(gameVer));
786 string readGitVer = Shared::PlatformByteOrder::fromCommonEndian(string(gitVer));
787 string readActualFilePath = Shared::PlatformByteOrder::fromCommonEndian(string(actualFilePath));
788
789 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("CRC readGameVer [%s] [%s]\n%s\n",readGameVer.c_str(),readGitVer.c_str(),readActualFilePath.c_str());
790
791 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
792 SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d for Cache file [%s] readbytes = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),readbytes);
793 }
794
795 fclose(fp);
796
797 struct tm future; /* as in future date */
798 future.tm_sec = 0;
799 future.tm_min = 0;
800 future.tm_hour = 0;
801 future.tm_mday = 6; /* 1st */
802 future.tm_mon = 6; /* July */
803 future.tm_year = 2012 - 1900; /* 2038 in years since 1900 */
804 future.tm_isdst = 0; /* Daylight Saving not in affect (UTC) */
805 #ifdef _BSD_SOURCE
806 future.tm_zone = "UTC";
807 #endif
808
809 time_t tBadCRCDate = mktime( &future );
810
811 result.second = lastUpdateDate;
812 if( readGameVer != "" && readGitVer != "" &&
813 refreshDate > 0 &&
814 refreshDate > tBadCRCDate &&
815 time(NULL) < refreshDate) {
816
817 result.first = true;
818 value = crcValue;
819
820 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
821 //struct tm *loctime = localtime (&refreshDate);
822 struct tm loctime = threadsafe_localtime(refreshDate);
823 char szBuf1[100]="";
824 strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime);
825
826 SystemFlags::OutputDebug(SystemFlags::debugSystem,
827 "=-=-=-=- READ CACHE for Cache file [%s] refreshDate = %ld [%s], crcValue = %u\n",
828 crcCacheFile.c_str(),refreshDate, szBuf1, crcValue);
829 }
830 }
831 else {
832 //time_t now = time(NULL);
833 //struct tm *loctime = localtime (&now);
834 struct tm loctime = threadsafe_localtime(systemtime_now());
835 char szBuf1[100]="";
836 strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime);
837
838 loctime = threadsafe_localtime(refreshDate);
839 char szBuf2[100]="";
840 strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",&loctime);
841
842 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
843 SystemFlags::OutputDebug(SystemFlags::debugSystem,
844 "=-=-=-=- NEED TO CALCULATE CRC for Cache file [%s] now = %ld [%s], refreshDate = %ld [%s], crcValue = %u\n",
845 crcCacheFile.c_str(), systemtime_now(), szBuf1, refreshDate, szBuf2, crcValue);
846 }
847 }
848 }
849 else {
850 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
851 SystemFlags::OutputDebug(SystemFlags::debugSystem,"FILE NOT FOUND(1) for Cache file [%s]\n",crcCacheFile.c_str());
852 }
853 }
854 }
855 else {
856 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) {
857 SystemFlags::OutputDebug(SystemFlags::debugSystem,"FILE NOT FOUND(2) for Cache file [%s]\n",crcCacheFile.c_str());
858 }
859 }
860
861 return result;
862 }
863
writeCachedFileCRCValue(string crcCacheFile,uint32 & crcValue,string actualFileName)864 void writeCachedFileCRCValue(string crcCacheFile, uint32 &crcValue, string actualFileName) {
865 #ifdef WIN32
866 FILE *fp = _wfopen(utf8_decode(crcCacheFile).c_str(), L"w");
867 #else
868 FILE *fp = fopen(crcCacheFile.c_str(),"w");
869 #endif
870 if(fp != NULL) {
871 //RandomGen random;
872 //int offset = random.randRange(5, 15);
873 srand((unsigned int)time(NULL) + (unsigned long)crcCacheFile.length());
874 int offset = rand() % 15;
875 if(offset == 0) {
876 offset = 3;
877 }
878 time_t now = time(NULL);
879 time_t refreshDate = now + (REFRESH_CRC_DAY_SECONDS * offset);
880
881 //struct tm *loctime = localtime (&refreshDate);
882 struct tm loctime = threadsafe_localtime(refreshDate);
883 char szBuf1[100]="";
884 strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime);
885
886 string writeGameVer = Shared::PlatformByteOrder::toCommonEndian(gameVersion);
887 string writeGameGITVersion = Shared::PlatformByteOrder::toCommonEndian(gameGITVersion);
888 string writeActualFileName = Shared::PlatformByteOrder::toCommonEndian(actualFileName);
889
890 fprintf(fp,"%20ld,%20u,%20ld",
891 Shared::PlatformByteOrder::toCommonEndian(refreshDate),
892 Shared::PlatformByteOrder::toCommonEndian(crcValue),
893 Shared::PlatformByteOrder::toCommonEndian(now));
894
895 fprintf(fp,"\n%s\n%s\n%s",
896 writeGameVer.c_str(),
897 writeGameGITVersion.c_str(),
898 writeActualFileName.c_str());
899
900 fclose(fp);
901
902 //if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"========== Writing CRC Cache offset [%d] refreshDate = %ld [%s], crcValue = %u, file [%s]\n",offset,refreshDate,szBuf1,crcValue,crcCacheFile.c_str());
903 }
904 }
905
clearFolderTreeContentsCheckSum(vector<string> paths,string pathSearchString,const string & filterFileExt)906 void clearFolderTreeContentsCheckSum(vector<string> paths, string pathSearchString, const string &filterFileExt) {
907 std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt);
908 string cacheLookupId = cacheKeys.first;
909 std::map<string,uint32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,uint32> >(cacheLookupId);
910
911 string cacheKey = cacheKeys.second;
912 if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
913 crcTreeCache.erase(cacheKey);
914 }
915 for(unsigned int idx = 0; idx < paths.size(); ++idx) {
916 string path = paths[idx];
917 clearFolderTreeContentsCheckSum(path, filterFileExt);
918 }
919
920 string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
921 if(fileExists(crcCacheFile) == true) {
922
923 bool result = removeFile(crcCacheFile);
924 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result);
925 }
926 }
927
getFolderTreeContentsCheckSumRecursivelyLastGenerated(vector<string> paths,string pathSearchString,const string & filterFileExt)928 time_t getFolderTreeContentsCheckSumRecursivelyLastGenerated(vector<string> paths, string pathSearchString, const string &filterFileExt) {
929 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] Calculating CRC for [%s] -----------\n",__FILE__,__FUNCTION__,__LINE__,pathSearchString.c_str());
930
931 std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt);
932 //string cacheLookupId = cacheKeys.first;
933 //std::map<string,uint32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,uint32> >(cacheLookupId);
934
935 string cacheKey = cacheKeys.second;
936 string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
937 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] -----------\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),pathSearchString.c_str());
938
939 uint32 crcValue = 0;
940 pair<bool,time_t> crcResult = hasCachedFileCRCValue(crcCacheFile, crcValue);
941 if(crcResult.first == true) {
942 //struct tm *loctime = localtime (&crcResult.second);
943 struct tm loctime = threadsafe_localtime(crcResult.second);
944 char szBuf1[100]="";
945 strftime(szBuf1,100,"%Y-%m-%d %H:%M:%S",&loctime);
946
947 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED FILE for cacheKey [%s] last updated [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str(),szBuf1);
948 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE for cacheKey [%s] last updated [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str(),szBuf1);
949
950 return crcResult.second;
951 }
952 else {
953 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s]\n",__FILE__,__FUNCTION__,cacheKey.c_str());
954 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s]\n",__FILE__,__FUNCTION__,cacheKey.c_str());
955 }
956
957 return 0;
958 }
959
960 //finds all filenames like path and gets their checksum of all files combined
getFolderTreeContentsCheckSumRecursively(vector<string> paths,string pathSearchString,const string & filterFileExt,Checksum * recursiveChecksum,bool forceNoCache)961 uint32 getFolderTreeContentsCheckSumRecursively(vector<string> paths, string pathSearchString, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache) {
962 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] Calculating CRC for [%s] -----------\n",__FILE__,__FUNCTION__,__LINE__,pathSearchString.c_str());
963
964 std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumCacheKey(paths, pathSearchString, filterFileExt);
965 string cacheLookupId = cacheKeys.first;
966 std::map<string,uint32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,uint32> >(cacheLookupId);
967
968 string cacheKey = cacheKeys.second;
969 if(forceNoCache == false && crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
970 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str());
971 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning folders found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str());
972 return crcTreeCache[cacheKey];
973 }
974
975 string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
976 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for CRC Cache file [%s]\n",crcCacheFile.c_str());
977
978 if(recursiveChecksum == NULL) {
979 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] forceNoCache = %d -----------\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),pathSearchString.c_str(),forceNoCache);
980 }
981
982 uint32 crcValue = 0;
983 if(forceNoCache == false && hasCachedFileCRCValue(crcCacheFile, crcValue).first == true) {
984 crcTreeCache[cacheKey] = crcValue;
985 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache);
986 if(recursiveChecksum == NULL) {
987 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache);
988 }
989
990 return crcTreeCache[cacheKey];
991 }
992 else {
993 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache);
994 if(recursiveChecksum == NULL) {
995 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache);
996 }
997 }
998
999 Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum);
1000 for(unsigned int idx = 0; idx < paths.size(); ++idx) {
1001 string path = paths[idx] + pathSearchString;
1002
1003 getFolderTreeContentsCheckSumRecursively(path, filterFileExt, &checksum, forceNoCache);
1004 }
1005
1006 if(recursiveChecksum != NULL) {
1007 *recursiveChecksum = checksum;
1008 }
1009
1010 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Final CRC file count: %d\n",__FILE__,__FUNCTION__,__LINE__,checksum.getFileCount());
1011
1012 uint32 result = checksum.getFinalFileListSum();
1013 //if(forceNoCache == false) {
1014 crcTreeCache[cacheKey] = result;
1015 writeCachedFileCRCValue(crcCacheFile, crcTreeCache[cacheKey],getCRCCacheFileName(cacheKeys));
1016 //}
1017 return result;
1018 }
1019
getFolderTreeContentsCheckSumCacheKey(const string & path,const string & filterFileExt)1020 std::pair<string,string> getFolderTreeContentsCheckSumCacheKey(const string &path, const string &filterFileExt) {
1021 string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumRecursivelyCacheLookupKey2;
1022
1023 string cacheKey = path + "_" + filterFileExt;
1024 return make_pair(cacheLookupId,cacheKey);
1025 }
1026
clearFolderTreeContentsCheckSum(const string & path,const string & filterFileExt)1027 void clearFolderTreeContentsCheckSum(const string &path, const string &filterFileExt) {
1028 std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumCacheKey(path,filterFileExt);
1029 string cacheLookupId = cacheKeys.first;
1030 std::map<string,uint32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,uint32> >(cacheLookupId);
1031
1032 string cacheKey = cacheKeys.second;
1033 if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
1034 crcTreeCache.erase(cacheKey);
1035 }
1036 string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
1037 if(fileExists(crcCacheFile) == true) {
1038 bool result = removeFile(crcCacheFile);
1039 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result);
1040 }
1041 }
1042
1043 //finds all filenames like path and gets their checksum of all files combined
getFolderTreeContentsCheckSumRecursively(const string & path,const string & filterFileExt,Checksum * recursiveChecksum,bool forceNoCache)1044 uint32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum, bool forceNoCache) {
1045 std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumCacheKey(path, filterFileExt);
1046
1047 string cacheLookupId = cacheKeys.first;
1048 std::map<string,uint32> &crcTreeCache = CacheManager::getCachedItem< std::map<string,uint32> >(cacheLookupId);
1049
1050 string cacheKey = cacheKeys.second;
1051 if(forceNoCache == false && crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
1052 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning [%s] found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),crcTreeCache[cacheKey],cacheKey.c_str());
1053 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("\n-------------- In [%s::%s Line: %d] scanning [%s] found CACHED checksum = %d for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),crcTreeCache[cacheKey],cacheKey.c_str());
1054 return crcTreeCache[cacheKey];
1055 }
1056
1057 string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
1058 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Looking for CRC Cache file [%s]\n",crcCacheFile.c_str());
1059
1060 if(recursiveChecksum == NULL) {
1061 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] looking for cached CRC file [%s] for [%s] forceNoCache = %d -----------\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),path.c_str(),forceNoCache);
1062 }
1063
1064 uint32 crcValue = 0;
1065 if(forceNoCache == false && hasCachedFileCRCValue(crcCacheFile, crcValue).first == true) {
1066 crcTreeCache[cacheKey] = crcValue;
1067 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache);
1068 if(recursiveChecksum == NULL) {
1069 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s Line: %d] scanning folders found CACHED FILE checksum = %d for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,__LINE__,crcTreeCache[cacheKey],cacheKey.c_str(),forceNoCache);
1070 }
1071
1072 return crcTreeCache[cacheKey];
1073 }
1074 else {
1075 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache);
1076 if(recursiveChecksum == NULL) {
1077 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"-------------- In [%s::%s] scanning folders DID NOT FIND CACHED FILE checksum for cacheKey [%s] forceNoCache = %d\n",__FILE__,__FUNCTION__,cacheKey.c_str(),forceNoCache);
1078 }
1079 }
1080
1081 bool topLevelCaller = (recursiveChecksum == NULL);
1082 Checksum checksum = (recursiveChecksum == NULL ? Checksum() : *recursiveChecksum);
1083
1084 std::string mypath = path;
1085 // Stupid win32 is searching for all files without extension when *. is
1086 // specified as wildcard
1087 //
1088 if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) {
1089 mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2));
1090 mypath += "*";
1091 }
1092
1093 glob_t globbuf;
1094
1095 int res = glob(mypath.c_str(), 0, 0, &globbuf);
1096 #if !defined(__APPLE__) && !defined(__DragonFly__) && !defined(__OpenBSD__)
1097 if(res < 0) {
1098 std::stringstream msg;
1099 msg << "#2 Couldn't scan directory '" << mypath << "': " << strerror(errno);
1100 throw megaglest_runtime_error(msg.str());
1101 }
1102 #endif
1103
1104 int fileLoopCount = 0;
1105 int fileMatchCount = 0;
1106 for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
1107 const char* p = globbuf.gl_pathv[i];
1108 //printf("Line: %d p [%s]\n",__LINE__,p);
1109
1110 if(isdir(p) == false) {
1111 bool addFile = true;
1112 if(EndsWith(p, ".") == true || EndsWith(p, "..") == true || EndsWith(p, ".git") == true) {
1113 addFile = false;
1114 }
1115 else if(filterFileExt != "") {
1116 addFile = EndsWith(p, filterFileExt);
1117 }
1118
1119 if(addFile) {
1120 checksum.addFile(p);
1121 fileMatchCount++;
1122 }
1123 }
1124 fileLoopCount++;
1125 }
1126
1127 globfree(&globbuf);
1128
1129 // Look recursively for sub-folders
1130 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__OpenBSD__)
1131 res = glob(mypath.c_str(), 0, 0, &globbuf);
1132 #else
1133 res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
1134 #endif
1135
1136 #if !defined(__APPLE__) && !defined(__DragonFly__) && !defined(__OpenBSD__)
1137 if(res < 0) {
1138 std::stringstream msg;
1139 msg << "#3 Couldn't scan directory '" << mypath << "': " << strerror(errno);
1140 throw megaglest_runtime_error(msg.str());
1141 }
1142 #endif
1143
1144 for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
1145 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__OpenBSD__)
1146 struct stat statStruct;
1147 // only process if dir..
1148 lstat( globbuf.gl_pathv[i], &statStruct);
1149 if( S_ISDIR(statStruct.st_mode) == 0)
1150 continue;
1151 #endif
1152 const char *p = globbuf.gl_pathv[i];
1153 //printf("Line: %d p [%s]\n",__LINE__,p);
1154
1155 string currentPath = p;
1156 endPathWithSlash(currentPath);
1157
1158 getFolderTreeContentsCheckSumRecursively(currentPath + "*", filterFileExt, &checksum, forceNoCache);
1159 }
1160
1161 globfree(&globbuf);
1162
1163 if(recursiveChecksum != NULL) {
1164 *recursiveChecksum = checksum;
1165 }
1166
1167 if(topLevelCaller == true) {
1168 //printf("In [%s::%s Line: %d] Final CRC file count for [%s]: %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),checksum.getFileCount());
1169 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] Final CRC file count for [%s]: %d\n",__FILE__,__FUNCTION__,__LINE__,path.c_str(),checksum.getFileCount());
1170
1171 uint32 result = checksum.getFinalFileListSum();
1172 //if(forceNoCache == false) {
1173 crcTreeCache[cacheKey] = result;
1174 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] ending checksum = %d for cacheKey [%s] fileMatchCount = %d, fileLoopCount = %d\n",__FILE__,__FUNCTION__,path.c_str(),crcTreeCache[cacheKey],cacheKey.c_str(),fileMatchCount,fileLoopCount);
1175 writeCachedFileCRCValue(crcCacheFile, crcTreeCache[cacheKey],getCRCCacheFileName(cacheKeys));
1176 //}
1177
1178 return result;
1179 }
1180 else {
1181 return 0;
1182 }
1183 }
1184
1185
getFolderTreeContentsCheckSumListCacheKey(vector<string> paths,string pathSearchString,const string & filterFileExt)1186 std::pair<string,string> getFolderTreeContentsCheckSumListCacheKey(vector<string> paths, string pathSearchString, const string &filterFileExt) {
1187 string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey1;
1188
1189 string cacheKey = "";
1190 for(unsigned int idx = 0; idx < paths.size(); ++idx) {
1191 string path = paths[idx] + pathSearchString;
1192 cacheKey += path + "_" + filterFileExt + "_";
1193 }
1194 return make_pair(cacheLookupId,cacheKey);
1195 }
1196
clearFolderTreeContentsCheckSumList(vector<string> paths,string pathSearchString,const string & filterFileExt)1197 void clearFolderTreeContentsCheckSumList(vector<string> paths, string pathSearchString, const string &filterFileExt) {
1198 std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumListCacheKey(paths, pathSearchString, filterFileExt);
1199 string cacheLookupId = cacheKeys.first;
1200 std::map<string,vector<std::pair<string,uint32> > > &crcTreeCache = CacheManager::getCachedItem< std::map<string,vector<std::pair<string,uint32> > > >(cacheLookupId);
1201
1202 string cacheKey = cacheKeys.second;
1203 if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
1204 crcTreeCache.erase(cacheKey);
1205 }
1206 for(unsigned int idx = 0; idx < paths.size(); ++idx) {
1207 string path = paths[idx];
1208 clearFolderTreeContentsCheckSumList(path, filterFileExt);
1209 }
1210 string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
1211 if(fileExists(crcCacheFile) == true) {
1212 bool result = removeFile(crcCacheFile);
1213 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result);
1214 }
1215 }
1216
getFolderTreeContentsCheckSumListRecursively(vector<string> paths,string pathSearchString,const string & filterFileExt,vector<std::pair<string,uint32>> * recursiveMap)1217 vector<std::pair<string,uint32> > getFolderTreeContentsCheckSumListRecursively(vector<string> paths, string pathSearchString, const string &filterFileExt, vector<std::pair<string,uint32> > *recursiveMap) {
1218 std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumListCacheKey(paths, pathSearchString, filterFileExt);
1219 string cacheLookupId = cacheKeys.first;
1220 std::map<string,vector<std::pair<string,uint32> > > &crcTreeCache = CacheManager::getCachedItem< std::map<string,vector<std::pair<string,uint32> > > >(cacheLookupId);
1221
1222 string cacheKey = cacheKeys.second;
1223 if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
1224 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders found CACHED result for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str());
1225 return crcTreeCache[cacheKey];
1226 }
1227 else {
1228 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] scanning folders, NO CACHE found result for cacheKey [%s]\n",__FILE__,__FUNCTION__,__LINE__,cacheKey.c_str());
1229 }
1230
1231 bool topLevelCaller = (recursiveMap == NULL);
1232
1233 vector<std::pair<string,uint32> > checksumFiles = (recursiveMap == NULL ? vector<std::pair<string,uint32> >() : *recursiveMap);
1234 for(unsigned int idx = 0; idx < paths.size(); ++idx) {
1235 string path = paths[idx] + pathSearchString;
1236 checksumFiles = getFolderTreeContentsCheckSumListRecursively(path, filterFileExt, &checksumFiles);
1237 }
1238
1239 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size());
1240
1241 if(topLevelCaller == true) {
1242 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION, checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size());
1243 }
1244
1245 crcTreeCache[cacheKey] = checksumFiles;
1246 return crcTreeCache[cacheKey];
1247 }
1248
1249 //finds all filenames like path and gets the checksum of each file
getFolderTreeContentsListRecursively(const string & path,const string & filterFileExt,bool includeFolders,vector<string> * recursiveMap)1250 vector<string> getFolderTreeContentsListRecursively(const string &path, const string &filterFileExt, bool includeFolders, vector<string> *recursiveMap) {
1251 bool topLevelCaller = (recursiveMap == NULL);
1252 vector<string> resultFiles = (recursiveMap == NULL ? vector<string>() : *recursiveMap);
1253
1254 std::string mypath = path;
1255 /** Stupid win32 is searching for all files without extension when *. is
1256 * specified as wildcard
1257 */
1258 if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) {
1259 mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2));
1260 mypath += "*";
1261 }
1262
1263 glob_t globbuf;
1264
1265 int globFlags = 0;
1266 if(EndsWith(mypath,"{,.}*") == true) {
1267 #ifndef WIN32
1268 globFlags = GLOB_BRACE;
1269 #else
1270 // Windows glob source cannot handle GLOB_BRACE
1271 // but that should be ok for win32 platform
1272 replaceAll(mypath,"{,.}*","*");
1273 #endif
1274 }
1275
1276 int res = glob(mypath.c_str(), globFlags, 0, &globbuf);
1277 #if !defined(__APPLE__) && !defined(__DragonFly__) && !defined(__OpenBSD__)
1278 if(res < 0) {
1279 std::stringstream msg;
1280 msg << "#4 Couldn't scan directory '" << mypath << "': " << strerror(errno);
1281 throw megaglest_runtime_error(msg.str());
1282 }
1283 #endif
1284 for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
1285 const char* p = globbuf.gl_pathv[i];
1286
1287 bool skipItem = (EndsWith(p, ".") == true || EndsWith(p, "..") == true);
1288 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"~~~~~~~~~~~ Glob file [%s] skipItem = %d\n",p,skipItem);
1289
1290 if(skipItem == false) {
1291 if(isdir(p) == false) {
1292 bool addFile = true;
1293 if(filterFileExt != "") {
1294 addFile = EndsWith(p, filterFileExt);
1295 }
1296
1297 if(addFile) {
1298 resultFiles.push_back(p);
1299 }
1300 }
1301 else if(includeFolders == true) {
1302 resultFiles.push_back(p);
1303 }
1304 }
1305 }
1306
1307 globfree(&globbuf);
1308
1309 // Look recursively for sub-folders
1310 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__OpenBSD__)
1311 res = glob(mypath.c_str(), 0, 0, &globbuf);
1312 #else //APPLE doesn't have the GLOB_ONLYDIR definition..
1313 globFlags |= GLOB_ONLYDIR;
1314 res = glob(mypath.c_str(), globFlags, 0, &globbuf);
1315 #endif
1316
1317 #if !defined(__APPLE__) && !defined(__DragonFly__) && !defined(__OpenBSD__)
1318 if(res < 0) {
1319 std::stringstream msg;
1320 msg << "#5 Couldn't scan directory '" << mypath << "': " << strerror(errno);
1321 throw megaglest_runtime_error(msg.str());
1322 }
1323 #endif
1324
1325 for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
1326 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__OpenBSD__)
1327 struct stat statStruct;
1328 // only get if dir..
1329 lstat( globbuf.gl_pathv[ i], &statStruct);
1330 if( S_ISDIR(statStruct.st_mode) == 0)
1331 continue;
1332 #endif
1333 const char* p = globbuf.gl_pathv[i];
1334
1335 bool skipItem = (EndsWith(p, ".") == true || EndsWith(p, "..") == true);
1336 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"~~~~~~~~~~~ Glob folder [%s] skipItem = %d\n",p,skipItem);
1337
1338 if(skipItem == false) {
1339 if(includeFolders == true) {
1340 resultFiles.push_back(p);
1341 }
1342
1343 string currentPath = p;
1344 endPathWithSlash(currentPath);
1345
1346 if(EndsWith(mypath,"{,.}*") == true) {
1347 currentPath += "{,.}*";
1348 }
1349 else {
1350 currentPath += "*";
1351 }
1352 resultFiles = getFolderTreeContentsListRecursively(currentPath, filterFileExt, includeFolders,&resultFiles);
1353 }
1354 }
1355
1356 globfree(&globbuf);
1357
1358 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s]\n",__FILE__,__FUNCTION__,path.c_str());
1359
1360 if(topLevelCaller == true) {
1361 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION\n",__FILE__,__FUNCTION__,__LINE__);
1362 }
1363
1364 return resultFiles;
1365 }
1366
getFolderTreeContentsCheckSumListCacheKey(const string & path,const string & filterFileExt)1367 std::pair<string,string> getFolderTreeContentsCheckSumListCacheKey(const string &path, const string &filterFileExt) {
1368 string cacheLookupId = CacheManager::getFolderTreeContentsCheckSumListRecursivelyCacheLookupKey2;
1369
1370 string cacheKey = path + "_" + filterFileExt;
1371 return make_pair(cacheLookupId,cacheKey);
1372 }
1373
clearFolderTreeContentsCheckSumList(const string & path,const string & filterFileExt)1374 void clearFolderTreeContentsCheckSumList(const string &path, const string &filterFileExt) {
1375 std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumListCacheKey(path,filterFileExt);
1376 string cacheLookupId = cacheKeys.first;
1377 std::map<string,vector<std::pair<string,uint32> > > &crcTreeCache = CacheManager::getCachedItem< std::map<string,vector<std::pair<string,uint32> > > >(cacheLookupId);
1378
1379 string cacheKey = cacheKeys.second;
1380 if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
1381 crcTreeCache.erase(cacheKey);
1382 }
1383 string crcCacheFile = getFormattedCRCCacheFileName(cacheKeys);
1384 if(fileExists(crcCacheFile) == true) {
1385 bool result = removeFile(crcCacheFile);
1386 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] fileitem [%s] result = %d\n",__FILE__,__FUNCTION__,__LINE__,crcCacheFile.c_str(),result);
1387 }
1388 }
1389
1390 //finds all filenames like path and gets the checksum of each file
getFolderTreeContentsCheckSumListRecursively(const string & path,const string & filterFileExt,vector<std::pair<string,uint32>> * recursiveMap)1391 vector<std::pair<string,uint32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,uint32> > *recursiveMap) {
1392 std::pair<string,string> cacheKeys = getFolderTreeContentsCheckSumListCacheKey(path, filterFileExt);
1393 string cacheLookupId = cacheKeys.first;
1394 std::map<string,vector<std::pair<string,uint32> > > &crcTreeCache = CacheManager::getCachedItem< std::map<string,vector<std::pair<string,uint32> > > >(cacheLookupId);
1395
1396 string cacheKey = cacheKeys.second;
1397 if(crcTreeCache.find(cacheKey) != crcTreeCache.end()) {
1398 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] FOUND CACHED result for cacheKey [%s]\n",__FILE__,__FUNCTION__,path.c_str(),cacheKey.c_str());
1399 return crcTreeCache[cacheKey];
1400 }
1401
1402 bool topLevelCaller = (recursiveMap == NULL);
1403 vector<std::pair<string,uint32> > checksumFiles = (recursiveMap == NULL ? vector<std::pair<string,uint32> >() : *recursiveMap);
1404
1405 std::string mypath = path;
1406 /** Stupid win32 is searching for all files without extension when *. is
1407 * specified as wildcard
1408 */
1409 if((int)mypath.size() >= 2 && mypath.compare(max((int)0,(int)mypath.size() - 2), 2, "*.") == 0) {
1410 mypath = mypath.substr(0, max((int)0,(int)mypath.size() - 2));
1411 mypath += "*";
1412 }
1413
1414 glob_t globbuf;
1415
1416 int res = glob(mypath.c_str(), 0, 0, &globbuf);
1417
1418 #if !defined(__APPLE__) && !defined(__DragonFly__) && !defined(__OpenBSD__)
1419 if(res < 0) {
1420 std::stringstream msg;
1421 msg << "#6 Couldn't scan directory '" << mypath << "': " << strerror(errno);
1422 throw megaglest_runtime_error(msg.str());
1423 }
1424 #endif
1425
1426 for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
1427 const char* p = globbuf.gl_pathv[i];
1428
1429 if(isdir(p) == false) {
1430 bool addFile = true;
1431 if(EndsWith(p, ".") == true || EndsWith(p, "..") == true || EndsWith(p, ".git") == true) {
1432 addFile = false;
1433 }
1434 else if(filterFileExt != "") {
1435 addFile = EndsWith(p, filterFileExt);
1436 }
1437
1438 if(addFile) {
1439 Checksum checksum;
1440 checksum.addFile(p);
1441
1442 checksumFiles.push_back(std::pair<string,uint32>(p,checksum.getSum()));
1443 }
1444 }
1445 }
1446
1447 globfree(&globbuf);
1448
1449 // Look recursively for sub-folders
1450 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__OpenBSD__)
1451 res = glob(mypath.c_str(), 0, 0, &globbuf);
1452 #else //APPLE doesn't have the GLOB_ONLYDIR definition..
1453 res = glob(mypath.c_str(), GLOB_ONLYDIR, 0, &globbuf);
1454 #endif
1455
1456 #if !defined(__APPLE__) && !defined(__DragonFly__) && !defined(__OpenBSD__)
1457 if(res < 0) {
1458 std::stringstream msg;
1459 msg << "#7 Couldn't scan directory '" << mypath << "': " << strerror(errno);
1460 throw megaglest_runtime_error(msg.str());
1461 }
1462 #endif
1463
1464 for(int i = 0; i < (int)globbuf.gl_pathc; ++i) {
1465 #if defined(__APPLE__) || defined(__DragonFly__) || defined(__OpenBSD__)
1466 struct stat statStruct;
1467 // only get if dir..
1468 lstat( globbuf.gl_pathv[ i], &statStruct);
1469 if( S_ISDIR(statStruct.st_mode) == 0)
1470 continue;
1471 #endif
1472 const char *p = globbuf.gl_pathv[i];
1473
1474 string currentPath = p;
1475 endPathWithSlash(currentPath);
1476
1477 checksumFiles = getFolderTreeContentsCheckSumListRecursively(currentPath + "*", filterFileExt, &checksumFiles);
1478 }
1479
1480 globfree(&globbuf);
1481
1482 crcTreeCache[cacheKey] = checksumFiles;
1483
1484 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] scanning [%s] cacheKey [%s] checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,path.c_str(),cacheKey.c_str(),checksumFiles.size());
1485
1486 if(topLevelCaller == true) {
1487 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] EXITING TOP LEVEL RECURSION, checksumFiles.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,checksumFiles.size());
1488 }
1489
1490 return crcTreeCache[cacheKey];
1491 }
1492
extractFileFromDirectoryPath(string filename)1493 string extractFileFromDirectoryPath(string filename) {
1494 size_t lastDirectory = filename.find_last_of("/\\");
1495 if (lastDirectory == string::npos) {
1496 return filename;
1497 }
1498
1499 return filename.erase( 0, lastDirectory + 1);
1500 }
1501
extractDirectoryPathFromFile(string filename)1502 string extractDirectoryPathFromFile(string filename) {
1503 size_t lastDirectory = filename.find_last_of("/\\");
1504 string path = "";
1505 if (lastDirectory != string::npos) {
1506 path = filename.substr( 0, lastDirectory + 1);
1507 }
1508
1509 return path;
1510 }
1511
extractLastDirectoryFromPath(string Path)1512 string extractLastDirectoryFromPath(string Path) {
1513 string result = Path;
1514 size_t lastDirectory = Path.find_last_of("/\\");
1515 if (lastDirectory == string::npos) {
1516 result = Path;
1517 }
1518 else {
1519 if(Path.length() > lastDirectory + 1) {
1520 result = Path.erase( 0, lastDirectory + 1);
1521 }
1522 else {
1523 for(int i = (int)lastDirectory-1; i >= 0; --i) {
1524 if((Path[i] == '/' || Path[i] == '\\') && i > 0) {
1525 result = Path.erase( 0, i);
1526 break;
1527 }
1528 }
1529 }
1530 }
1531 return result;
1532 }
1533
extractExtension(const string & filepath)1534 string extractExtension(const string& filepath) {
1535 size_t lastPoint = filepath.find_last_of('.');
1536 size_t lastDirectory = filepath.find_last_of("/\\");
1537
1538 if (lastPoint == string::npos || (lastDirectory != string::npos && lastDirectory > lastPoint)) {
1539 return "";
1540 }
1541 return filepath.substr(lastPoint+1);
1542 }
1543
createDirectoryPaths(string Path)1544 void createDirectoryPaths(string Path) {
1545 char DirName[256]="";
1546 const char *path = Path.c_str();
1547 char *dirName = DirName;
1548 while(*path) {
1549 //if (('\\' == *path) || ('/' == *path))
1550 if ('/' == *path) {
1551 if(isdir(DirName) == false) {
1552 #ifdef WIN32
1553 int result = _wmkdir(utf8_decode(DirName).c_str());
1554 //int result = _mkdir(DirName);
1555 #elif defined(__GNUC__)
1556 int result = mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG);
1557 #else
1558 #error "Your compiler needs to support mkdir!"
1559 #endif
1560 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DirName [%s] result = %d, errno = %d\n",__FILE__,__FUNCTION__,__LINE__,DirName,result,errno);
1561 }
1562 }
1563 *dirName++ = *path++;
1564 *dirName = '\0';
1565 }
1566 #ifdef WIN32
1567 //int result = _mkdir(DirName);
1568 int result = _wmkdir(utf8_decode(DirName).c_str());
1569 #elif defined(__GNUC__)
1570 int result = mkdir(DirName, S_IRWXU | S_IRWXO | S_IRWXG);
1571 #else
1572 #error "Your compiler needs to support mkdir!"
1573 #endif
1574 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] DirName [%s] result = %d, errno = %d\n",__FILE__,__FUNCTION__,__LINE__,DirName,result,errno);
1575 }
1576
getFullscreenVideoInfo(int & colorBits,int & screenWidth,int & screenHeight,bool isFullscreen)1577 void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight,bool isFullscreen) {
1578 // TTSDL What does this method do ? I have no clue...
1579 //
1580 // // Get the current video hardware information
1581 // //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
1582 // //colorBits = vidInfo->vfmt->BitsPerPixel;
1583 // //screenWidth = vidInfo->current_w;
1584 // //screenHeight = vidInfo->current_h;
1585 //
1586 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
1587 //
1588 // /* Get available fullscreen/hardware modes */
1589 //
1590 // #if defined(WIN32) || defined(__APPLE__)
1591 //
1592 // int flags = 0;
1593 //
1594 // #else
1595 //
1596 // int flags = SDL_WINDOW_RESIZABLE;
1597 //
1598 // #endif
1599 // if(isFullscreen) flags = SDL_WINDOW_FULLSCREEN;
1600 // SDL_Rect**modes = SDL_ListModes(NULL, SDL_OPENGL|flags);
1601 //
1602 // /* Check if there are any modes available */
1603 // if (modes == (SDL_Rect**)0) {
1604 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] no hardware modes available.\n",__FILE__,__FUNCTION__,__LINE__);
1605 //
1606 // const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
1607 // colorBits = vidInfo->vfmt->BitsPerPixel;
1608 // screenWidth = vidInfo->current_w;
1609 // screenHeight = vidInfo->current_h;
1610 //
1611 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight);
1612 // }
1613 // /* Check if our resolution is restricted */
1614 // else if (modes == (SDL_Rect**)-1) {
1615 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] all resolutions available.\n",__FILE__,__FUNCTION__,__LINE__);
1616 //
1617 // const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
1618 // colorBits = vidInfo->vfmt->BitsPerPixel;
1619 // screenWidth = vidInfo->current_w;
1620 // screenHeight = vidInfo->current_h;
1621 //
1622 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight);
1623 // }
1624 // else{
1625 // /* Print valid modes */
1626 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] available Modes are:\n",__FILE__,__FUNCTION__,__LINE__);
1627 //
1628 // int bestW = -1;
1629 // int bestH = -1;
1630 // for(int i=0; modes[i]; ++i) {
1631 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%d x %d\n",modes[i]->w, modes[i]->h);
1632 //
1633 // if(bestW < modes[i]->w) {
1634 // bestW = modes[i]->w;
1635 // bestH = modes[i]->h;
1636 // }
1637 // }
1638 //
1639 // if(bestW > screenWidth) {
1640 // screenWidth = bestW;
1641 // screenHeight = bestH;
1642 // }
1643 //
1644 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] using current resolution: %d x %d.\n",__FILE__,__FUNCTION__,__LINE__,screenWidth,screenHeight);
1645 // }
1646 }
1647
1648
getFullscreenVideoModes(vector<ModeInfo> * modeinfos,bool isFullscreen)1649 void getFullscreenVideoModes(vector<ModeInfo> *modeinfos, bool isFullscreen) {
1650 // Get the current video hardware information
1651 //const SDL_VideoInfo* vidInfo = SDL_GetVideoInfo();
1652 //colorBits = vidInfo->vfmt->BitsPerPixel;
1653 //screenWidth = vidInfo->current_w;
1654 //screenHeight = vidInfo->current_h;
1655
1656 if (SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled)
1657 SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
1658
1659 //SDL_PixelFormat format;
1660 //SDL_Rect **modes;
1661 //int loops(0);
1662 //int bpp(0);
1663 std::map<std::string,bool> uniqueResList;
1664
1665 ///////////////////////////
1666 vector<pair<int,int> > allResoltuions;
1667 SDL_DisplayMode mode = {SDL_PIXELFORMAT_UNKNOWN, 0, 0, 0, 0};
1668 int max=SDL_GetNumDisplayModes(0);
1669 for (int i = 0; i < max; ++i) {
1670 if(0==SDL_GetDisplayMode(0,i,&mode)) {
1671 int bpp;
1672 Uint32 Rmask;
1673 Uint32 Gmask;
1674 Uint32 Bmask;
1675 Uint32 Amask;
1676 SDL_PixelFormatEnumToMasks(mode.format,&bpp,&Rmask,&Gmask,&Bmask,&Amask);
1677 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%d x %d\n",allResoltuions[i].first, allResoltuions[i].second,bpp);
1678 string lookupKey = intToStr(mode.w) + "_" + intToStr(mode.h) + "_" + intToStr(bpp);
1679 if(uniqueResList.find(lookupKey) == uniqueResList.end()) {
1680 uniqueResList[lookupKey] = true;
1681 modeinfos->push_back(ModeInfo(mode.w,mode.h,bpp));
1682 }
1683 }
1684 }
1685 //////////////////////////////////
1686 std::sort(modeinfos->begin(),modeinfos->end());
1687 }
1688
1689
1690
changeVideoModeFullScreen(bool value)1691 void changeVideoModeFullScreen(bool value) {
1692 Private::shouldBeFullscreen = value;
1693 }
1694
restoreVideoMode(SDL_Window * sdlWindow,bool exitingApp)1695 void restoreVideoMode(SDL_Window *sdlWindow,bool exitingApp) {
1696 //SDL_Quit();
1697 if(exitingApp == true && SDL_WasInit(SDL_INIT_VIDEO)) {
1698 SDL_SetRelativeMouseMode(SDL_FALSE);
1699 SDL_SetWindowBrightness(sdlWindow, 1.0f);
1700 }
1701 }
1702
1703 //int getScreenW() {
1704 // return SDL_GetVideoSurface()->w; //SDL_GetWindowSurface()
1705 //}
1706 //
1707 //int getScreenH() {
1708 // return SDL_GetVideoSurface()->h;
1709 //}
1710
sleep(int millis)1711 void sleep(int millis) {
1712 SDL_Delay(millis);
1713 }
1714
isCursorShowing()1715 bool isCursorShowing() {
1716 int state = SDL_ShowCursor(SDL_QUERY);
1717 return (state == SDL_ENABLE);
1718 }
1719
showCursor(bool b)1720 void showCursor(bool b) {
1721 //printf("In showCursor, b: %d, isCursorShowing(): %d\n",b,isCursorShowing());
1722
1723
1724 if(isCursorShowing() == b) {
1725 return;
1726 }
1727 //printf("showCursor(bool b) b=%d\n",b);
1728 SDL_ShowCursor(b == true ? SDL_ENABLE : SDL_DISABLE);
1729 }
1730
1731 //bool isKeyDown(SDLKey key) {
1732 // const Uint8* keystate = SDL_GetKeyboardState(0);
1733 //
1734 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = %d\n",__FILE__,__FUNCTION__,__LINE__,key);
1735 //
1736 // if(key >= 0) {
1737 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] keystate[key] = %d\n",__FILE__,__FUNCTION__,__LINE__,keystate[key]);
1738 //
1739 // return (keystate[key] != 0);
1740 // }
1741 // if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning false\n",__FILE__,__FUNCTION__,__LINE__);
1742 // return false;
1743 //
1744 //}
1745
isKeyDown(int virtualKey)1746 bool isKeyDown(int virtualKey) {
1747 char key = static_cast<char> (virtualKey);
1748 const Uint8* keystate = SDL_GetKeyboardState(0);
1749
1750 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = %d\n",__FILE__,__FUNCTION__,__LINE__,key);
1751
1752 if(key >= 0) {
1753 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] keystate[key] = %d\n",__FILE__,__FUNCTION__,__LINE__,keystate[(unsigned char)key]);
1754
1755 return (keystate[(unsigned char)key] != 0);
1756 }
1757 switch(key) {
1758 //SDLTT case vkAdd:
1759 // return (keystate[SDL_SCANCODE_PLUS] != 0 || keystate[SDL_SCANCODE_KP_PLUS] != 0);
1760 case vkSubtract:
1761 return (keystate[SDL_SCANCODE_MINUS] != 0 || keystate[SDL_SCANCODE_KP_MINUS] != 0);
1762 case vkAlt:
1763 return (keystate[SDL_SCANCODE_LALT] != 0 || keystate[SDL_SCANCODE_RALT] != 0);
1764 case vkControl:
1765 return (keystate[SDL_SCANCODE_LCTRL] != 0 || keystate[SDL_SCANCODE_RCTRL] != 0);
1766 case vkShift:
1767 return (keystate[SDL_SCANCODE_LSHIFT] != 0 || keystate[SDL_SCANCODE_RSHIFT] != 0);
1768 case vkEscape:
1769 return (keystate[SDL_SCANCODE_ESCAPE] != 0);
1770 case vkUp:
1771 return (keystate[SDL_SCANCODE_UP] != 0);
1772 case vkLeft:
1773 return (keystate[SDL_SCANCODE_LEFT] != 0);
1774 case vkRight:
1775 return (keystate[SDL_SCANCODE_RIGHT] != 0);
1776 case vkDown:
1777 return (keystate[SDL_SCANCODE_DOWN] != 0);
1778 case vkReturn:
1779 return (keystate[SDL_SCANCODE_RETURN] != 0 || keystate[SDL_SCANCODE_KP_ENTER] != 0);
1780 case vkBack:
1781 return (keystate[SDL_SCANCODE_BACKSPACE] != 0);
1782 case vkDelete:
1783 return (keystate[SDL_SCANCODE_DELETE] != 0);
1784 case vkPrint:
1785 return (keystate[SDL_SCANCODE_PRINTSCREEN] != 0);
1786 case vkPause:
1787 return (keystate[SDL_SCANCODE_PAUSE] != 0);
1788 default:
1789 std::cerr << "isKeyDown called with unknown key.\n";
1790 break;
1791 }
1792 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] returning false\n",__FILE__,__FUNCTION__,__LINE__);
1793 return false;
1794 }
1795
replaceAllHTMLEntities(string & context)1796 string replaceAllHTMLEntities(string& context) {
1797 replaceAll(context,""","\"");
1798 replaceAll(context,"&","&");
1799 replaceAll(context,"<","<");
1800 replaceAll(context,">",">");
1801 //replaceAll(context,"Œ","Œ");
1802 replaceAll(context,"Œ","\xC5\x92\0");
1803 //replaceAll(context,"œ","œ");
1804 replaceAll(context,"œ","\xC5\x93\0");
1805 //replaceAll(context,"Š","Š");
1806 replaceAll(context,"Š","\xC5\xA0\0");
1807 //replaceAll(context,"š","š");
1808 replaceAll(context,"š","\xC5\xA1\0");
1809 //replaceAll(context,"Ÿ","Ÿ");
1810 replaceAll(context,"Ÿ","\xC5\xB8\0");
1811 replaceAll(context,"ˆ","ˆ");
1812 replaceAll(context,"˜","˜");
1813 replaceAll(context," "," ");
1814 replaceAll(context," "," ");
1815 replaceAll(context," "," ");
1816 replaceAll(context,"–","-");
1817 replaceAll(context,"—","-");
1818 //replaceAll(context,"‘","‘");
1819 replaceAll(context,"‘","\xE2\x80\x98\0");
1820 //replaceAll(context,"’","’");
1821 replaceAll(context,"’","\xE2\x80\x99\0");
1822 //replaceAll(context,"‚","‚");
1823 replaceAll(context,"‚","\xE2\x80\x9A\0");
1824 //replaceAll(context,"“","“");
1825 replaceAll(context,"“","\xE2\x80\x9C\0");
1826 //replaceAll(context,"”","”");
1827 replaceAll(context,"”","\xE2\x80\x9D\0");
1828 //replaceAll(context,"„","„");
1829 replaceAll(context,"„","\xE2\x80\x9E\0");
1830 //replaceAll(context,"†","†");
1831 replaceAll(context,"†","\xE2\x80\xA0\0");
1832 //replaceAll(context,"‡","‡");
1833 replaceAll(context,"‡","\xE2\x80\xA1\0");
1834 //replaceAll(context,"‰","‰");
1835 replaceAll(context,"‰","\xE2\x80\xB0\0");
1836 //replaceAll(context,"‹","‹");
1837 replaceAll(context,"‹","\xE2\x80\xB9\0");
1838 //replaceAll(context,"›","›");
1839 replaceAll(context,"›","\xE2\x80\xBA\0");
1840 //replaceAll(context,"€","€");
1841 replaceAll(context,"€","\xE2\x82\xAC\0");
1842
1843 return context;
1844 }
1845
replaceAll(string & context,const string & from,const string & to)1846 string replaceAll(string& context, const string& from, const string& to) {
1847 size_t lookHere = 0;
1848 size_t foundHere = 0;
1849 if((foundHere = context.find(from, lookHere)) != string::npos) {
1850 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Replacing context [%s] from [%s] to [%s]\n",context.c_str(),from.c_str(),to.c_str());
1851
1852 while((foundHere = context.find(from, lookHere)) != string::npos) {
1853 context.replace(foundHere, from.size(), to);
1854 lookHere = foundHere + to.size();
1855 }
1856
1857 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("New context [%s]\n",context.c_str());
1858 }
1859 return context;
1860 }
1861
replaceAllBetweenTokens(vector<char> & context,const string & startToken,const string & endToken,const string & newText,bool removeTokens)1862 vector<char> replaceAllBetweenTokens(vector<char>& context,
1863 const string &startToken, const string &endToken, const string &newText,
1864 bool removeTokens) {
1865 string newValue(context.begin(),context.end());
1866 replaceAllBetweenTokens(newValue,startToken,endToken,newText,removeTokens);
1867 context = vector<char>(newValue.begin(),newValue.end());
1868 return context;
1869 }
1870
replaceAllBetweenTokens(string & context,const string & startToken,const string & endToken,const string & newText,bool removeTokens)1871 string replaceAllBetweenTokens(string& context, const string &startToken,
1872 const string &endToken, const string &newText, bool removeTokens) {
1873 size_t lookHere = 0;
1874 size_t foundHere = 0;
1875 if((foundHere = context.find(startToken, lookHere)) != string::npos) {
1876 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Replacing context [%s] from [%s] to [%s]\n",context.c_str(),from.c_str(),to.c_str());
1877
1878 while((foundHere = context.find(startToken, lookHere)) != string::npos) {
1879 size_t foundHereEnd = context.find(endToken, foundHere+1);
1880 if(foundHereEnd == string::npos) {
1881 break;
1882 }
1883 if(removeTokens == true) {
1884 foundHereEnd += endToken.size();
1885
1886 context.replace(foundHere, foundHereEnd-foundHere+1, newText);
1887 lookHere = foundHere + newText.size();
1888 }
1889 else {
1890 foundHere += startToken.size();
1891 foundHereEnd -= 1;
1892
1893 context.replace(foundHere, foundHereEnd-foundHere+1, newText);
1894 lookHere = foundHere + newText.size();
1895 }
1896 }
1897
1898 //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("New context [%s]\n",context.c_str());
1899 }
1900 return context;
1901 }
1902
getFullFileArchiveExtractCommand(string fileArchiveExtractCommand,string fileArchiveExtractCommandParameters,string outputpath,string archivename)1903 string getFullFileArchiveExtractCommand(string fileArchiveExtractCommand,
1904 string fileArchiveExtractCommandParameters, string outputpath, string archivename) {
1905 string parsedOutputpath = outputpath;
1906 string parsedArchivename = archivename;
1907
1908 // This is required for execution on win32
1909 #if defined(WIN32)
1910 replaceAll(parsedOutputpath, "\\\\", "\\");
1911 replaceAll(parsedOutputpath, "/", "\\");
1912 replaceAll(parsedArchivename, "\\\\", "\\");
1913 replaceAll(parsedArchivename, "/", "\\");
1914 #endif
1915
1916 string result = fileArchiveExtractCommand;
1917 result += " ";
1918 string args = replaceAll(fileArchiveExtractCommandParameters, "{outputpath}", parsedOutputpath);
1919 args = replaceAll(args, "{archivename}", parsedArchivename);
1920 result += args;
1921
1922 return result;
1923 }
1924
getFullFileArchiveCompressCommand(string fileArchiveCompressCommand,string fileArchiveCompressCommandParameters,string archivename,string archivefiles)1925 string getFullFileArchiveCompressCommand(string fileArchiveCompressCommand,
1926 string fileArchiveCompressCommandParameters,
1927 string archivename, string archivefiles) {
1928 string parsedArchivename = archivename;
1929 string parsedArchivefiles = archivefiles;
1930
1931 // This is required for execution on win32
1932 #if defined(WIN32)
1933 replaceAll(parsedArchivename, "\\\\", "\\");
1934 replaceAll(parsedArchivename, "/", "\\");
1935 replaceAll(parsedArchivefiles, "\\\\", "\\");
1936 replaceAll(parsedArchivefiles, "/", "\\");
1937
1938 #endif
1939
1940 string result = fileArchiveCompressCommand;
1941 result += " ";
1942 string args = replaceAll(fileArchiveCompressCommandParameters, "{archivename}", parsedArchivename);
1943 args = replaceAll(args, "{archivefiles}", parsedArchivefiles);
1944 result += args;
1945
1946 return result;
1947 }
1948
executeShellCommand(string cmd,int expectedResult,ShellCommandOutputCallbackInterface * cb)1949 bool executeShellCommand(string cmd, int expectedResult, ShellCommandOutputCallbackInterface *cb) {
1950 bool result = false;
1951 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"About to run [%s]", cmd.c_str());
1952 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("About to run [%s]", cmd.c_str());
1953
1954 #ifdef WIN32
1955 FILE *file = _wpopen(utf8_decode(cmd).c_str(),L"r");
1956 #else
1957 FILE *file = popen(cmd.c_str(),"r");
1958 #endif
1959
1960 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"file = [%p]", file);
1961 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("file = [%p]", file);
1962
1963 if(file != NULL) {
1964 char szBuf[4096]="";
1965 while(feof(file) == false) {
1966 if(fgets( szBuf, 4095, file) != NULL) {
1967 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"%s",szBuf);
1968 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("%s",szBuf);
1969
1970 if(cb != NULL) {
1971 cb->ShellCommandOutput_CallbackEvent(cmd,szBuf,cb->getShellCommandOutput_UserData(cmd));
1972 }
1973 }
1974 }
1975 #ifdef WIN32
1976 int cmdRet = _pclose(file);
1977 #else
1978 int cmdRet = pclose(file);
1979 #endif
1980
1981 /* Close pipe and print return value. */
1982 if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"Process returned %d\n", cmdRet);
1983 if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Process returned %d\n", cmdRet);
1984 result = (expectedResult == IGNORE_CMD_RESULT_VALUE || expectedResult == cmdRet);
1985 }
1986 return result;
1987 }
1988
removeFile(string file)1989 bool removeFile(string file) {
1990 #ifdef WIN32
1991 int result = _unlink(file.c_str());
1992 #else
1993 int result = unlink(file.c_str());
1994 #endif
1995
1996 return (result == 0);
1997 }
1998
renameFile(string oldFile,string newFile)1999 bool renameFile(string oldFile, string newFile) {
2000 int result = rename(oldFile.c_str(),newFile.c_str());
2001 return (result == 0);
2002 }
2003
getFileSize(string filename)2004 off_t getFileSize(string filename) {
2005 #ifdef WIN32
2006 #if defined(__MINGW32__)
2007 struct _stat stbuf;
2008 #else
2009 struct _stat64i32 stbuf;
2010 #endif
2011 if(_wstat(utf8_decode(filename).c_str(), &stbuf) != -1) {
2012 #else
2013 struct stat stbuf;
2014 if(stat(filename.c_str(), &stbuf) != -1) {
2015 #endif
2016 return stbuf.st_size;
2017 }
2018 return 0;
2019 }
2020
2021 string executable_path(string exeName, bool includeExeNameInPath) {
2022 string value = "";
2023 #ifdef _WIN32
2024 char path[MAX_PATH]="";
2025 if( GetModuleFileNameA(NULL,path,MAX_PATH) == 0 ) {
2026 if(includeExeNameInPath == true) {
2027 value = exeName;
2028 }
2029 else {
2030 value = extractDirectoryPathFromFile(exeName);
2031 }
2032 }
2033 else {
2034 if(includeExeNameInPath == true) {
2035 value = path;
2036 }
2037 else {
2038 value = extractDirectoryPathFromFile(path);
2039 }
2040 }
2041 #elif __APPLE__
2042 char path[MAXPATHLEN+1]="";
2043 uint32_t path_len = MAXPATHLEN;
2044 if ( _NSGetExecutablePath(path, &path_len) ) {
2045 if(includeExeNameInPath == true) {
2046 value = exeName;
2047 }
2048 else {
2049 value = extractDirectoryPathFromFile(exeName);
2050 }
2051 }
2052 else {
2053 if(includeExeNameInPath == true) {
2054 value = path;
2055 }
2056 else {
2057 value = extractDirectoryPathFromFile(path);
2058 }
2059 }
2060 #else
2061 char exe_link_path[200]="";
2062 int length = readlink("/proc/self/exe", exe_link_path, sizeof(exe_link_path));
2063 if(length < 0 || length >= 200 ) {
2064 char *argv0_path = realpath(exeName.c_str(),NULL);
2065 if(argv0_path != NULL) {
2066 if(includeExeNameInPath == true) {
2067 value = argv0_path;
2068 }
2069 else {
2070 value = extractDirectoryPathFromFile(argv0_path);
2071 }
2072 free(argv0_path);
2073 argv0_path = NULL;
2074 }
2075 else {
2076 const char *shell_path = getenv("_");
2077 if(shell_path != NULL) {
2078 if(includeExeNameInPath == true) {
2079 value = shell_path;
2080 }
2081 else {
2082 value = extractDirectoryPathFromFile(shell_path);
2083 }
2084 }
2085 else {
2086 if(includeExeNameInPath == true) {
2087 value = exeName;
2088 }
2089 else {
2090 value = extractDirectoryPathFromFile(exeName);
2091 }
2092 }
2093 }
2094 }
2095 else {
2096 exe_link_path[length] = '\0';
2097 if(includeExeNameInPath == true) {
2098 value = exe_link_path;
2099 }
2100 else {
2101 value = extractDirectoryPathFromFile(exe_link_path);
2102 }
2103 }
2104 #endif
2105 return value;
2106 }
2107
2108 bool searchAndReplaceTextInFile(string fileName, string findText, string replaceText, bool simulateOnly) {
2109 bool replacedText = false;
2110 const int MAX_LEN_SINGLE_LINE = 4096;
2111 char buffer[MAX_LEN_SINGLE_LINE+2];
2112 char *buff_ptr, *find_ptr;
2113 FILE *fp1, *fp2;
2114 size_t find_len = findText.length();
2115
2116 string tempfileName = fileName + "_tmp";
2117 #ifdef WIN32
2118 fp1 = _wfopen(utf8_decode(fileName).c_str(), L"r");
2119 fp2 = _wfopen(utf8_decode(tempfileName).c_str(), L"w");
2120 #else
2121 fp1 = fopen(fileName.c_str(),"r");
2122 fp2 = fopen(tempfileName.c_str(),"w");
2123 #endif
2124
2125 if(fp1 == NULL) {
2126 if(fp2) fclose(fp2);
2127
2128 throw megaglest_runtime_error("cannot open input file [" + fileName + "]");
2129 }
2130 if(fp2 == NULL) {
2131 if(fp1) fclose(fp1);
2132
2133 throw megaglest_runtime_error("cannot open output file [" + tempfileName + "]");
2134 }
2135
2136 while(fgets(buffer,MAX_LEN_SINGLE_LINE + 2,fp1)) {
2137 buff_ptr = buffer;
2138 if(findText != "") {
2139 while ((find_ptr = strstr(buff_ptr,findText.c_str()))) {
2140 //printf("Replacing text [%s] with [%s] in file [%s]\n",findText.c_str(),replaceText.c_str(),fileName.c_str());
2141
2142 while(buff_ptr < find_ptr) {
2143 fputc((int)*buff_ptr++,fp2);
2144 }
2145 fputs(replaceText.c_str(),fp2);
2146
2147 buff_ptr += find_len;
2148 replacedText = true;
2149 }
2150 }
2151 fputs(buff_ptr,fp2);
2152 }
2153
2154 fclose(fp2);
2155 fclose(fp1);
2156
2157 if(replacedText == true && simulateOnly == false) {
2158 removeFile(fileName);
2159 renameFile(tempfileName,fileName);
2160 }
2161 else {
2162 removeFile(tempfileName);
2163 }
2164 //removeFile(tempfileName);
2165 return replacedText;
2166 }
2167
2168 void saveDataToFile(string filename, string data) {
2169 //Open an input and output stream in binary mode
2170 #if defined(WIN32) && !defined(__MINGW32__)
2171 FILE *fp2 = _wfopen(utf8_decode(filename).c_str(), L"wb");
2172 ofstream out(fp2);
2173 #else
2174 ofstream out(filename.c_str(),ios::binary);
2175 #endif
2176
2177 if(out.is_open()) {
2178 out<< data;
2179 }
2180 else if(out.is_open() == false) {
2181 throw megaglest_runtime_error("cannot open input file [" + filename + "]");
2182 }
2183
2184 //Close file
2185 out.close();
2186
2187 #if defined(WIN32) && !defined(__MINGW32__)
2188 if(fp2) {
2189 fclose(fp2);
2190 }
2191 #endif
2192 }
2193
2194 void copyFileTo(string fromFileName, string toFileName) {
2195 //Open an input and output stream in binary mode
2196 #if defined(WIN32) && !defined(__MINGW32__)
2197 FILE *fp1 = _wfopen(utf8_decode(fromFileName).c_str(), L"rb");
2198 ifstream in(fp1);
2199 FILE *fp2 = _wfopen(utf8_decode(toFileName).c_str(), L"wb");
2200 ofstream out(fp2);
2201 #else
2202 ifstream in(fromFileName.c_str(),ios::binary);
2203 ofstream out(toFileName.c_str(),ios::binary);
2204 #endif
2205
2206 if(in.is_open() && out.is_open()) {
2207 while(in.eof() == false) {
2208 out.put(in.get());
2209 }
2210 }
2211 else if(in.is_open() == false) {
2212 throw megaglest_runtime_error("cannot open input file [" + fromFileName + "]");
2213 }
2214 else if(out.is_open() == false) {
2215 throw megaglest_runtime_error("cannot open input file [" + toFileName + "]");
2216 }
2217
2218 //Close both files
2219 in.close();
2220 out.close();
2221
2222 #if defined(WIN32) && !defined(__MINGW32__)
2223 if(fp1) {
2224 fclose(fp1);
2225 }
2226 if(fp2) {
2227 fclose(fp2);
2228 }
2229 #endif
2230 }
2231
2232 bool valid_utf8_file(const char* file_name) {
2233 #if defined(WIN32) && !defined(__MINGW32__)
2234 wstring wstr = utf8_decode(file_name);
2235 FILE *fp = _wfopen(wstr.c_str(), L"r");
2236 ifstream ifs(fp);
2237 #else
2238 ifstream ifs(file_name);
2239 #endif
2240
2241 if (!ifs) {
2242 return false; // even better, throw here
2243 }
2244 istreambuf_iterator<char> it(ifs.rdbuf());
2245 istreambuf_iterator<char> eos;
2246
2247 bool result = utf8::is_valid(it, eos);
2248
2249 ifs.close();
2250 #if defined(WIN32) && !defined(__MINGW32__)
2251 if(fp) {
2252 fclose(fp);
2253 }
2254 #endif
2255
2256 return result;
2257 }
2258
2259 string getFileTextContents(string path) {
2260 #if defined(WIN32) && !defined(__MINGW32__)
2261 FILE *fp = _wfopen(utf8_decode(path).c_str(), L"rb");
2262 ifstream xmlFile(fp);
2263 #else
2264 ifstream xmlFile(path.c_str(),ios::binary);
2265 #endif
2266 if(xmlFile.is_open() == false) {
2267 throw megaglest_runtime_error("Can not open file: [" + path + "]");
2268 }
2269
2270 xmlFile.unsetf(ios::skipws);
2271
2272 // Determine stream size
2273 xmlFile.seekg(0, ios::end);
2274 streampos size = xmlFile.tellg();
2275 xmlFile.seekg(0);
2276
2277 // Load data and add terminating 0
2278 vector<char> buffer;
2279 buffer.resize((unsigned int)size + 1);
2280 xmlFile.read(&buffer.front(), static_cast<streamsize>(size));
2281 buffer[(unsigned int)size] = 0;
2282
2283 return &buffer.front();
2284 }
2285
2286 // =====================================
2287 // ModeInfo
2288 // =====================================
2289
2290 ModeInfo::ModeInfo(int w, int h, int d) {
2291 width=w;
2292 height=h;
2293 depth=d;
2294 }
2295
2296 string ModeInfo::getString() const{
2297 return intToStr(width)+"x"+intToStr(height)+"-"+intToStr(depth);
2298 }
2299
2300 void ValueCheckerVault::addItemToVault(const void *ptr,int value) {
2301 #ifndef _DISABLE_MEMORY_VAULT_CHECKS
2302
2303 Checksum checksum;
2304 vaultList[ptr] = checksum.addInt(value);
2305
2306 #endif
2307
2308 // if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] add vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value);
2309 }
2310
2311 void ValueCheckerVault::checkItemInVault(const void *ptr,int value) const {
2312 #ifndef _DISABLE_MEMORY_VAULT_CHECKS
2313
2314 map<const void *,uint32>::const_iterator iterFind = vaultList.find(ptr);
2315 if(iterFind == vaultList.end()) {
2316 // if(SystemFlags::VERBOSE_MODE_ENABLED) {
2317 // printf("In [%s::%s Line: %d] check vault key [%p] value [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,value);
2318 // for(map<const void *,string>::const_iterator iterFind = vaultList.begin();
2319 // iterFind != vaultList.end(); iterFind++) {
2320 // printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str());
2321 // }
2322 // }
2323 throw std::runtime_error("memory value has been unexpectedly modified (not found)!");
2324 }
2325 Checksum checksum;
2326 if(iterFind->second != checksum.addInt(value)) {
2327 // if(SystemFlags::VERBOSE_MODE_ENABLED) {
2328 // printf("In [%s::%s Line: %d] check vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value);
2329 // for(map<const void *,string>::const_iterator iterFind = vaultList.begin();
2330 // iterFind != vaultList.end(); iterFind++) {
2331 // printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str());
2332 // }
2333 // }
2334 throw std::runtime_error("memory value has been unexpectedly modified (changed)!");
2335 }
2336
2337 #endif
2338
2339 }
2340
2341 string getUserHome() {
2342 string home_folder;
2343 home_folder = safeCharPtrCopy(getenv("HOME"),8095);
2344 if(home_folder == "") {
2345 #if _BSD_SOURCE || _SVID_SOURCE || _XOPEN_SOURCE >= 500 || _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED
2346 struct passwd *pw = getpwuid(getuid());
2347 home_folder = safeCharPtrCopy(pw->pw_dir,8095);
2348 #endif
2349 }
2350 return home_folder;
2351 }
2352
2353 string safeCharPtrCopy(const char *ptr,int maxLength) {
2354 string result = "";
2355 if(ptr == NULL) {
2356 return result;
2357 }
2358 if(maxLength <= 0) {
2359 maxLength = 8096;
2360 }
2361
2362 int ptrLength = (int)strlen(ptr);
2363 if(ptrLength >= maxLength) {
2364 char *pBuffer = new char[maxLength+1];
2365 memset(pBuffer,0,maxLength+1);
2366 #ifdef WIN32
2367 memcpy(pBuffer,ptr,min((int)strlen(ptr),maxLength));
2368 #else
2369 memcpy(pBuffer,ptr,std::min((int)strlen(ptr),maxLength));
2370 #endif
2371
2372 result = pBuffer;
2373 delete [] pBuffer;
2374 }
2375 else {
2376 result = ptr;
2377 }
2378 return result;
2379 }
2380
2381
2382 }}//end namespace
2383