Created
June 2, 2013 20:41
-
-
Save boo1ean/5694893 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <dirent.h> | |
#include <sys/stat.h> | |
#include <iostream> | |
#include <vector> | |
#include <string> | |
#include <algorithm> | |
#include <sstream> | |
using namespace std; | |
#define REQUIRED_ARGS_NUMBER 1 + 1 | |
class File | |
{ | |
enum | |
{ | |
ACCESS_ERROR = -1 | |
}; | |
vector<string> &split(const string &s, char delim, vector<string> &elems) { | |
stringstream ss(s); | |
string item; | |
while (getline(ss, item, delim)) { | |
elems.push_back(item); | |
} | |
return elems; | |
} | |
vector<string> split(const string &s, char delim) { | |
vector<string> elems; | |
split(s, delim, elems); | |
return elems; | |
} | |
protected: | |
string path; | |
public: | |
enum | |
{ | |
PATH_SEPARATOR = '/' | |
}; | |
class NotExistException : exception | |
{ | |
virtual const char * what() const throw() | |
{ | |
return "Node doesn't exist."; | |
} | |
}; | |
static bool exists(string path) | |
{ | |
return ACCESS_ERROR != access(path.c_str(), F_OK); | |
} | |
static bool isDir(string path) | |
{ | |
struct stat stat = File::stat(path); | |
return S_IFDIR & stat.st_mode; | |
} | |
static struct stat stat(string path) | |
{ | |
struct stat stat; | |
::stat(path.c_str(), &stat); | |
return stat; | |
} | |
File(string path) : path(path) | |
{ | |
// Throw exception if file doesn't exist | |
if (!File::exists(path)) { | |
throw NotExistException(); | |
} | |
} | |
// Get file stats | |
struct stat stat() const | |
{ | |
return File::stat(path); | |
} | |
// Get filename | |
string name() | |
{ | |
return split(path, PATH_SEPARATOR).back(); | |
} | |
// Get number of hard links | |
nlink_t hardLinksCount() const | |
{ | |
return stat().st_nlink; | |
} | |
bool operator>(const File &other) const | |
{ | |
return hardLinksCount() > other.hardLinksCount(); | |
} | |
}; | |
class Dir : File | |
{ | |
public: | |
typedef vector<File> List; | |
class InvalidNodeTypeException : exception | |
{ | |
virtual const char * what() const throw() | |
{ | |
return "Specified object is not a directory."; | |
} | |
}; | |
Dir(string path) : File(path) | |
{ | |
if (!File::isDir(path)) { | |
throw InvalidNodeTypeException(); | |
} | |
} | |
// Get list of filenames | |
List files() | |
{ | |
List listing; | |
struct dirent * de = NULL; | |
DIR * dir = opendir(path.c_str()); | |
while (de = readdir(dir)) | |
{ | |
try { | |
listing.push_back(File(path + de->d_name)); | |
} catch (NotExistException e) { | |
cout << "Something went wrong." << endl; | |
exit(EXIT_FAILURE); | |
} | |
} | |
closedir(dir); | |
return listing; | |
} | |
}; | |
void usage() | |
{ | |
cout << "Usage:" << endl; | |
cout << "ls_sort path/to/target/dir" << endl; | |
} | |
void slashify(string &target) | |
{ | |
if (File::PATH_SEPARATOR != target.at(target.size() - 1)) { | |
target += File::PATH_SEPARATOR; | |
} | |
} | |
bool comparator(const File &a, const File &b) { | |
return a > b; | |
} | |
int main(int argc, char * argv[]) { | |
if (REQUIRED_ARGS_NUMBER != argc) { | |
usage(); | |
return EXIT_FAILURE; | |
} | |
string target_dir = argv[1]; | |
slashify(target_dir); | |
Dir * dir; | |
try { | |
dir = new Dir(target_dir); | |
} catch (File::NotExistException e) { | |
cout << "Directory doesn't exist: \"" << target_dir << "\"" << endl; | |
return EXIT_FAILURE; | |
} catch (Dir::InvalidNodeTypeException e) { | |
cout << "Specified source node is not a directory: \"" << target_dir << "\"" << endl; | |
return EXIT_FAILURE; | |
} | |
cout << "Source dir: \"" << target_dir << "\"" << endl; | |
Dir::List files = dir->files(); | |
sort(files.begin(), files.end(), comparator); | |
for (int i = 0; i < files.size(); ++i) { | |
cout << files.at(i).hardLinksCount() << " - " << files.at(i).name() << endl; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment