filefunctions.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. int bajs;
  65. sscanf(exif.DateTimeOriginal.c_str(), "%i:%i:%i %i:%i:%i", &result->tm_year, &result->tm_mon, &result->tm_mday, &result->tm_hour, &result->tm_min, &result->tm_sec);
  66. // Coarse sanity check to avoid very invalid dates
  67. if(result->tm_year < 70 || result->tm_yday > 200)
  68. {
  69. delete result;
  70. return nullptr;
  71. }
  72. result->tm_year -= 1900;
  73. result->tm_mon -= 1;
  74. return result;
  75. }
  76. STATUS_CODE filefunctions::cd(std::string const &path_arg, COMMAND_FLAGS flags)
  77. {
  78. DWORD attr;
  79. std::string path;
  80. if(flags&CF_RELATIVE)
  81. {
  82. path = filefunctions_wd;
  83. if(path.length() == 0)
  84. {
  85. int path_len = GetCurrentDirectory(0, nullptr);
  86. LPTSTR temp = new TCHAR[path_len+1];
  87. if(!GetCurrentDirectory(path_len+1, temp))
  88. return SC_INVALID_PATH;
  89. path = std::string(temp);
  90. DEBUG("__CD__ GetCurrentDirectory() = " << temp);
  91. delete[] temp;
  92. }
  93. if(path_arg.length())
  94. path += "\\" + path_arg;
  95. }
  96. else
  97. {
  98. path = path_arg;
  99. }
  100. attr = GetFileAttributes(path.c_str());
  101. DEBUG("__CD__ Path: " << path);
  102. DEBUG("__CD__ Attr: " << std::hex << attr);
  103. if(attr == FILE_ATTRIBUTE_DIRECTORY)
  104. {
  105. filefunctions_wd = path;
  106. return SC_SUCCESS;
  107. }
  108. return SC_INVALID_PATH;
  109. }
  110. STATUS_CODE filefunctions::mv(std::string const &src_arg, std::string const &dest_arg, COMMAND_FLAGS flags)
  111. {
  112. std::string src, dest;
  113. DWORD attr;
  114. if(flags & CF_RELATIVE)
  115. {
  116. src = filefunctions_wd;
  117. dest = filefunctions_wd;
  118. if(src.length())
  119. src += "\\" + src_arg;
  120. if(dest.length())
  121. dest += "\\" + dest_arg;
  122. }
  123. else
  124. {
  125. src = src_arg;
  126. dest = dest_arg;
  127. }
  128. DEBUG("__MV__ Source: " << src);
  129. DEBUG("__MV__ Destination: " << dest);
  130. attr = GetFileAttributes(src.c_str());
  131. if (attr == INVALID_FILE_ATTRIBUTES)
  132. {
  133. DEBUG("__MV__ Source does not exist");
  134. return SC_DOES_NOT_EXIST;
  135. }
  136. if(mkdir(dest.substr(0,dest.find_last_of('/\\'))))
  137. {
  138. DEBUG("__MV__ Could not determine destination directory");
  139. return SC_INVALID_DESTINATION;
  140. }
  141. if(MoveFile(src.c_str(), dest.c_str()))
  142. {
  143. DEBUG("__MV__ Moved file\n\n");
  144. return SC_SUCCESS;
  145. }
  146. if(GetLastError() == ERROR_ALREADY_EXISTS)
  147. {
  148. DEBUG("__MV__ Target already exists");
  149. return SC_ALREADY_EXISTS;
  150. }
  151. return SC_OTHER_FAILIURE;
  152. }
  153. STATUS_CODE filefunctions::mkdir(std::string const &arg_path, COMMAND_FLAGS flags)
  154. {
  155. std::string path;
  156. if(flags & CF_RELATIVE)
  157. {
  158. path = filefunctions_wd;
  159. if(arg_path.length())
  160. path += "\\" + arg_path;
  161. }
  162. else
  163. {
  164. path = arg_path;
  165. }
  166. DEBUG("__MKDIR__ Path: " << path);
  167. DWORD attr = GetFileAttributes(path.c_str());
  168. if(attr == FILE_ATTRIBUTE_DIRECTORY)
  169. {
  170. DEBUG("__MKDIR__ SUCCESS Attr: " << attr);
  171. return SC_SUCCESS;
  172. }
  173. else if(attr != INVALID_FILE_ATTRIBUTES)
  174. {
  175. DEBUG("__MKDIR__ FAILED Attr: " << attr);
  176. return SC_IS_NOT_DIRECTORY;
  177. }
  178. size_t parent_separator = path.find_last_of('/\\');
  179. if(parent_separator == std::string::npos)
  180. {
  181. DEBUG("__MKDIR__ Invalid path");
  182. return SC_INVALID_PATH;
  183. }
  184. std::string parent = path.substr(0,parent_separator);
  185. DEBUG("__MKDIR__ Parent: " << parent);
  186. if(mkdir(parent) == SC_SUCCESS)
  187. {
  188. if(CreateDirectory(path.c_str(), nullptr))
  189. {
  190. DEBUG("__MKDIR__ Created directory: " << path);
  191. return SC_SUCCESS;
  192. }
  193. else
  194. {
  195. DEBUG("__MKDIR__ CreateDirectory failed");
  196. return SC_OTHER_FAILIURE;
  197. }
  198. }
  199. else
  200. {
  201. DEBUG("__MKDIR__ mkdir(" << parent << ") failed");
  202. return SC_OTHER_FAILIURE;
  203. }
  204. }
  205. //STATUS_CODE filefunctions::rm(std::string const &path, COMMAND_FLAGS flags = CF_NONE);
  206. std::string filefunctions::pwd(void)
  207. {
  208. return filefunctions_wd;
  209. }
  210. STATUS_CODE filefunctions::ls(std::string path_arg, std::queue<File_Struct> &content, COMMAND_FLAGS flags)
  211. {
  212. std::string path;
  213. if(flags & CF_RELATIVE)
  214. {
  215. path = filefunctions_wd;
  216. if(path_arg.length())
  217. path += path_arg;
  218. }
  219. else
  220. {
  221. path = path_arg;
  222. }
  223. DEBUG("__LS__ ls(" << path << ")");
  224. DWORD attr = GetFileAttributes(path.c_str());
  225. if(attr != FILE_ATTRIBUTE_DIRECTORY)
  226. return SC_IS_NOT_DIRECTORY;
  227. std::string path_joker = path + "\\*";
  228. WIN32_FIND_DATA file_data;
  229. HANDLE status = FindFirstFile(path_joker.c_str(), &file_data);
  230. if(status == INVALID_HANDLE_VALUE)
  231. return SC_OTHER_FAILIURE;
  232. do
  233. {
  234. File_Struct temp;
  235. temp.path = path + "\\" + file_data.cFileName;
  236. if (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  237. {
  238. DEBUG("__LS__ Found directory!");
  239. DEBUG("__LS__ Directory: \"" << temp.path << "\"");
  240. if(flags&CF_RECURSIVE)
  241. {
  242. if(strcmp(file_data.cFileName, ".")==0 || strcmp(file_data.cFileName, "..")==0)
  243. {
  244. DEBUG("__LS__ Ignoring directory . or ..");
  245. }
  246. else
  247. {
  248. DEBUG("__LS__ Which is not . or ..\nGoing in!\n");
  249. ls(temp.path, content, CF_RECURSIVE);
  250. }
  251. }
  252. else
  253. {
  254. DEBUG("__LS__ Ignoring directory, not recursive");
  255. }
  256. }
  257. else
  258. {
  259. DEBUG("__LS__ Found file!");
  260. DEBUG("__LS__ File: \"" << temp.path << "\"");
  261. time_t unix_time = filetime_to_unixtime(file_data.ftLastWriteTime);
  262. DEBUG("__LS__ Modified time: " << std::dec << unix_time);
  263. temp.modified = new tm;
  264. memcpy(temp.modified, localtime(&unix_time), sizeof(tm));
  265. temp.file_ending = temp.path.substr(temp.path.find_last_of('.')+1);
  266. std::transform(temp.file_ending.begin(), temp.file_ending.end(), temp.file_ending.begin(), ::tolower);
  267. DEBUG("__LS__ File ending: " << temp.file_ending);
  268. if(temp.file_ending == "jpeg" || temp.file_ending == "jpg")
  269. {
  270. DEBUG("__LS__ Found JPEG-file, decoding EXIF");
  271. temp.taken = get_exif_time(temp.path);
  272. }
  273. content.push(temp);
  274. }
  275. DEBUG("__LS__ Checking for other files\n");
  276. } while (FindNextFile(status, &file_data) != 0);
  277. DEBUG("__LS__ Finnished ls()\n\n");
  278. return SC_SUCCESS;
  279. }
  280. #else
  281. // Fail?
  282. Hård fail som fan!
  283. #endif // __linux__