Skip to content

Instantly share code, notes, and snippets.

@boo1ean
Created June 2, 2013 20:41
Show Gist options
  • Save boo1ean/5694893 to your computer and use it in GitHub Desktop.
Save boo1ean/5694893 to your computer and use it in GitHub Desktop.
#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