filefunctions.cpp 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. #include "filefunctions.h"
  2. #include "debugging.h"
  3. #include "exif.h"
  4. #include <string>
  5. #include <algorithm>
  6. #include <cstdio>
  7. #include <iostream>
  8. #include <sstream>
  9. #include <iomanip>
  10. #include <locale>
  11. using namespace filefunctions;
  12. std::string filefunctions::filefunctions_wd;
  13. COMMAND_FLAGS filefunctions::operator|(filefunctions::COMMAND_FLAGS a, filefunctions::COMMAND_FLAGS b)
  14. {
  15. return COMMAND_FLAGS(int(a)|int(b));
  16. }
  17. #ifdef __linux__
  18. // Linux methods
  19. Ej implementerat
  20. #elif _WIN32
  21. // Windows methods
  22. #include <windows.h>
  23. time_t filetime_to_unixtime(FILETIME const &t)
  24. {
  25. LARGE_INTEGER big_time;
  26. time_t unix_time;
  27. big_time.HighPart = t.dwHighDateTime;
  28. big_time.LowPart = t.dwLowDateTime;
  29. unix_time = big_time.QuadPart/10000000-11644473600;
  30. return unix_time;
  31. }
  32. tm* get_exif_time(std::string path)
  33. {
  34. FILE *filen = fopen(path.c_str(), "rb");
  35. if (filen == nullptr)
  36. {
  37. DEBUG("__GET_EXIF_TIME__ Could not find file: " << path);
  38. return nullptr;
  39. }
  40. DEBUG("__GET_EXIF_TIME__ Opened file: " << path);
  41. fseek(filen, 0, SEEK_END);
  42. unsigned long file_size = ftell(filen);
  43. rewind(filen);
  44. unsigned char *buf = new unsigned char[file_size];
  45. DEBUG("__GET_EXIF_TIME__ File size: " << file_size);
  46. if (fread(buf, 1, file_size, filen) != file_size)
  47. {
  48. DEBUG("__GET_EXIF_TIME__ Could not read file");
  49. delete[] buf;
  50. fclose(filen);
  51. return nullptr;
  52. }
  53. fclose(filen);
  54. easyexif::EXIFInfo exif;
  55. if(exif.parseFrom(buf, file_size))
  56. {
  57. DEBUG("__GET_EXIF_TIME__ Could not parse file");
  58. delete[] buf;
  59. return nullptr;
  60. }
  61. delete[] buf;
  62. DEBUG("__GET_EXIF_TIME__ File parsed!");
  63. tm *result = new tm;
  64. //tm *result = (tm*)malloc(sizeof(tm));
  65. int bajs;
  66. sscanf(exif.DateTimeOriginal.c_str(), "%d:%d:%d %d:%d:%d", &result->tm_year, &result->tm_mon, &result->tm_mday, &result->tm_hour, &result->tm_min, &result->tm_sec);
  67. DEBUG("__GET_EXIF_TIME__ DateTime: " << exif.DateTimeOriginal.c_str());
  68. DEBUG("__GET_EXIF_TIME__ year: " << result->tm_year);
  69. DEBUG("__GET_EXIF_TIME__ month: " << result->tm_mon);
  70. DEBUG("__GET_EXIF_TIME__ date: " << result->tm_mday);
  71. DEBUG("__GET_EXIF_TIME__ hour: " << result->tm_hour);
  72. DEBUG("__GET_EXIF_TIME__ minute: " << result->tm_min);
  73. DEBUG("__GET_EXIF_TIME__ second: " << result->tm_sec);
  74. result->tm_year -= 1900;
  75. result->tm_mon -= 1;
  76. time_t unix_time = mktime(result);
  77. DEBUG("__GET_EXIF_TIME__ Time: " << unix_time);
  78. // Sort of a sanity check
  79. if(unix_time == -1)
  80. {
  81. delete result;
  82. return nullptr;
  83. }//*/
  84. return result;
  85. }
  86. STATUS_CODE filefunctions::cd(std::string const &path_arg, COMMAND_FLAGS flags)
  87. {
  88. DWORD attr;
  89. std::string path;
  90. if(flags&CF_RELATIVE)
  91. {
  92. path = filefunctions_wd;
  93. if(path.length() == 0)
  94. {
  95. int path_len = GetCurrentDirectory(0, nullptr);
  96. LPTSTR temp = new TCHAR[path_len+1];
  97. if(!GetCurrentDirectory(path_len+1, temp))
  98. return SC_INVALID_PATH;
  99. path = std::string(temp);
  100. DEBUG("__CD__ GetCurrentDirectory() = " << temp);
  101. delete[] temp;
  102. }
  103. if(path_arg.length())
  104. path += "\\" + path_arg;
  105. }
  106. else
  107. {
  108. path = path_arg;
  109. }
  110. attr = GetFileAttributes(path.c_str());
  111. DEBUG("__CD__ Path: " << path);
  112. DEBUG("__CD__ Attr: " << std::hex << attr);
  113. if(attr != INVALID_FILE_ATTRIBUTES && attr&FILE_ATTRIBUTE_DIRECTORY)
  114. {
  115. filefunctions_wd = path;
  116. return SC_SUCCESS;
  117. }
  118. return SC_INVALID_PATH;
  119. }
  120. STATUS_CODE filefunctions::mv(std::string const &src_arg, std::string const &dest_arg, COMMAND_FLAGS flags)
  121. {
  122. std::string src, dest;
  123. DWORD attr;
  124. if(flags & CF_RELATIVE)
  125. {
  126. src = filefunctions_wd;
  127. dest = filefunctions_wd;
  128. if(src.length())
  129. src += "\\" + src_arg;
  130. if(dest.length())
  131. dest += "\\" + dest_arg;
  132. }
  133. else
  134. {
  135. src = src_arg;
  136. dest = dest_arg;
  137. }
  138. DEBUG("__MV__ Source: " << src);
  139. DEBUG("__MV__ Destination: " << dest);
  140. attr = GetFileAttributes(src.c_str());
  141. if (attr == INVALID_FILE_ATTRIBUTES)
  142. {
  143. DEBUG("__MV__ Source does not exist");
  144. return SC_DOES_NOT_EXIST;
  145. }
  146. if(mkdir(dest.substr(0,dest.find_last_of('/\\'))))
  147. {
  148. DEBUG("__MV__ Could not determine destination directory");
  149. return SC_INVALID_DESTINATION;
  150. }
  151. if(MoveFile(src.c_str(), dest.c_str()))
  152. {
  153. DEBUG("__MV__ Moved file\n\n");
  154. return SC_SUCCESS;
  155. }
  156. if(GetLastError() == ERROR_ALREADY_EXISTS)
  157. {
  158. DEBUG("__MV__ Target already exists");
  159. return SC_ALREADY_EXISTS;
  160. }
  161. return SC_OTHER_FAILIURE;
  162. }
  163. STATUS_CODE filefunctions::mkdir(std::string const &arg_path, COMMAND_FLAGS flags)
  164. {
  165. std::string path;
  166. if(flags & CF_RELATIVE)
  167. {
  168. path = filefunctions_wd;
  169. if(arg_path.length())
  170. path += "\\" + arg_path;
  171. }
  172. else
  173. {
  174. path = arg_path;
  175. }
  176. DEBUG("__MKDIR__ Path: " << path);
  177. DWORD attr = GetFileAttributes(path.c_str());
  178. if(attr != INVALID_FILE_ATTRIBUTES && attr&FILE_ATTRIBUTE_DIRECTORY)
  179. {
  180. DEBUG("__MKDIR__ SUCCESS Attr: " << attr);
  181. return SC_SUCCESS;
  182. }
  183. else if(attr != INVALID_FILE_ATTRIBUTES)
  184. {
  185. DEBUG("__MKDIR__ FAILED Attr: " << attr);
  186. return SC_IS_NOT_DIRECTORY;
  187. }
  188. size_t parent_separator = path.find_last_of('/\\');
  189. if(parent_separator == std::string::npos)
  190. {
  191. DEBUG("__MKDIR__ Invalid path");
  192. return SC_INVALID_PATH;
  193. }
  194. std::string parent = path.substr(0,parent_separator);
  195. DEBUG("__MKDIR__ Parent: " << parent);
  196. if(mkdir(parent) == SC_SUCCESS)
  197. {
  198. if(CreateDirectory(path.c_str(), nullptr))
  199. {
  200. DEBUG("__MKDIR__ Created directory: " << path);
  201. return SC_SUCCESS;
  202. }
  203. else
  204. {
  205. DEBUG("__MKDIR__ CreateDirectory failed");
  206. return SC_OTHER_FAILIURE;
  207. }
  208. }
  209. else
  210. {
  211. DEBUG("__MKDIR__ mkdir(" << parent << ") failed");
  212. return SC_OTHER_FAILIURE;
  213. }
  214. }
  215. //STATUS_CODE filefunctions::rm(std::string const &path, COMMAND_FLAGS flags = CF_NONE);
  216. std::string filefunctions::pwd(void)
  217. {
  218. return filefunctions_wd;
  219. }
  220. STATUS_CODE filefunctions::ls(std::string path_arg, std::queue<File_Struct> &content, COMMAND_FLAGS flags)
  221. {
  222. std::string path;
  223. if(flags & CF_RELATIVE)
  224. {
  225. path = filefunctions_wd;
  226. if(path_arg.length())
  227. path += path_arg;
  228. }
  229. else
  230. {
  231. path = path_arg;
  232. }
  233. DEBUG("__LS__ ls(" << path << ")");
  234. DWORD attr = GetFileAttributes(path.c_str());
  235. if(attr != INVALID_FILE_ATTRIBUTES && !(attr&FILE_ATTRIBUTE_DIRECTORY))
  236. return SC_IS_NOT_DIRECTORY;
  237. std::string path_joker = path + "\\*";
  238. WIN32_FIND_DATA file_data;
  239. HANDLE status = FindFirstFile(path_joker.c_str(), &file_data);
  240. if(status == INVALID_HANDLE_VALUE)
  241. return SC_OTHER_FAILIURE;
  242. do
  243. {
  244. File_Struct temp;
  245. temp.modified = nullptr;
  246. temp.taken = nullptr;
  247. temp.file_ending = "";
  248. temp.path = path + "\\" + file_data.cFileName;
  249. if (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  250. {
  251. DEBUG("__LS__ Found directory!");
  252. DEBUG("__LS__ Directory: \"" << temp.path << "\"");
  253. if(flags&CF_RECURSIVE)
  254. {
  255. if(strcmp(file_data.cFileName, ".")==0 || strcmp(file_data.cFileName, "..")==0)
  256. {
  257. DEBUG("__LS__ Ignoring directory . or ..");
  258. }
  259. else
  260. {
  261. INFO("__LS__ Found directory. Going in!\n");
  262. ls(temp.path, content, CF_RECURSIVE);
  263. }
  264. }
  265. else
  266. {
  267. DEBUG("__LS__ Ignoring directory, not recursive");
  268. }
  269. }
  270. else
  271. {
  272. DEBUG("__LS__ Found file!");
  273. INFO("__LS__ File: \"" << temp.path << "\"");
  274. time_t unix_time = filetime_to_unixtime(file_data.ftLastWriteTime);
  275. DEBUG("__LS__ Modified time: " << std::dec << unix_time);
  276. if(unix_time < 800000000 || unix_time > 3500000000)
  277. {
  278. delete temp.modified;
  279. temp.modified = nullptr;
  280. }
  281. else
  282. {
  283. temp.modified = new tm;
  284. memcpy(temp.modified, localtime(&unix_time), sizeof(tm));
  285. }
  286. temp.file_ending = temp.path.substr(temp.path.find_last_of('.')+1);
  287. std::transform(temp.file_ending.begin(), temp.file_ending.end(), temp.file_ending.begin(), ::tolower);
  288. DEBUG("__LS__ File ending: " << temp.file_ending);
  289. if(temp.file_ending == "jpeg" || temp.file_ending == "jpg")
  290. {
  291. DEBUG("__LS__ Found JPEG-file, decoding EXIF");
  292. temp.taken = get_exif_time(temp.path);
  293. }
  294. content.push(temp);
  295. }
  296. DEBUG("__LS__ Checking for other files\n");
  297. } while (FindNextFile(status, &file_data) != 0);
  298. DEBUG("__LS__ Finnished ls()\n\n");
  299. return SC_SUCCESS;
  300. }
  301. #else
  302. // Fail?
  303. Hård fail som fan!
  304. #endif // __linux__