ewmscp  ..
checkGpfsAcls.cpp
Go to the documentation of this file.
1 
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <unistd.h>
5 
6 #include <gpfs.h>
7 #include <string>
8 #include <forward_list>
9 #include <Options.h>
10 #include <throwcall.h>
11 #include <scoped.h>
12 #include "gpfsFcntlHandler.h"
13 
24 static unsigned long nDirs = 0;
25 static unsigned long nFiles = 0;
26 static options::single<size_t> maxGoodEntries('n',"maxGoodEntries",
27  "maximum number of aces in an acl considered good",14);
28 static options::single<size_t> minGoodEntries('m',"minGoodEntries",
29  "minimum number of aces in an acl considered good",0);
30 
31 static std::map<size_t,unsigned long> aclLength;
32 static std::map<size_t,unsigned long> multiples;
33 
34 
35 void checkAcl(const std::string& path) {
37  acl.get(-1, path);
38  unsigned duplicates(0);
39  aclLength[acl.size()]++;
40  gpfs_ace_v4_t nullAce = {0,0,0,0,0};
41 
42  for (auto ace1 = acl.begin(); ace1 != acl.end(); ++ace1) {
43  for (auto ace2 = ace1 + 1; ace2 != acl.end(); ++ace2) {
44  if (!(*ace1 == nullAce) && *ace1 == *ace2) {
45  *ace2=nullAce; // mark as already counted
46  duplicates++;
47  }
48  }
49  }
50  multiples[duplicates]++;
51  if (acl.size() > maxGoodEntries || acl.size() < minGoodEntries || duplicates > 0) {
52  std::cout << path << " " << acl.size() << " " << duplicates << "\n";
53  }
54 }
55 
56 void handleDir(const std::string& path) {
57  std::forward_list<std::string> subdirs;
58  {
59  scoped::Dir dir(path);
60  while (auto entry = readdir(dir)) {
61  if (entry->d_name[entry->d_name[0] != '.' ? 0 : entry->d_name[1] != '.' ? 1 : 2] == '\0') {
62  continue; // skip . .. and empty strings
63  }
64  if (entry->d_type == DT_DIR) {
65  subdirs.emplace_front(path + "/" + entry->d_name);
66  nDirs++;
67  } else if (entry->d_type == DT_REG) {
68  std::string filePath(path);
69  filePath += "/";
70  filePath += entry->d_name;
71  nFiles++;
72  checkAcl(filePath);
73  } else {
74  std::cerr << "ignoring '" << entry->d_name << "' in '" << path << "', it's neither dir nor file\n";
75  }
76  }
77  }
78  for (const auto& subdir : subdirs) {
79  checkAcl(subdir);
80  handleDir(subdir);
81  }
82 }
83 
84 
85 int main(int argc, const char *argv[]) {
86  options::parser parser(
87  "set the ACLs of the files given on the command line\n"
88  "\t to those they would inherit from theirparent directories.\n"
89  "\tDirectories given on the command line are left unchanged,\n"
90  "\t but all their content is recursively scanned and the ACLs\n"
91  "\t of all their sub-directories and files are set\n"
92  "\t as if freshly inherited.\n"
93  , "", {});
95  "files to be checked");
96  parser.fParse(argc, argv);
97  for (const auto& file : files) {
98  struct stat statbuf;
99  throwcall::good0(lstat(file.c_str(), &statbuf), "can't stat ", file);
100  if (S_ISDIR(statbuf.st_mode)) {
101  nDirs++;
102  checkAcl(file);
103  handleDir(file);
104  } else if (S_ISREG(statbuf.st_mode)) {
105  nFiles++;
106  checkAcl(file);
107  } else {
108  std::cerr << "ignoring '" << file << "', it's neither dir nor file\n";
109  }
110  }
111  std::cout << "processed " << nFiles << " files in " << nDirs << " directories\n";
112  for (const auto& item: aclLength) {
113  std::cout << "files with " << item.first << " aces in the acl: " << item.second << "\n";
114  }
115  for (const auto& item: multiples) {
116  std::cout << "files with " << item.first << " duplicates in the acl: " << item.second << "\n";
117  }
118  return 0;
119 }
options::parser
class that contains the parser, i.e. does that option handling
Definition: Options.h:363
options::single< size_t >
aclLength
static std::map< size_t, unsigned long > aclLength
Definition: checkGpfsAcls.cpp:31
scoped.h
checkAcl
void checkAcl(const std::string &path)
Definition: checkGpfsAcls.cpp:35
gpfs_acl_handler
class for handling non-opaque gpfs acls
Definition: gpfsFcntlHandler.h:33
Options.h
minGoodEntries
static options::single< size_t > minGoodEntries('m',"minGoodEntries", "minimum number of aces in an acl considered good", 0)
nDirs
static unsigned long nDirs
Definition: checkGpfsAcls.cpp:24
throwcall.h
multiples
static std::map< size_t, unsigned long > multiples
Definition: checkGpfsAcls.cpp:32
nFiles
static unsigned long nFiles
Definition: checkGpfsAcls.cpp:25
handleDir
void handleDir(const std::string &path)
Definition: checkGpfsAcls.cpp:56
gpfsFcntlHandler.h
main
int main(int argc, const char *argv[])
Definition: checkGpfsAcls.cpp:85
scoped::Dir
Definition: scoped.h:71
options::positional
Definition: Options.h:876
throwcall::good0
void good0(T call, const Args &... args)
template function to wrap system calls that return 0 on success
Definition: throwcall.h:40
maxGoodEntries
static options::single< size_t > maxGoodEntries('n',"maxGoodEntries", "maximum number of aces in an acl considered good", 14)
acl
Definition: acl.cpp:10