#include #include #include #include #include #include #include #include #include #include "rainbow.h" #include "rls.h" /////// DIRLIST DEFINITIONS /////// ENTLIST DIRLIST::all() { DIRENTS all; sorter(dirs, all); sorter(files, all); int len = all.size(); if (len < 10) len = 10; else if (len > 50) len = 50; prnt.r.init(len); return ENTLIST{all}; } int DIRLIST::charcomp(char a, char b) { if (a > 96) a-=32; if (b > 96) b-=32; if (b == a) return 2; return a>b; } int DIRLIST::strcomp(std::string a, std::string b) { int len = a.length(); if (b.length()= paths.size();} void PATHS::first() {i = 0;} void PATHS::validate() { if (size()==0) add("."); for (first();!end(); next()) { if (!std::filesystem::exists(path()) || !std::filesystem::is_directory(path())) { prnt(path().string()+" not valid; skipping."); } } first(); } DIRLIST PATHS::read() { DIRLIST list; for (const auto& entry : std::filesystem::directory_iterator(path())) { if (std::filesystem::is_directory(entry)) list.dirs.push_back(entry); else list.files.push_back(entry); } return list; } size_t PATHS::size() const {return paths.size();} std::string PATHS::str() { std::string p = path().string(); if (p[p.length()-1] != '/') p.append("/"); return p; } /////// FLAGS DEFINITIONS /////// void FLAGS::toggle(std::string arg) { if (arg == "nocolor" || arg == "c") color = false; else if (arg == "list" || arg == "l") list = true; else if (arg == "all" || arg == "a") all = true; else if (arg == "help" || arg == "h") help = true; else if (arg == "number" || arg == "n") number = true; else printf("Unknown flag: %s\n", arg.c_str()); } void FLAGS::parse(int argc, char* argv[]) { std::string arg; size_t len; int j; for (int i = 1; i < argc; i++) { arg = std::string(argv[i]); len = arg.length(); if (len >= 2 && arg.substr(0,2) == "--") toggle(arg.substr(2)); else if (len >= 1 && arg[0] == '-') for (j = 1; j < len; j++) toggle(arg.substr(j,1)); else paths.add(arg); } if (paths.size() == 0) paths.add("."); } /////// printer DEFINITIONS /////// void printer::operator()() {printf("\n");} void printer::operator()(std::string str) { if (flags.color) { r.print2d(str + "\n"); r.next(); } else printf("%s\n", str.c_str()); } /////// ENTLIST DEFINITIONS /////// void ENTLIST::print() { std::string outstr = ""; struct stat st; for (DIRENT e : list) { ST{e}; } } /////// ST DEFINITIONS /////// std::string ST::perms() { std::string permissions; permissions += (S_ISDIR(st.st_mode)) ? 'd' : '-'; permissions += (st.st_mode & S_IRUSR) ? 'r' : '-'; permissions += (st.st_mode & S_IWUSR) ? 'w' : '-'; permissions += (st.st_mode & S_IXUSR) ? 'x' : '-'; permissions += (st.st_mode & S_IRGRP) ? 'r' : '-'; permissions += (st.st_mode & S_IWGRP) ? 'w' : '-'; permissions += (st.st_mode & S_IXGRP) ? 'x' : '-'; permissions += (st.st_mode & S_IROTH) ? 'r' : '-'; permissions += (st.st_mode & S_IWOTH) ? 'w' : '-'; permissions += (st.st_mode & S_IXOTH) ? 'x' : '-'; return permissions; } std::string ST::owner() { struct passwd *pw = getpwuid(st.st_uid); if (pw == nullptr) { return "Unknown"; } return std::string(pw->pw_name); } std::string ST::size() { const char* suffix = "BKMGT"; D s = D(st.st_size); uint size = uint(log(s)/log(1024)); char b[50]; char d[50]; sprintf(b, "%.2lf", D(D(s) / D(pow(uint(1024), size)))); sprintf(d, "%6s %c", std::string(b).c_str(), suffix[size]); return std::string(b); } std::string ST::init(DIRENT e) { std::string outstr = ""; if (stat(e.path().c_str(), &st) != 0) return "err"; //error reading file if (flags.list) { outstr += perms() + " " + owner(); } outstr += size() + " " + e.path().filename().string(); return outstr; } ST::ST(DIRENT e) { prnt(init(e)); } /////// MAIN /////// void runHelp(std::string name) { prnt("Usage: "+name+" [OPTIONS] "); prnt("List content of PATH in rainbow."); prnt("Options:"); prnt(" -h, --help\t\tdisplay this help message"); prnt(" -c, --nocolor\t\tdisable color output"); prnt(" -l, --list\tmore info."); prnt(" -a, --all\tlist all files"); prnt(" -n, --number\tcount files"); exit(0); } std::string convsize(unsigned long n) { if (n == 0) return " 0.00 "; double f = n; char c[] = " KMGT"; unsigned long i = 0; for (; f > 999; i++) f /= 1000; if (i > 4) return " >1.00 P "; n = 100 * f; std::string s = ""; for (; n > 0; n /= 10) s = std::to_string(n % 10) + s; for (; s.length() < 5; s = " " + s); return s.substr(0, 3) + "." + s.substr(3, 2) + " " + c[i] + " "; } int main(int argc, char* argv[]) { flags.parse(argc, argv); if (flags.help) runHelp(argv[0]); for (paths.first(); !paths.end(); paths.next()) { prnt(paths.str()); ENTLIST list = ENTLIST{paths.read().all()}; list.print(); prnt(); } return 0; }