Checking user permissions in C++ - c++

I have some code to create a directory using the sys/stat.h header. However, when trying to create a directory that the user does not have the correct permissions for (such as a non-root user creating a folder in /), no error is thrown, and no output is given, even though the folder is not created. Is there a way to check if a user has the correct permissions before creating a directory? My code is below.
//Defines the mkdir command
#include <iostream>
#include <string>
#include <sys/stat.h>
//C headers
#include <cerrno>
#include <cstring>
#include <cstdio>
//Custom headers
#include "string_algorithms.hpp"
#include "chdir.hpp"
//Defines current working directory
#define GetCurrentDir getcwd
using namespace std;
void mkdirFunc(string path)
{
try
{
//Find how many directories need to be created
vector<string> numberOfDirectories = strSplitter(path, "\\");
int count=0;
char cCurrentPath[FILENAME_MAX];
if (!GetCurrentDir(cCurrentPath, sizeof(cCurrentPath)))
{
printf("ERROR: %s\n", strerror(errno));
}
for(int i=0; i<numberOfDirectories.size(); i++)
{
mkdir(string(numberOfDirectories[i]).c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
chdirFunc(string(numberOfDirectories[i]));
}
chdirFunc(cCurrentPath);
}
catch(int e)
{
printf("ERROR: %s\n", strerror(errno));
}
}

Related

unable to write /proc/sys/kernel/ns_last_pid file

I want to edit the ns_last_pid file present in /proc/sys/kernel, but i'm getting the error of Read-only file system. How to resolve this?
This is what i've written to open the file.
int fd = open("/proc/sys/kernel/ns_last_pid", O_RDWR | O_CREAT, 0644);
if (fd < 0) {
cout<<strerror(errno)<<"\n";
return 1;
}
I've to write this file, change it's value. This file contains a single number represnting the last pid allocated to any process. I've to edit this so that i can get desired pid number for a process. like these guys are doing for their project CRIU(see first link).
Pid_restore(criu.org),
How to set process ID in Linux for a specific program(stackoverflow answer)
EDIT 1: Smallest reproducible example
#include <fstream>
#include <bits/stdc++.h>
#include <sys/types.h>
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sched.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/syscall.h>
using namespace std;
int main(){
printf("Opening ns_last_pid...\n");
int fd = open("/proc/sys/kernel/ns_last_pid", O_RDWR | O_CREAT, 0644);
if (fd < 0) {
cout<<strerror(errno)<<"\n";
return 1;
}
printf("Locking ns_last_pid...\n");
if (flock(fd, LOCK_EX)) {
close(fd);
printf("Can't lock ns_last_pid\n");
return 1;
}
printf("Done\n");
char buf[100];
int pid_max = 30000;
snprintf(buf, sizeof(buf), "%d", pid_max-1);
printf("Writing pid-1 to ns_last_pid...\n");
cout<<fd<<"\n";
if (write(fd, buf, strlen(buf)) != strlen(buf)) {
cout<<strerror(errno)<<"\n";
printf("Can't write to buf\n");
return 1;
}
printf("Done\n");
printf("Cleaning up...");
if (flock(fd, LOCK_UN)) {
printf("Can't unlock");
}
close(fd);
printf("Done\n");
return 0;
}
For a program to change kernel files, it should be owned by root
sudo chown root program // program is the executable(the binary)
set the setuid bit on the executable to execute a program with superuser access.
with this it will run as root even if we execute it as any user on our machine.
sudo chmod u+s program
Compile the source code and run the program with sudo to prevent other permission access errors.
Thanks to TedLyngmo for suggesting this solution.

Reading all file names in a directory

I am trying to read all file names present in a particular directory. I have made a program in C++ but this only prints the files directly in this directory. I want all the files which are also present in the subdirectory.
I have written a program in c++ which prints the file names in a directory but I want all file names in subdirectory also.
#include <stdio.h>
#include <windows.h>
#include <bits/stdc++.h>
#include <dirent.h>
using namespace std;
#include <sys/types.h>
#include <sys/stat.h>
#ifndef WIN32
#include <unistd.h>
#endif
#ifdef WIN32
#define stat _stat
#endif
int main ()
{
DIR *dir;
struct dirent *ent;
if ((dir = opendir ("c:\\test")) != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL) {
printf ("%s\n", ent->d_name);
}
closedir (dir);
} else {
/* could not open directory */
perror ("");
return EXIT_FAILURE;
}
}
Actual result:1.Printing file names which are directly in the directory and printing the subdirectory name.
Expected: I want instead of printing subdirectory name the program should print the names of files in that subdirectory.
If you have C++17 available, use recursive_directory_iterator. If not, you could use dirent.h-functions. Consider, for example, the following generic traverseFiles-function, which passes each file found then to a function that handles the file detected:
#include <iostream>
#include <dirent.h>
#include <string>
void traverseFiles(const std::string &path, std::function<void(const std::string &)> cb) {
if (auto dir = opendir(path.c_str())) {
while (auto f = readdir(dir)) {
if (f->d_name[0] == '.') continue;
if (f->d_type == DT_DIR)
traverseFiles(path + f->d_name + "/", cb);
if (f->d_type == DT_REG)
cb(path + f->d_name);
}
closedir(dir);
}
}
void fileDetected(const std::string &f) {
std::cout << "file:" << f << std::endl;
}
int main() {
traverseFiles("c:/somestartdir", &fileDetected);
}
Using C++17 recursive_directory_iterator:
#include <filesystem>
void ls_recursive(const std::filesystem::path& path) {
for(const auto& p: std::filesystem::recursive_directory_iterator(path)) {
std::cout << p.path() << '\n';
}
}
If you are using windows OS then you can run below code to get a list of files in the provided directory.
#include <windows.h>
#include <TCHAR.h>
#include <stdio.h>
void Enum(TCHAR root[0xFF])
{
HANDLE hFind;
WIN32_FIND_DATA wfd;
TCHAR GeneralPath[0xFF];
TCHAR AgainFolder[0xFF];
TCHAR FileFullPath[0xFF];
_stprintf(GeneralPath, _T("%s\\*.*"), root);
hFind = FindFirstFile(GeneralPath, &wfd);
if(INVALID_HANDLE_VALUE==hFind)
return;
do
{
if( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) //Checking Founded File Attribute is it File or Folder/Directory
{
if( !_tcscmp(wfd.cFileName, _T(".")) || !_tcscmp(wfd.cFileName, _T("..")) ) //if Founded directory is same(.) or parent(..) then ignore them
continue;
_stprintf(AgainFolder, _T("%s\\%s"), root, wfd.cFileName);
Enum(AgainFolder); //Recursion because folder is inside another folder
}
else
{
_stprintf(FileFullPath, _T("%s\\%s"), root, wfd.cFileName); // "Folder\\fileName.extension"
_tprintf(_T("%s\n"),FileFullPath);
}
}while(FindNextFile(hFind, &wfd));
CloseHandle(hFind);
hFind=INVALID_HANDLE_VALUE;
}
int main()
{
TCHAR Folder[0xFF]=_T("c:\\windows");
Enum(Folder);
return 0;
}
If you want to access complete visual studio solution you can clone this repository.

Loading an image from a folder using OpenCV 3.0 in Windows

I am using Visual Studio 2010, with OpenCV 3.0. I'm trying to load some images from a folder but I am having problems.
Firstly I did not have the file dirent.h, so I downloaded it in order to get the DIR* and "dirent*" structures to access to the files. All seems to be well, but now when I get to the line
string fileName = in_file->d_name;
I have found that I don't access to the name of the file.
Anyone have any thoughts on this?
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <opencv2/core/dirent.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include <conio.h>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#pragma comment(lib, "User32.lib")
#include <errno.h>
#include <iostream>
#include <time.h>
#include <limits.h>
#include <fstream>
#include <sys/stat.h>
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/ml.hpp>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace cv::ml;
using namespace std;
int patchWidth = 15;
int patchHeight = 15;
int main(int, char**)
{
string imagesPath = "Images";
string resultsPath = "Patches";
DIR* FD;
struct dirent* in_file;
if (NULL == (FD = opendir (imagesPath.c_str())))
{
fprintf(stderr, "Error : Failed to open input directory\n");
return 0;
}
while ((in_file = readdir(FD)))
{
/* On linux/Unix we don't want current and parent directories
* If you're on Windows machine remove this two lines
*/
// if (!strcmp (in_file->d_name, "."))
// continue;
// if (!strcmp (in_file->d_name, ".."))
// continue;
/* Open directory entry file for common operation */
/* TODO : change permissions to meet your need! */
string fileName = in_file->d_name;
string pathFile = imagesPath;
pathFile.append("/");
pathFile.append(fileName);
//pathFile.append(".jpg");
Mat img = imread(pathFile.c_str());
Thanks in advance.
for a much simpler solution, just use cv::glob :
String imagesPath = "Images/*.png"; // it has filters, too !
vector<String> fn;
glob(path, fn, true); // recursive, if you want
for (size_t i=0; i<fn.size(); i++)
{
Mat img = imread(fn[i]);
...
}

How to search a directory for all text files

this is my first official post here, so let's begin:
I need to make a method in my class Searcher to find all the text files in a directory and add them to a vector.
I figured, when I find another directory, to call the function recursively so that I could do my search for the .txt files in that directory aswell..and so on.
So here is how I did it:
void IndexIt(string direktorij) {
string pom(direktorij);
DIR* dir = opendir(direktorij.c_str());
if(dir==NULL) {
cout<<"Ne mogu otvoriti direktorij!";
return;
}
struct dirent *file;
while ((file = readdir(dir))!=NULL) {
string filename(file->d_name);
if (filename.substr(filename.length()-4)== ".txt") {
AddTheFilenameInVector(filename); //made a simple method to add the filename in a vector
} //so I could save it for later use
string filepath = pom + "\\" + filename;
try {
struct stat filedata;
stat (filepath.c_str(), &filedata);
if (S_ISDIR(filedata.st_mode)) {
IndexIt(filepath);
}
}
catch(...) {
int b(2);
cout<<" "<<b*2;
}
}
}
When I try to build it, I just get the caught exceptions in the try-catch block. I must be doing something wrong and I suspect on my recursive calling of IndexIt(filepath).
I've tried with other alternatives such as
string directory;
const size_t last_slash_idx = filename.rfind('\\');
if (std::string::npos != last_slash_idx) {
directory = filename.substr(0, last_slash_idx);
}
to get the filepath, also didn't resolve my issue.
I hope I explained it well enough.
I forgot to say that any libraries except those bellow are not allowed.
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <fstream>

Using pipe in Eclipse

I'm trying to compile my code in Eclipse
But it wouldnt compile my pipe use.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include <signal.h>
#include <map>
#include <string>
#include <iostream>
#include <sstream>
#include <fstream>
#include <sys/wait.h>
using namespace std;
int OpenPipeRead(string sinterface)
{
int ret_val,errno;
string lpipename="",lpipepath="";
lpipepath = mconfig[C_PIPEPATH];
lpipename.append(lpipepath); //Its not empty only when there is argument for parallal telepath_sniff instances.
lpipename.append(mconfig[C_PIPENAME]);
if(strcmp(sinterface.c_str(), "") != 0)
lpipename.append("_" + sinterface);
printf("Trying to open Pipe for reading\n");
syslog(LOG_INFO, "Try to open Pipe for reading\n");
/* Create the named - pipe */
ret_val = mkfifo(lpipename.c_str(), 0666);
if ((ret_val == -1) && (errno != EEXIST)) {
perror("Error creating the named pipe");
syslog(LOG_ERR, "Error creating the named pipe");
exit(1);
}
if((pipehandler = open(lpipename.c_str(), O_RDWR)) < 1) /* Open the pipe for reading and writing , in append mode */
{
perror("Failed to open pipe file");
syslog(LOG_ERR, "Failed to open pipe file");
exit(1);
}
printf("Pipe opened.\n");
syslog(LOG_INFO, "Pipe opened.\n");
}
int main(){
OpenPipeRead("arg");
}
errors are :
../src/main.cpp:325: error: ‘EEXIST’ was not declared in this scope
../src/main.cpp:330: error: ‘O_RDWR’ was not declared in this scope
../src/main.cpp:330: error: ‘open’ was not declared in this scope
It does compile outside of Eclipse
Any includes or flags I need to compile with on Eclipse?
Thanks
The EEXIST MACRO is defined in asm-generic/errno-base.h and the O_RDWR Flag is defined in fcntl.h.
Add :
#include <asm-generic/errno-base.h>
#include <fcntl.h>
To the file containing OpenPipeRead definition and it should compile.