1

我编写了一个可执行文件来检查xattr tags. 我想在目录的所有文件上使用该可执行文件,这意味着我想在该目录中找到的每个文件以及其中目录的每个文件上执行它......等等。

xattr executable和我用来在目录中递归导航的程序如下所示:

#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;
}

xattr program从终端单独使用时,效果非常好。用于递归获取目录中所有文件的程序在没有forkand的情况下可以正常工作exec。但是,当我使用它们时,程序显示重复,执行 xattr 程序但没有找到标签,就像它刚刚执行,但没有完成,有些文件没有显示......

这是我可以拥有的输出示例:

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

该程序似乎挂在我的终端...

我在这里想要实现的是能够xattr在目录中的每个文件上执行我的程序,第一个第二个程序被调用。我很难让它与forkand一起使用execv

请问你能帮帮我吗?

谢谢。

4

1 回答 1

1

您不需要自己处理递归,您可以只处理作为命令行参数给出的文件,并用于find将您的命令递归地应用于层次结构中的所有文件:

find . -type f -exec logic args '{}' \;

如果您的logic程序无法从$PATH变量中获得,请将其名称替换为find参数列表中的路径。args是您要在文件名之前传递给程序的参数。

于 2020-05-09T19:32:16.930 回答