Folder size linux - c++

I need to monitor folders on my linux machine periodically to check whether they are exceeding certain limits.
I have checked stat function call but running stat recursively on all sub folders and files is time consuming and I need to do this for all folders.
Does kernal maintain any datastructures which I can interpret in my program.Or is their any standard api for this.

If you need to enforce limits then use quotas

In case the quota mechanism isn't suitible, then
inotify might be handy:
From wikipedia:
inotify is a Linux kernel subsystem
that acts to extend filesystems to
notice changes to the filesystem, and
report those changes to applications.report those changes to applications.

Type
du -sm directory_name
Will give you the total size of the directory in megabytes recursively.
Type
man du
for help with this command.

You want quotactl:
quotactl -- manipulate filesystem quotas
SYNOPSIS
#include <sys/types.h> /* types needed by quota.h */
#include <sys/quota.h> /* for disk quotas */

Calling stat recursively is the only way to get the current folder size. If you want to continuously monitor the file system, take a look at inotify.

I agree with #Axel. However if you really need to do this in code, you could execute the du shell command via popen:
FILE* pf = popen("du -ch [your folder] | grep total")
Then read the output from the command via the file handle and fgets(...)

Use command du, check this link ...
"How To Check Folder Size"

Related

Mounting ecryptfs using C++ mount function

I am trying to mount ecryptfs from within a C++ program. I can definitely mount it without it asking questions by issuing this command at the prompt:
sudo mount -t ecryptfs -o "rw,key=passphrase:passphrase_passwd=geoff,ecryptfs_cipher=aes,ecryptfs_key_bytes=32,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=n,no_sig_cache" ~/source/ ~/target/
Note that in reality, I am passing a full canonical path in case that matters.
But from within the program I get failure with errno=EINVAL after trying by using the mount() function with the same arguments:
mount("~/source/", "~/target/", "ecryptfs", MS_NODEV, "rw,key=passphrase:passphrase_passwd=geoff,ecryptfs_cipher=aes,ecryptfs_key_bytes=32,ecryptfs_passthrough=n,ecryptfs_enable_filename_crypto=n,no_sig_cache")
The program does launch with root privileges and I have checked that I have CAP_SYS_ADMIN.
The mount() function returns -1 and sets errno to EINVAL.
Have I got the arguments correct? Is this maybe a privileges issue?
EDIT: I got it to work by executing mount externally via system(), but would still like to use the function because of reasons.
I believe this is because mount -t ecryptfs is actually calling the helper executable mount.ecryptfs, and it's processing some of the options (in particular, key=) itself. What's actually passed to the kernel is different (you can see this by looking at /proc/mounts afterward).
If you look closely at https://manpages.ubuntu.com/manpages/kinetic/en/man7/ecryptfs.7.html, key= and ecryptfs_enable_filename_crypto= are listed under "MOUNT HELPER OPTIONS" - the actual kernel module's options are ecryptfs_sig=(fekek_sig) and ecryptfs_fnek_sig=(fnek_sig).
So, if you want to bypass the helper and do the mount directly, you'd need to load the tokens into the kernel's keyring with https://man7.org/linux/man-pages/man2/keyctl.2.html and replace key= with the resulting token signatures, like mount.ecryptfs did.
It does appear that there is a libecrytpfs with functions in ecryptfs.h like ecryptfs_add_passphrase_key_to_keyring which you can (presumably, not tested) use to do this in a way matching the mount.ecryptfs

C Program: Get inode header fields and information by inode number

I need to write a program in C/C++ that request the user to put in an inode number and then return all of the inode header fields and information back. I am not familiar with linux systems and commands at all. I have found some commands and tried different things that didnt work like I needed.
find -inum inodenumber
will give me the path to the file that contains the specified number. All the information I need comes from istat (according to my research) but I cant get it to work. Im doing
istat FILENAME.jpg
I get the response:
Missing image name and/or address
usage: istat[-B num] [-f fstype] [-i ingtype] [-b dev_sector_size] [-o imgoffset] [-z zone] [-s seconds] [ivV] image inum ...
What do I need to do?
istat only works on disk images, not live filesystems.
There are no system calls in Linux which can look a file up in a live filesystem by its inode number.
Run man istat of course.
In general, you can always get help from the terminal itself by running man.
Try running find with the inode number and then use the filename it generates with stat.

Mount NTFS device in C++ on linux?

I'm attempting to mount an external drive in my C++ application. I originally tried to use mount(2) but this fails:
int ret = mount(deviceName.c_str(), mountPoint.c_str(), fsType.c_str(), 0, NULL);
errno is 19, ENODEV (filesystem type not configured in kernel)
However, if I switch to using mount(8) it works fine:
std::string cmd = "mount -t " + fsType + " " + deviceName + " " + mountPoint;
int ret = system(cmd.c_str());
Does mount(2) have a different list of acceptable filesystem types? This is an ntfs device, so I was using ntfs-3g as the fstype. I checked /proc/filesystems and saw that this was not listed, so I tried fuseblk but that just changes the error to 22, EINVAL.
What is the correct way to mount NTFS devices using mount(2)?
mount.2 is just a kernel call. mount.8 is a complete external tool which is extended beyond what kernel does.
I think you may be looking for libmount which is a library implementing the whole mounting magic done by mount.8. Newer mount versions use it as well. It's provided in util-linux.
Have you tried running mount(8) using the strace command? It will print out the system calls made by the program, including mount(2). When I do such a mount, it spawns mount.ntfs (which is NTFS-3g) which then does a mount for fuseblk and then spins off into the background to support that mount point.
FUSE-based filesystems are handled differently because the user-space daemon must be started. Mounting with fuseblk doesn't provide enough information for the kernel to start the daemon (and the kernel doesn't even really have the information to start the daemon). For ntfs-3g, one would normally do something like ntfs-3g /dev/sda1 /mnt/windows (from the help). There isn't a programmatic way to tell the kernel to do this because it happens in user-space.

how to JUDGE other program's result via cpp?

I've got a series of cpp source file and I want to write another program to JUDGE if they can run correctly (give input and compare their output with standart output) . so how to:
call/spawn another program, and give a file to be its standard input
limit the time and memory of the child process (maybe setrlimit thing? is there any examples?)
donot let the process to read/write any file
use a file to be its standard output
compare the output with the standard output.
I think the 2nd and 3rd are the core part of this prob. Is there any way to do this?
ps. system is Linux
To do this right, you probably want to spawn the child program with fork, not system.
This allows you to do a few things. First of all, you can set up some pipes to the parent process so the parent can supply the input to the child, and capture the output from the child to compare to the expected result.
Second, it will let you call seteuid (or one of its close relatives like setreuid) to set the child process to run under a (very) limited user account, to prevent it from writing to files. When fork returns in the parent, you'll want to call setrlimit to limit the child's CPU usage.
Just to be clear: rather than directing the child's output to a file, then comparing that to the expected output, I'd capture the child's output directly via a pipe to the parent. From there the parent can write the data to a file if desired, but can also compare the output directly to what's expected, without going through a file.
std::string command = "/bin/local/app < my_input.txt > my_output_file.txt 2> my_error_file.txt";
int rv = std::system( command.c_str() );
1) The system function from the STL allows you to execute a program (basically as if invoked from a shell). Note that this approach is inherenly insecure, so only use it in a trusted environment.
2) You will need to use threads to be able to achieve this. There are a number of thread libraries available for C++, but I cannot give you recommendation.
[After edit in OP's post]
3) This one is harder. You either have to write a wrapper that monitors read/write access to files or do some Linux/Unix privilege magic to prevent it from accessing files.
4) You can redirect the output of a program (that it thinks goes to the standard output) by adding > outFile.txt after the way you would normally invoke the program (see 1)) -- e.g. otherapp > out.txt
5) You could run diff on the saved file (from 3)) to the "golden standard"/expected output captured in another file. Or use some other method that better fits your need (for example you don't care about certain formatting as long as the "content" is there). -- This part is really dependent on your needs. diff does a basic comparing job well.

Win32 C/C++ checking if two instances of the same program use the same arguments

I have an application and I want to be able to check if (for instance) two instances of it used the same arguments on execution. To make it clearer:
myapp 1 2
myapp 1 3
This isn't a Singleton design pattern problem as I can have more than one instance running. I though about checking the running processes, but it seems that I can only get the process name and that doesn't help me.
Writing a file on startup and then having other instances check if that file exists isn't viable due to abnormal program termination which would leave me hanging.
In Linux I solved this by checking /proc/pid/cmdline and parsing the information there.
Does anyone have any idea if I can do something similar on windows?
Cheers
You can do this via WMI's Win32_Process class.
You want wmic.exe. Try something like:
wmic.exe process list | findstr myapp.exe
Then sort it / parse it / whatever you need to do.
wmic is really a great tool to have.
I ended up using this script instead of filling up my code with WMI calls:
wmic process where "name='cmd.exe'" get CommandLine > list.txt
works great!
cheers and thanks you Seth and Reed
After some thinking I decided to do things a bit simpler...
Implementing a mutex and checking it's existence is. As I needed to check if the instances started with the same parameters and not if the same application was started, I just needed to decide on the mutex name in runtime!
so...
sprintf(cmdstr,"myapp_%i_%i",arg1,arg2);
DWORD m_dwLastError;
m_hMutex = CreateMutex(NULL, FALSE, cmdstr);
m_dwLastError = GetLastError();
if(ERROR_ALREADY_EXISTS == m_dwLastError)
{
found_other = true;
}
and that's it! no parsing, no wmi, no windows development sdk...
Cheers to you all!