I wrote an executable that checks the presence of combinations of xattr tags
. I want to use that executable on all the files of a directory, that means I want to execute it on every files I find in that directory and every files of the directories there are in it... etc.
My xattr executable
and the program I use to recursively navigate in the dirs look like this:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/xattr.h>
#include <string.h>
#include <errno.h>
int main(int argc, char const *argv[]){
char argNormaux[4096] = {0};
char argNeg[4096] = {0};
char argEt[4096] = {0};
int nbArgsNormaux = 0;
if (argc > 2){
for (int i = 2; i < argc; i++){
const char *arg = argv[i];
if (strstr(argv[i],"et") != NULL){
// printf("%d. Et trouvé. Argument=%s\n", i, argv[i]);
strcat(argEt, argv[i]);
}
else if (strstr(argv[i], "!") != NULL){
// printf("%d. Négation trouvée. Argument=%s\n", i, argv[i]);
strcat(argNeg, argv[i]);
}
else {
// printf("%d. Argument trouvé=%s\n", i, argv[i]);
strcat(argNormaux, argv[i]);
nbArgsNormaux++;
}
}
// printf("nbArgsNormaux=%d\n", nbArgsNormaux);
// printf("Liste des arguments normaux: %s\n", argNormaux);
// printf("Liste des négations: %s\n", argNeg);
// printf("Liste des et: %s\n", argEt);
const char *path = argv[1];
printf("path=%s\n", path);
// printf("Tags du fichier %s\n", path);
char buf[4096];
int rc;
rc = listxattr(path, buf, sizeof(buf));
if (rc < 0){
perror("listxattr");
}
else {
if (strlen(buf) == 0){
printf("Il n'y a aucun tag sur ce fichier.\n");
return 1;
}
int tagsNormauxCheck = 0;
int tagsNegCheck = 0;
char *token = buf;
while(*token){
char tagBuf[4096];
if (strlen(token) == 2){
if (strcmp(token, "\0\0\0")) break;
}
rc = getxattr(path, token, &tagBuf, sizeof(tagBuf));
if (rc < 0){
perror("getxattr");
}
else {
if (strstr(argNormaux, tagBuf) != NULL) {
// printf("tagbuf=%s\n", tagBuf);
// printf("Check NULL\n");
tagsNormauxCheck++;
}
if (strstr(argNeg, tagBuf) != NULL) {
tagsNegCheck = 1;
break;
}
}
memset(&tagBuf, 0, sizeof(tagBuf));
token = strchr(token, '\0');
token++;
}
// printf("Normaux=%d, NegCheck=%d\n", tagsNormauxCheck, tagsNegCheck);
if (tagsNormauxCheck == nbArgsNormaux && tagsNegCheck == 0){
printf("Le fichier %s possède la combinaison des tags donnés.", path);
return 1;
}
}
}
else {
printf("Pas assez d'arguments.\n");
return 0;
}
return 0;
}
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>
void listFilesRecursively(char *basePath, int argc, char const *argv[]){
char path[4096];
struct dirent *dp;
DIR *dir = opendir(basePath);
// Unable to open directory stream
if (!dir) return;
char const *cpArgv[argc+2];
for (int i = 1; i < argc; i++){
cpArgv[i] = argv[i];
}
cpArgv[argc+2] = NULL;
while ((dp = readdir(dir)) != NULL){
if (strcmp(dp->d_name, ".") != 0 && strcmp(dp->d_name, "..") != 0){
if (dp->d_type == DT_REG){
cpArgv[0] = "./logic";
cpArgv[1] = path;
strcpy(cpArgv[1], basePath);
strcat(cpArgv[1], "/");
strcat(cpArgv[1], dp->d_name);
printf("%s\n", dp->d_name);
for (int i = 0; i < argc; i++){
printf("cpArgv[%d]=%s\n",i, cpArgv[i]);
}
}
if (fork() == 0){
execv("./logic",cpArgv);
}
// Construct new path from our base path
strcpy(path, basePath);
strcat(path, "/");
strcat(path, dp->d_name);
listFilesRecursively(path, argc, cpArgv);
}
}
closedir(dir);
}
int main(int argc, char const *argv[]){
if (argc > 1){
listFilesRecursively(argv[1], argc, argv);
}
else {
printf("Pas assez d'arguments, test.\n");
}
return 0;
}
The xattr program
works perfectly fine when used alone, from the terminal. The program used to get all the files recursively in a directory works perfectly fine when used without the fork
and exec
. However, when I use them, The program is showing duplicates, the xattr program is executed but not finding the tags, like it's just executed, but not finishing, and some files are not showed...
This an example of the output I can have:
dir2fichierUN.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/dir2/dir2fichierUN.txt
cpArgv[2]=essai1
fichier1.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier1.txt
cpArgv[2]=essai1
fichier2.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier2.txt
cpArgv[2]=essai1
fichier1.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier1.txt
cpArgv[2]=essai1
fichier1.txt
fichier2.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier2.txt
cpArgv[2]=essai1
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier1.txt
cpArgv[2]=essai1
fichier2.txt
cpArgv[0]=./logic
cpArgv[1]=testDir/fichier2.txt
cpArgv[2]=essai1
path=testDir/fichier1.txt
path=testDir/fichier2.txt
path=testDir/fichier1.txt
path=testDir/fichier2.txt
path=testDir/fichier1.txt
path=testDir/fichier2.txt
path=testDir/fichier1.txt
path=testDir/fichier2.txt
The program seems to be hanging in my terminal...
What I'm trying to achieve here is to be able to execute my xattr
program on every file there are in the directory the first the second program is called. I have troubles making it work with fork
and execv
.
Could you help me please?
Thanks.