From 70a7735d85a06fa6df7f4a66695a1b7fccda0c0e Mon Sep 17 00:00:00 2001 From: pavlik_dev <121434853+pavliktt@users.noreply.github.com> Date: Tue, 20 Aug 2024 19:51:21 +0200 Subject: [PATCH] Add files via upload --- main.cpp | 355 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 main.cpp diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..e70f337 --- /dev/null +++ b/main.cpp @@ -0,0 +1,355 @@ +/* + The original of this program belongs to pavlik_tt! + Please, if you are going to modify this code in any way, do one of these things: + * Create a fork on GitHub where you post the source code of this program. + * Leave this comment, but under the line #2 leave your name as the author of the fork. + If you take large blocks of code from here, please provide attribution in a comment above it. + + I don’t force you to do these things, but it will be more pleasant for me. +*/ + +/* + Some notes: + 1. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE 1024 + +enum FileType { + Unknown, + File, Folder, + + Archive, Audio, + Application, + Video, Binary, + Text +}; + +std::vector get_files_in_directory(const std::string& path) +{ + DIR* dp = opendir(path.c_str()); + // int normal, hidden; + int normal[2] = {0,0}; + int hidden[2] = {0,0}; + if (dp != nullptr) { + struct dirent* ep; + while((ep = readdir(dp))) { + // if (ep->d_name[0] != '.') i++; + if (strcmp(ep->d_name, ".") != 0 && strcmp(ep->d_name, "..") != 0) { + if (ep->d_name[0] == '.') { + hidden[(ep->d_type == DT_DIR) ? 1 : 0]++; + }else { + normal[(ep->d_type == DT_DIR) ? 1 : 0]++; + } + } + } + + (void)closedir(dp); + } + else + perror("Couldn't open the directory"); + std::vector result; + result.insert(result.end(), normal[0]); + result.insert(result.end(), normal[1]); + result.insert(result.end(), hidden[0]); + result.insert(result.end(), hidden[1]); + return result; +} + +bool starts_with(const std::string& prefix, const std::string& string) { + return string.rfind(prefix, 0) == 0; +} + +bool is_archive(const std::string& mime_type) +{ + const std::string archives[] = { + "application/x-archive", + "application/x-cpio", + "application/x-shar", + "application/x-iso9660-image", + "application/x-sbx", + "application/x-tar", + "application/x-brotli", + "application/x-bzip2", + "application/vnd.genozip", + "application/gzip", + "application/x-lzip", + "application/x-lzma", + "application/x-lzop", + "application/x-snappy-framed", + "application/x-xz", + "application/x-compress", + "application/x-compress", + "application/zstd", + "application/x-7z-compressed", + "application/x-ace-compressed", + "application/x-astrotite-afa", + "application/x-alz-compressed", + "application/vnd.android.package-archive", + "application/x-freearc", + "application/x-arj", + "application/x-b1", + "application/vnd.ms-cab-compressed", + "application/x-cfs-compressed", + "application/x-dar", + "application/x-dgc-compressed", + "application/x-apple-diskimage", + "application/x-gca-compressed", + "application/java-archive", + "application/x-lzh", + "application/x-lzx", + "application/x-rar-compressed", + "application/x-stuffit", + "application/x-stuffitx", + "application/x-gtar", + "application/x-ms-wim", + "application/x-xar", + "application/zip", + "application/x-zoo" + }; + int len = sizeof(archives)/sizeof(archives[0]); + + for(int i = 0; i < len; ++i) + { + if(starts_with(archives[i], mime_type)) + { + return true; + } + } + return false; +} + +std::string get_name_from_filetype(const enum FileType fs) +{ + switch (fs) { + case FileType::Application: + return "Application"; + case FileType::Archive: + return "Archive"; + case FileType::Audio: + return "Audio"; + case FileType::Binary: + return "Binary"; + case FileType::File: + return "File"; + case FileType::Folder: + return "Folder"; + case FileType::Text: + return "Text"; + case FileType::Video: + return "Video"; + default: + return "Unknown"; + } +} +std::string get_emoji_from_filetype(const enum FileType fs) +{ + switch (fs) { + case FileType::Application: + return "βš™οΈ"; + case FileType::Archive: + return "πŸ—œοΈ"; + case FileType::Audio: + return "🎡"; + case FileType::Binary: + return "βš™οΈ"; + case FileType::File: + return "πŸ“„"; + case FileType::Folder: + return "πŸ“"; + case FileType::Text: + return "πŸ“"; + case FileType::Video: + return "πŸŽ₯"; + default: + return "?"; + } +} + +std::string readable_fs(const long int size /*in bytes*/, const double divide_by = 1024, const std::string& suffix = "B") +{ + if(size < 1024) { + char buffer[128]; + sprintf(buffer, "%i B", static_cast(size)); + std::string result(buffer); + return buffer; + } + auto result = static_cast(size); + int i = 0; + const std::string units[] = {"", "K", "M", "G", "T", "P", "E", "Z", "Y"}; + while (result > divide_by) { + result /= divide_by; + i++; + } + char buffer[128]; + sprintf(buffer, "%.*f %s%s", i, result, units[i].c_str(), suffix.c_str()); + std::string str_result(buffer); + return str_result; +} + +std::string get_mime(const std::string& filename) +{ + const char* file_path = filename.c_str(); + const auto magic_cookie = static_cast(magic_open(MAGIC_MIME_TYPE)); + if (magic_cookie == nullptr) { + std::cerr << "Unable to initialize libmagic\n"; + return ""; + } + + // Load definitions from the mime types database + if (magic_load(magic_cookie, nullptr) != 0) { + std::cerr << "Unable to load database definitions\n"; + magic_close(magic_cookie); + return ""; + } + + // Determines the MIME type of the file + const char *mime_type = magic_file(magic_cookie, file_path); + if (mime_type == nullptr) { + std::cerr << "Unable to determine the MIME type of the file\n"; + magic_close(magic_cookie); + return ""; + } + + std::string result(mime_type); + + // Close libmagic + magic_close(magic_cookie); + + return result; +} + +std::string print_permissions(mode_t mode, bool is_dir) { + std::string user; + user += (mode & S_IRUSR) ? "r" : "-"; + user += (mode & S_IWUSR) ? "w" : "-", + user += (mode & S_IXUSR) ? "x" : "-"; + + std::string group; + group += (mode & S_IRGRP) ? "r" : "-"; + group += (mode & S_IWGRP) ? "w" : "-"; + group += (mode & S_IXGRP) ? "x" : "-"; + + std::string other; + other += (mode & S_IROTH) ? "r" : "-"; + other += (mode & S_IWOTH) ? "w" : "-"; + other += (mode & S_IXOTH) ? "x" : "-"; + + + return (is_dir ? "d" : "-") + user + group + other; +} + +std::string basename(const std::string& filepath) { + return filepath.substr(filepath.find_last_of("/\\") + 1); +} + +int main(int argc, char *argv[]) +{ + bool absolute = false; + bool emojis = true; + // char* filename = "/home/pavlik/Desktop/twrp-3.7.0_9-0-starlte.img"; + if (argc < 2) { + std::cerr << "Usage:\n\t" << argv[0] << " [args] filename ...\n"; + std::cerr << "Args:" << std::endl; + std::cerr << "\t-A Output absolute path" << std::endl; + std::cerr << "\t-E Do not show emojis" << std::endl; + return 255; + } + std::vector files; + for (int i = 1; i < argc; ++i) { + if (argv[i][0] != '-') { + std::string temp(argv[i]); + files.insert(files.end(), temp); + } else { + std::string arg(argv[i]); + if(arg == "-A") { + absolute = true; + } + if (arg == "-E") { + emojis = false; + } + } + } + + size_t last = files.size(); + for (size_t i = 0; i < last; ++i) { + const std::string& filename = files[i]; + char* c_filename = const_cast(filename.c_str()); + + struct stat file_stat = {}; + + if (stat(filename.c_str(), &file_stat) != 0) { + perror("stat"); + return 1; + } + // start + int is_file = S_ISREG(file_stat.st_mode); + char temp[4097] = {'\0'}; + if (realpath(c_filename, temp) == nullptr) { + perror("realpath"); + return 1; + } + std::string full_name(temp); // = malloc(4097); + // delete[] temp; + std::string name = basename(full_name); + if(!is_file) name += "/"; + std::string mime_type = get_mime(full_name); + FileType file; + if (starts_with("inode/directory", mime_type) || !is_file) { + file = FileType::Folder; + } else if (is_archive(mime_type)) { + file = FileType::Archive; + } else if (starts_with("application/octet-stream", mime_type)) { + file = FileType::Binary; + } else if (starts_with("application", mime_type)) { + file = FileType::Application; + } else if (starts_with("audio", mime_type)) { + file = FileType::Audio; + } else if (starts_with("video", mime_type)) { + file = FileType::Video; + } else if (starts_with("text", mime_type)) { + file = FileType::Text; + } else { + file = FileType::Unknown; + } + std::string type = get_name_from_filetype(file); + std::string emoji = get_emoji_from_filetype(file); + if (emojis) printf("%s ", emoji.c_str()); + printf("\033[1m%s\033[0m:\n", name.c_str()); + printf("\tName: %s\n", name.c_str()); + printf("\tType: %s\n", type.c_str()); + if (absolute) printf("\tAbsolute path: %s\n", full_name.c_str()); + printf("\tMIME: %s\n", mime_type.c_str()); // Default MIME type, adjust as needed + + if (is_file) { + std::string _1024 = readable_fs(file_stat.st_size, 1000, "B"); + std::string _1000 = readable_fs(file_stat.st_size, 1024, "iB"); + if (file_stat.st_size >= 1000) printf("\tFile size: %s or %s (%li bytes)\n", _1024.c_str(), _1000.c_str(), file_stat.st_size); + else printf("\tFile size: %li bytes\n", file_stat.st_size); + } else { + auto insides = get_files_in_directory(full_name); + printf("\tContents:\n"); + printf("\t\tNormal: %i files and %i folders.\n", insides[0], insides[1]); + printf("\t\tHidden: %i files and %i folders.\n", insides[2], insides[3]); + } + printf("\tPermissions: %s\n", print_permissions(file_stat.st_mode, !is_file).c_str()); + if (i != last-1) { + printf("\n"); + } + } + + return 0; +} +