C - 递归复制文件

C - recursively copying files

我不知道为什么,但我找不到问题出在哪里。我 运行 测试它是目录还是文件,甚至文件也被视为文件夹。

问题是,虽然 运行即使是文件循环,它也会进入目录进程并发布“file1 for directories”

代码如下:

void copie_dossier(char *doss1, char *doss2) {
    struct dirent *dptr;
    DIR *dp;
    struct stat stbuf;

    char newDest[strlen(doss2) + 1];
    char tempSrc[strlen(doss1) + 1];
    strcat(doss2, "/");
    strcat(doss1, "/");
    strcpy(newDest, doss2);
    strcpy(tempSrc, doss1);

    stat(doss1, &stbuf);

    dp = opendir(doss1);

    /*
    if (!dp) {
       perror("open_dir");
       exit(1);
    }
    */

    if (!(dp))
        return;
    if (!(dptr = readdir(dp)))
        return;

    int mk = mkdir(doss2, 0777);
    if (mk == -1) {
        perror("create_dir");
        exit(1);
    }

    while ((dptr = readdir(dp)) != NULL) {
        struct stat stbuf2;
        //stat(dptr->d_name, &stbuf2);
        char *new = dptr->d_name;

        if (!strcmp(dptr->d_name, ".") || !strcmp(dptr->d_name, "..")) {
            continue;
        }

        if (!stat(tempSrc, &stbuf2)) {
            if (S_ISREG(stbuf.st_mode)) {
                printf("%s for files\n", dptr->d_name);
                strcat(newDest, dptr->d_name);
                strcat(tempSrc, dptr->d_name);
                copy_files(tempSrc, newDest);
                strcpy(newDest, doss2);
                strcpy(tempSrc, doss1);
            }

            if (S_ISDIR(stbuf.st_mode)) {
                printf("%s for directory \n", dptr->d_name);
                strcat(newDest, dptr->d_name);
                strcat(tempSrc, dptr->d_name);
                copie_dossier(tempSrc, newDest);
                strcpy(newDest, doss2);
                strcpy(tempSrc, doss1);
            } 
        }
    }
    closedir(dp);
}

问题出在本地缓冲区的分配上:

char newDest[strlen(doss2) + 1];
char tempSrc[strlen(doss1) + 1];
strcat(doss2, "/");
strcat(doss1, "/");
strcpy(newDest, doss2);
strcpy(tempSrc, doss1);

即使是第一次使用 newDesttempSrc 也会在您复制不适合目标的字符串时调用未定义的行为。 newDesttempSrc 分别分配给 doss1doss2 中的字符数(最后的 '[=18=]'),但是您附加了一个额外的 / 复制前。

稍后在代码中,您连接目录条目名称,导致进一步的未定义行为。

您必须更改路径名组成的逻辑。您可以使用内存分配或全局缓冲区,在其中连接条目,同时记住路径名用于结束的位置以将其剥离回以前的状态。

在您的目录/文件名测试中还有另一个大问题:您没有 stat() 正确的路径名并且您使用单独的 stbuf2 而不是 stbuf。您应该首先创建当前条目的路径名,将其传递给 stat() 并检查结果 stbuf.

上的目录和文件名

这是一个改进的版本:

char *make_path(const char *path, const char *name) {
    size_t len = strlen(path);
    char *p = malloc(len + 1 + strlen(name) + 1);
    if (p) {
        strcpy(p, path);
        p[len] = '/';
        strcpy(p + len + 1, name);
    }
    return p;
}

void copie_dossier(const char *doss1, const char *doss2) {
    DIR *dp;
    struct dirent *dptr;

    dp = opendir(doss1);
    if (dp == NULL)
        return;

    int mk = mkdir(doss2, 0777);
    if (mk == -1) {
        perror("create_dir");
        exit(1);
    }

    while ((dptr = readdir(dp)) != NULL) {
        struct stat stbuf;
        char *source, *dest;

        if (!strcmp(dptr->d_name, ".") || !strcmp(dptr->d_name, "..")) {
            continue;
        }

        source = makepath(doss1, dptr->d_name);
        dest = makepath(doss2, dptr->d_name);
        if (!source || !dest) {
            perror("makepath");
            exit(1);
        }                
        if (!stat(source, &stbuf)) {
            if (S_ISREG(stbuf.st_mode)) {
                printf("%s for files\n", dptr->d_name);
                copy_files(source, dest);
            } else
            if (S_ISDIR(stbuf.st_mode)) {
                printf("%s for directory \n", dptr->d_name);
                copie_dossier(source, dest);
            } 
        } else {
            // should issue a diagnostic message
        }
        free(source);
        free(dest);
    }
    closedir(dp);
}

您没有 post 函数 copy_files 的代码。我假设它复制了一个文件,不管名字是什么。