#include "filesystem.h" #include "defines.h" Filesystem::Directory::Directory(std::string PathName, std::string BasePath) { MyBase = BasePath; if (PathName[0] == '/') { PathName.erase(0, 1); } if (BasePath[BasePath.size() - 1] != '/') { BasePath += "/"; } MyPath = PathName; FillEntries(); } Filesystem::Directory::~Directory() { } void Filesystem::Directory::FillEntries() { ValidDir = true; struct stat StatBuf; Entries.clear(); DIR * Dirp = opendir((MyBase + MyPath).c_str()); if (!Dirp) { ValidDir = false; } else { dirent * entry; while ((entry = readdir(Dirp))) { if (stat((MyBase + MyPath + "/" + entry->d_name).c_str(), &StatBuf) == -1) { DEBUG_MSG(DLVL_DEVEL, "Skipping %s, reason %s", entry->d_name, strerror(errno)); continue; } ///Convert stat to string Entries[std::string(entry->d_name)] = StatBuf; } } } void Filesystem::Directory::Print() { /// \todo Remove? Libraries shouldn't print stuff. if (!ValidDir) { DEBUG_MSG(DLVL_ERROR, "%s is not a valid directory", (MyBase + MyPath).c_str()); return; } printf("%s:\n", (MyBase + MyPath).c_str()); for (std::map::iterator it = Entries.begin(); it != Entries.end(); it++) { printf("\t%s\n", (*it).first.c_str()); } printf("\n"); } bool Filesystem::Directory::IsDir() { return ValidDir; } std::string Filesystem::Directory::PWD() { return "/" + MyPath; } std::string Filesystem::Directory::LIST(std::vector ActiveStreams) { FillEntries(); int MyPermissions; std::stringstream Converter; passwd * pwd; //For Username group * grp; //For Groupname tm * tm; //For time localisation char datestring[256]; //For time localisation std::string MyLoc = MyBase + MyPath; if (MyLoc[MyLoc.size() - 1] != '/') { MyLoc += "/"; } for (std::map::iterator it = Entries.begin(); it != Entries.end(); it++) { bool Active = (std::find(ActiveStreams.begin(), ActiveStreams.end(), (*it).first) != ActiveStreams.end()); if ((Active && (MyVisible[MyPath] & S_ACTIVE)) || ((!Active) && (MyVisible[MyPath] & S_INACTIVE)) || (((*it).second.st_mode / 010000) == 4)) { if (((*it).second.st_mode / 010000) == 4) { Converter << 'd'; } else { Converter << '-'; } MyPermissions = (((*it).second.st_mode % 010000) / 0100); if (MyPermissions & 4) { Converter << 'r'; } else { Converter << '-'; } if (MyPermissions & 2) { Converter << 'w'; } else { Converter << '-'; } if (MyPermissions & 1) { Converter << 'x'; } else { Converter << '-'; } MyPermissions = (((*it).second.st_mode % 0100) / 010); if (MyPermissions & 4) { Converter << 'r'; } else { Converter << '-'; } if (MyPermissions & 2) { Converter << 'w'; } else { Converter << '-'; } if (MyPermissions & 1) { Converter << 'x'; } else { Converter << '-'; } MyPermissions = ((*it).second.st_mode % 010); if (MyPermissions & 4) { Converter << 'r'; } else { Converter << '-'; } if (MyPermissions & 2) { Converter << 'w'; } else { Converter << '-'; } if (MyPermissions & 1) { Converter << 'x'; } else { Converter << '-'; } Converter << ' '; Converter << (*it).second.st_nlink; Converter << ' '; if ((pwd = getpwuid((*it).second.st_uid))) { Converter << pwd->pw_name; } else { Converter << (*it).second.st_uid; } Converter << ' '; if ((grp = getgrgid((*it).second.st_gid))) { Converter << grp->gr_name; } else { Converter << (*it).second.st_gid; } Converter << ' '; Converter << (*it).second.st_size; Converter << ' '; tm = localtime(&((*it).second.st_mtime)); strftime(datestring, sizeof(datestring), "%b %d %H:%M", tm); Converter << datestring; Converter << ' '; Converter << (*it).first; Converter << '\n'; } } return Converter.str(); } bool Filesystem::Directory::CWD(std::string Path) { if (Path[0] == '/') { Path.erase(0, 1); MyPath = Path; } else { if (MyPath != "") { MyPath += "/"; } MyPath += Path; } FillEntries(); printf("New Path: %s\n", MyPath.c_str()); if (MyPermissions.find(MyPath) != MyPermissions.end()) { printf("\tPermissions: %d\n", MyPermissions[MyPath]); } return SimplifyPath(); } bool Filesystem::Directory::CDUP() { return CWD(".."); } std::string Filesystem::Directory::RETR(std::string Path) { std::string Result; std::string FileName; if (Path[0] == '/') { Path.erase(0, 1); FileName = MyBase + Path; } else { FileName = MyBase + MyPath + "/" + Path; } std::ifstream File; File.open(FileName.c_str()); while (File.good()) { Result += File.get(); } File.close(); return Result; } void Filesystem::Directory::STOR(std::string Path, std::string Data) { if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_STOR)) { std::string FileName; if (Path[0] == '/') { Path.erase(0, 1); FileName = MyBase + Path; } else { FileName = MyBase + MyPath + "/" + Path; } std::ofstream File; File.open(FileName.c_str()); File << Data; File.close(); } } bool Filesystem::Directory::SimplifyPath() { MyPath += "/"; std::vector TempPath; std::string TempString; for (std::string::iterator it = MyPath.begin(); it != MyPath.end(); it++) { if ((*it) == '/') { if (TempString == "..") { if (!TempPath.size()) { return false; } TempPath.erase((TempPath.end() - 1)); } else if (TempString != "." && TempString != "") { TempPath.push_back(TempString); } TempString = ""; } else { TempString += (*it); } } MyPath = ""; for (std::vector::iterator it = TempPath.begin(); it != TempPath.end(); it++) { MyPath += (*it); if (it != (TempPath.end() - 1)) { MyPath += "/"; } } if (MyVisible.find(MyPath) == MyVisible.end()) { MyVisible[MyPath] = S_ALL; } return true; } bool Filesystem::Directory::DELE(std::string Path) { if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_DELE)) { std::string FileName; if (Path[0] == '/') { Path.erase(0, 1); FileName = MyBase + Path; } else { FileName = MyBase + MyPath + "/" + Path; } if (std::remove(FileName.c_str())) { DEBUG_MSG(DLVL_ERROR, "Removing file %s failed", FileName.c_str()); return false; } return true; } return false; } bool Filesystem::Directory::MKD(std::string Path) { std::string FileName; if (Path[0] == '/') { Path.erase(0, 1); FileName = MyBase + Path; } else { FileName = MyBase + MyPath + "/" + Path; } if (mkdir(FileName.c_str(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) { DEBUG_MSG(DLVL_ERROR, "Creating directory %s failed", FileName.c_str()); return false; } MyVisible[FileName] = S_ALL; return true; } bool Filesystem::Directory::Rename(std::string From, std::string To) { if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & P_RNFT)) { std::string FileFrom; if (From[0] == '/') { From.erase(0, 1); FileFrom = MyBase + From; } else { FileFrom = MyBase + MyPath + "/" + From; } std::string FileTo; if (To[0] == '/') { FileTo = MyBase + To; } else { FileTo = MyBase + MyPath + "/" + To; } if (std::rename(FileFrom.c_str(), FileTo.c_str())) { DEBUG_MSG(DLVL_ERROR, "Renaming %s to %s failed", FileFrom.c_str(), FileTo.c_str()); return false; } return true; } return false; } void Filesystem::Directory::SetPermissions(std::string Path, char Permissions) { MyPermissions[Path] = Permissions; } bool Filesystem::Directory::HasPermission(char Permission) { if (MyPermissions.find(MyPath) == MyPermissions.end() || (MyPermissions[MyPath] & Permission)) { return true; } return false; } void Filesystem::Directory::SetVisibility(std::string Pathname, char Visible) { MyVisible[Pathname] = Visible; }