/****************************************************************************
@File Name: statfs.h
@Author: wangzhicheng
@mail: 2363702560@qq.com
@Created Time: Tue 28 Feb 2017 05:15:08 PM CST
2017-03-01
****************************************************************************/
#ifndef STATFS_H
#define STATFS_H
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string>
#include <algorithm>
namespace statfs
{
using namespace std;
enum FILETYPE
{
ISDIR,
ISFIFO,
ISCHR, // character file
ISBLK, // block file
ISREG, // regular file
ISUNKNOWN // unknown
};
class Statfs
{
public:
/*
* @brief judge whether a process have permission to the file
* @path the full path of targeted file
* @perm the combination of rwx "r" -- read "w" -- write "x" -- execute
* such as "rx" "rxw" "wr" "rwx" and so on
* @return true if read is ok
* */
static bool Permit(const string &path, const string &perm);
/*
* @brief get the size of file
* */
static off_t FileSize(const string &path);
/*
* @brief get the size of dir
* */
static off_t DirSize(const string &path);
/*
* @brief get the type of file
* */
static FILETYPE FileType(const string &path);
};
}
#endif
/****************************************************************************
@File Name: statfs.cpp
@Author: wangzhicheng
@mail: 2363702560@qq.com
@Created Time: Tue 28 Feb 2017 05:15:08 PM CST
2017-03-01
****************************************************************************/
#include "statfs.h"
namespace statfs
{
bool Statfs::Permit(const string &path, const string &perm)
{
struct stat buf;
bool perms[3] = {0};
bool permits[3] = {0};
const static mode_t user_modes[3] = {S_IRUSR, S_IWUSR, S_IXUSR};
const static mode_t group_modes[3] = {S_IRGRP, S_IWGRP, S_IXGRP};
const static mode_t other_modes[3] = {S_IROTH, S_IWOTH, S_IXOTH};
if(perm.size() > 3 || perm.size() <= 0) return false;
if(stat(path.c_str(), &buf)) return false;
if(!getuid()) return true; // root
// get the permissions from the perm argument
for_each(begin(perm), end(perm), [&perms](char ch)
{
switch(ch)
{
case 'r':
case 'R':
if(!perms[0]) perms[0] = true;
break;
case 'w':
case 'W':
if(!perms[1]) perms[1] = true;
break;
case 'x':
case 'X':
if(!perms[2]) perms[2] = true;
break;
}
});
// check the buf and update permits
for(int i = 0;i < 3;i++)
{
if(!perms[i]) continue;
if(buf.st_uid == geteuid())
{
permits[i] = buf.st_mode & user_modes[i];
continue;
}
if(buf.st_gid == getegid())
{
permits[i] = buf.st_mode & group_modes[i];
continue;
}
permits[i] = buf.st_mode & S_IROTH;
}
// judge
for(int i = 0;i < 3;i++)
{
if(!perms[i]) continue;
if(!permits[i]) return false;
}
return true;
}
/*
* @brief get the size of file
* */
off_t Statfs::FileSize(const string &path)
{
struct stat buf;
if(stat(path.c_str(), &buf)) return -1;
return buf.st_size;
}
/*
* @brief get the type of file
* */
FILETYPE Statfs::FileType(const string &path)
{
struct stat buf;
if(stat(path.c_str(), &buf)) return ISUNKNOWN;
if(S_ISDIR(buf.st_mode)) return ISDIR;
if(S_ISREG(buf.st_mode)) return ISREG;
if(S_ISFIFO(buf.st_mode)) return ISFIFO;
if(S_ISCHR(buf.st_mode)) return ISCHR;
if(S_ISBLK(buf.st_mode)) return ISBLK;
return ISUNKNOWN;
}
/*
* @brief get the size of dir
* */
off_t Statfs::DirSize(const string &path)
{
off_t total = 0;
DIR *dp = nullptr;
struct dirent *dirp = nullptr;
string newpath;
static const string STR = "/";
if(!(dp = opendir(path.c_str())))
{
closedir(dp);
return 0;
}
while((dirp = readdir(dp)))
{
if(!strcmp(dirp->d_name, ".") || !strcmp(dirp->d_name, "..")) continue;
// generate a new path
newpath = path;
if('/' != newpath[newpath.size() - 1]) newpath += STR; // judge the last character
newpath += dirp->d_name;
// is directory
if(ISDIR == Statfs::FileType(newpath))
{
total += DirSize(newpath);
}
else
{
total += FileSize(newpath);
}
}
return total;
}
}
/****************************************************************************
@File Name: test.cpp
@Author: wangzhicheng
@mail: 2363702560@qq.com
@Created Time: Tue 28 Feb 2017 05:37:13 PM CST
2017-03-01
****************************************************************************/
#include "statfs.h"
#include <iostream>
using namespace statfs;
int main()
{
// setuid(1000);
// cout << Statfs::Permit("/var/log/TrendMicro/SProtectLinux/System.20170218.0001", "rxw") << endl;
// cout << Statfs::FileSize("/var/log/TrendMicro/SProtectLinux/System.20170218.0001") << endl;
// cout << Statfs::FileSize("/opt/TrendMicro/SProtectLinux/Product.ini") << endl;
// cout << Statfs::FileType("/opt") << endl;
cout << Statfs::DirSize("/opt") << endl;
return 0;
}
statfs
最新推荐文章于 2024-02-09 19:40:05 发布