По заданию мне нужно реализовать ls -R. Он работает, но почему-то открывает не все папки. Что можно сделать?

Собственно код:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <pwd.h>
#include <time.h>
#include "grp.h"

void Color (struct stat cur_stat) {
    if ((cur_stat.st_mode & S_IXUSR) | (cur_stat.st_mode & S_IXGRP) | (cur_stat.st_mode & S_IXOTH)) {
        printf("\033[1;32m");
    }
    switch (cur_stat.st_mode & S_IFMT) {
        case S_IFBLK:
            printf("\033[1;33m \033[40m");
            break;
        case S_IFCHR:
            printf("\033[1;33m \033[40m");
            break;
        case S_IFDIR:
            printf("\033[1;34m");
            break;
        case S_IFIFO:
            printf("\033[0;33m \033[40m");
            break;
        case S_IFLNK:
            printf("\033[1;36m");
            break;
        case S_IFSOCK:
            printf("\033[1;35m");
            break;
    }
}

void Ps (struct stat cur_stat) {
    printf( (S_ISDIR(cur_stat.st_mode)) ? "d" : "-");
    printf( (cur_stat.st_mode & S_IRUSR) ? "r" : "-");
    printf( (cur_stat.st_mode & S_IWUSR) ? "w" : "-");
    printf( (cur_stat.st_mode & S_IXUSR) ? "x" : "-");
    printf( (cur_stat.st_mode & S_IRGRP) ? "r" : "-");
    printf( (cur_stat.st_mode & S_IWGRP) ? "w" : "-");
    printf( (cur_stat.st_mode & S_IXGRP) ? "x" : "-");
    printf( (cur_stat.st_mode & S_IROTH) ? "r" : "-");
    printf( (cur_stat.st_mode & S_IWOTH) ? "w" : "-");
    printf( (cur_stat.st_mode & S_IXOTH) ? "x" : "-");
}

void fi(struct stat cur_stat) {
    char t[1000];
    time_t time = cur_stat.st_mtim.tv_sec;
    struct tm * p = localtime(&time);
    strftime(t, 1000, "%b %2d %H:%M", p);

    Ps(cur_stat);
    printf("% ld %s %s %5ld %s ", cur_stat.st_nlink, getpwuid(cur_stat.st_uid)->pw_name, \
            getgrgid(cur_stat.st_gid)->gr_name, cur_stat.st_size, t);
}

void ls(DIR * dir, int flag_a, int flag_l, int flag_R) {
    struct dirent* file;
    char** subdirs;
    int* line;
    int isd = 0;
    subdirs = (char**)malloc(10000 * sizeof(char*));
    line = (int*)malloc(10000 * sizeof(int));

    while(file = readdir(dir)) {
        char* f_name = file->d_name;
        struct stat cur_stat;
        stat(f_name, &cur_stat);

        if (flag_a) {
            if (flag_l) {
                fi(cur_stat);
            }
            Color(cur_stat);
            printf("%s ", f_name);
            if (flag_l) {
                printf("\n");
            }
        }
        else if (f_name[0] != '.') {
            if (flag_l) {
                fi(cur_stat);
            }
            Color(cur_stat);
            printf("%s ", f_name);
            if (flag_l) {
                printf("\n");
            }
        }
        printf("\033[0m");

        if (flag_R && S_ISDIR(cur_stat.st_mode)) {
            line[isd] = strlen(f_name);
            subdirs[isd] = (char*)malloc(line[isd] * sizeof(char));
            strcpy(subdirs[isd], f_name);
            isd++;
        }
    }
    closedir(dir);

    while(flag_R && *subdirs) {
        if (flag_a || (*subdirs[0] != '.')) {
            printf("\n%s:\n", *subdirs);
            ls(opendir(*subdirs), flag_a, flag_l, flag_R);
        }
        subdirs++;
    }
    free(subdirs);
    free(line);
}
int main(int argc, char** argv){
    DIR * dir;
    const struct option long_option[] =
            {
                    {"all", no_argument, NULL, 'a'},
                    {"format=long", no_argument, NULL, 'l'},
                    {"recursive", no_argument, NULL, 'R'},
                    {NULL, no_argument, NULL, 0}
            };
    int long_index;
    const char short_option[]="alR";
    int opt;
    int flag_a = 0, flag_l = 0, flag_R = 0;
    while((opt = getopt_long(argc, argv, short_option, long_option, &long_index)) != -1)
    {
        switch(opt)
        {
            case 'a': flag_a++;
                break;
            case 'l': flag_l++;
                break;
            case 'R': flag_R++;
                break;
            case '?': printf("Неизвестный парамтер: -%c\n", optopt);
        }
    }

    char* pap = argv[optind];
    if (pap) {
        dir = opendir(pap);
    }
    else {
        dir = opendir(".");
    }
    ls(dir,flag_a,flag_l,flag_R);
    printf("\n");
    return 0;
}


Ответы (0 шт):