#include "filefunctions.h" #include "debugging.h" #include "exif.h" #include #include #include #include #include #include #include using namespace filefunctions; std::string filefunctions::filefunctions_wd; COMMAND_FLAGS filefunctions::operator|(filefunctions::COMMAND_FLAGS a, filefunctions::COMMAND_FLAGS b) { return COMMAND_FLAGS(int(a)|int(b)); } #ifdef __linux__ // Linux methods Ej implementerat #elif _WIN32 // Windows methods #include time_t filetime_to_unixtime(FILETIME const &t) { LARGE_INTEGER big_time; time_t unix_time; big_time.HighPart = t.dwHighDateTime; big_time.LowPart = t.dwLowDateTime; unix_time = big_time.QuadPart/10000000-11644473600; return unix_time; } tm* get_exif_time(std::string path) { FILE *filen = fopen(path.c_str(), "rb"); if (filen == nullptr) { DEBUG("__GET_EXIF_TIME__ Could not find file: " << path); return nullptr; } DEBUG("__GET_EXIF_TIME__ Opened file: " << path); fseek(filen, 0, SEEK_END); unsigned long file_size = ftell(filen); rewind(filen); unsigned char *buf = new unsigned char[file_size]; DEBUG("__GET_EXIF_TIME__ File size: " << file_size); if (fread(buf, 1, file_size, filen) != file_size) { DEBUG("__GET_EXIF_TIME__ Could not read file"); delete[] buf; fclose(filen); return nullptr; } fclose(filen); easyexif::EXIFInfo exif; if(exif.parseFrom(buf, file_size)) { DEBUG("__GET_EXIF_TIME__ Could not parse file"); delete[] buf; return nullptr; } delete[] buf; DEBUG("__GET_EXIF_TIME__ File parsed!"); tm *result = new tm; int bajs; 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); // Coarse sanity check to avoid very invalid dates if(result->tm_year < 70 || result->tm_yday > 200) { delete result; return nullptr; } result->tm_year -= 1900; result->tm_mon -= 1; return result; } STATUS_CODE filefunctions::cd(std::string const &path_arg, COMMAND_FLAGS flags) { DWORD attr; std::string path; if(flags&CF_RELATIVE) { path = filefunctions_wd; if(path.length() == 0) { int path_len = GetCurrentDirectory(0, nullptr); LPTSTR temp = new TCHAR[path_len+1]; if(!GetCurrentDirectory(path_len+1, temp)) return SC_INVALID_PATH; path = std::string(temp); DEBUG("__CD__ GetCurrentDirectory() = " << temp); delete[] temp; } if(path_arg.length()) path += "\\" + path_arg; } else { path = path_arg; } attr = GetFileAttributes(path.c_str()); DEBUG("__CD__ Path: " << path); DEBUG("__CD__ Attr: " << std::hex << attr); if(attr == FILE_ATTRIBUTE_DIRECTORY) { filefunctions_wd = path; return SC_SUCCESS; } return SC_INVALID_PATH; } STATUS_CODE filefunctions::mv(std::string const &src_arg, std::string const &dest_arg, COMMAND_FLAGS flags) { std::string src, dest; DWORD attr; if(flags & CF_RELATIVE) { src = filefunctions_wd; dest = filefunctions_wd; if(src.length()) src += "\\" + src_arg; if(dest.length()) dest += "\\" + dest_arg; } else { src = src_arg; dest = dest_arg; } DEBUG("__MV__ Source: " << src); DEBUG("__MV__ Destination: " << dest); attr = GetFileAttributes(src.c_str()); if (attr == INVALID_FILE_ATTRIBUTES) { DEBUG("__MV__ Source does not exist"); return SC_DOES_NOT_EXIST; } if(mkdir(dest.substr(0,dest.find_last_of('/\\')))) { DEBUG("__MV__ Could not determine destination directory"); return SC_INVALID_DESTINATION; } if(MoveFile(src.c_str(), dest.c_str())) { DEBUG("__MV__ Moved file\n\n"); return SC_SUCCESS; } if(GetLastError() == ERROR_ALREADY_EXISTS) { DEBUG("__MV__ Target already exists"); return SC_ALREADY_EXISTS; } return SC_OTHER_FAILIURE; } STATUS_CODE filefunctions::mkdir(std::string const &arg_path, COMMAND_FLAGS flags) { std::string path; if(flags & CF_RELATIVE) { path = filefunctions_wd; if(arg_path.length()) path += "\\" + arg_path; } else { path = arg_path; } DEBUG("__MKDIR__ Path: " << path); DWORD attr = GetFileAttributes(path.c_str()); if(attr == FILE_ATTRIBUTE_DIRECTORY) { DEBUG("__MKDIR__ SUCCESS Attr: " << attr); return SC_SUCCESS; } else if(attr != INVALID_FILE_ATTRIBUTES) { DEBUG("__MKDIR__ FAILED Attr: " << attr); return SC_IS_NOT_DIRECTORY; } size_t parent_separator = path.find_last_of('/\\'); if(parent_separator == std::string::npos) { DEBUG("__MKDIR__ Invalid path"); return SC_INVALID_PATH; } std::string parent = path.substr(0,parent_separator); DEBUG("__MKDIR__ Parent: " << parent); if(mkdir(parent) == SC_SUCCESS) { if(CreateDirectory(path.c_str(), nullptr)) { DEBUG("__MKDIR__ Created directory: " << path); return SC_SUCCESS; } else { DEBUG("__MKDIR__ CreateDirectory failed"); return SC_OTHER_FAILIURE; } } else { DEBUG("__MKDIR__ mkdir(" << parent << ") failed"); return SC_OTHER_FAILIURE; } } //STATUS_CODE filefunctions::rm(std::string const &path, COMMAND_FLAGS flags = CF_NONE); std::string filefunctions::pwd(void) { return filefunctions_wd; } STATUS_CODE filefunctions::ls(std::string path_arg, std::queue &content, COMMAND_FLAGS flags) { std::string path; if(flags & CF_RELATIVE) { path = filefunctions_wd; if(path_arg.length()) path += path_arg; } else { path = path_arg; } DEBUG("__LS__ ls(" << path << ")"); DWORD attr = GetFileAttributes(path.c_str()); if(attr != FILE_ATTRIBUTE_DIRECTORY) return SC_IS_NOT_DIRECTORY; std::string path_joker = path + "\\*"; WIN32_FIND_DATA file_data; HANDLE status = FindFirstFile(path_joker.c_str(), &file_data); if(status == INVALID_HANDLE_VALUE) return SC_OTHER_FAILIURE; do { File_Struct temp; temp.path = path + "\\" + file_data.cFileName; if (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { DEBUG("__LS__ Found directory!"); DEBUG("__LS__ Directory: \"" << temp.path << "\""); if(flags&CF_RECURSIVE) { if(strcmp(file_data.cFileName, ".")==0 || strcmp(file_data.cFileName, "..")==0) { DEBUG("__LS__ Ignoring directory . or .."); } else { DEBUG("__LS__ Which is not . or ..\nGoing in!\n"); ls(temp.path, content, CF_RECURSIVE); } } else { DEBUG("__LS__ Ignoring directory, not recursive"); } } else { DEBUG("__LS__ Found file!"); DEBUG("__LS__ File: \"" << temp.path << "\""); time_t unix_time = filetime_to_unixtime(file_data.ftLastWriteTime); DEBUG("__LS__ Modified time: " << std::dec << unix_time); temp.modified = new tm; memcpy(temp.modified, localtime(&unix_time), sizeof(tm)); temp.file_ending = temp.path.substr(temp.path.find_last_of('.')+1); std::transform(temp.file_ending.begin(), temp.file_ending.end(), temp.file_ending.begin(), ::tolower); DEBUG("__LS__ File ending: " << temp.file_ending); if(temp.file_ending == "jpeg" || temp.file_ending == "jpg") { DEBUG("__LS__ Found JPEG-file, decoding EXIF"); temp.taken = get_exif_time(temp.path); } content.push(temp); } DEBUG("__LS__ Checking for other files\n"); } while (FindNextFile(status, &file_data) != 0); DEBUG("__LS__ Finnished ls()\n\n"); return SC_SUCCESS; } #else // Fail? Hård fail som fan! #endif // __linux__