Связанный список конечных файлов и каталогов в дереве каталогов с использованием C

Я использую nftw(прогулка по дереву файлов) для обхода каталога (который имеет подкаталоги и файлы). Я передал каталог с помощью функции CLI. Теперь мне нужно сохранить листовые файлы и каталоги (пустые каталоги) в связанный список и распечатать их. Я создал функцию для nftw, которая называется disp& передал его в nftw, чтобы он распечатал некоторую информацию о файлах. Связанный список хранит информацию о файле, созданном stat & для печати связанного связанного списка printllиспользуется функция. Для файлов я могу проверить это typeflag == FTW_Fа затем введите следующее, но как мне проверить пустые каталоги в nftw и добавить их в связанный список?

Я пробовал следующее

      #define _XOPEN_SOURCE 500
#include <stdio.h>
#include <ftw.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

typedef struct node{
    long ino;     //Inode number
    long f_size;  //file size
    long a_tm;    //Access time
    long m_tm;    //Modify time
    long c_tm;    //change time
    struct node *next;
}node;

node *tmp = NULL;
static node *head = NULL;

void printll(node *head);

//display function
static int disp(const char *fpath,
          const struct stat *s,
          int typeflag,
          struct FTW *ftw);

//Function to create linked list
static int linked(const char *fpath,
          const struct stat *s,
          int typeflag,
          struct FTW *ftw); 


/* ------------------Main---------------------*/
int main(int argc, char *argv[]){
    int flags = 0;
    if(argc > 2 && strchr(argv[2], 'd') != NULL)
        flags |= FTW_DEPTH;

    printf("File_type\tF_size\t\tPath\t\t\t\t\t\t\tInode\n");

    if(nftw((argc < 2) ? "." : argv[1], disp, 20, flags) == -1) {
        perror("nftw");
        return -1;
    }
    printf("\n");
//  nftw((argc < 2) ? "." : argv[1], linked, 20, flags);
    printll(tmp);
    exit(EXIT_SUCCESS);
}

static int disp(const char *fpath,
      const struct stat *s,
      int typeflag,
      struct FTW *ftw){

    printf("%-3s\t\t%7jd\t\t%-40s\t\t%ld\n",
        (typeflag == FTW_D) ? "d" : (typeflag == FTW_F) ? "f": "???",
        s->st_size, fpath, s->st_ino);
    struct dirent *r;
    if(typeflag == FTW_F){      //How to check empty dirs here?
        if(head == NULL){
            head = malloc(sizeof(node));
            head->ino   =   s->st_ino;
            head->f_size    =   s->st_size;
            head->a_tm  =   s->st_atime;
            head->m_tm  =   s->st_mtime;
            head->c_tm  =   s->st_ctime;
            head->next  =   NULL;
            tmp = head;
        } else if(head != NULL) {
            if(tmp != NULL){
                node *ptr = malloc(sizeof(node));
                ptr->ino    =   s->st_ino;
                ptr->f_size =   s->st_size;
                ptr->a_tm   =   s->st_atime;
                ptr->m_tm   =   s->st_mtime;
                ptr->c_tm   =   s->st_ctime;
                ptr->next   =   NULL;
                
                tmp->next = ptr;
                tmp = tmp->next;
                
            }
        }
        while(tmp != NULL){
            printf("%ld\n", tmp->ino);
            printf("%ld\n", tmp->f_size);
            printf("%ld\n", tmp->a_tm);
            printf("%ld\n", tmp->m_tm);
            printf("%ld\n", tmp->c_tm);
            tmp = tmp->next;
        }
    }
    return 0;
}   


 void printll(node *head){
    node *ptr;
    if(head == NULL)
        printf("The linked list is NULL\n");
    ptr = head;
    while(ptr != NULL){
        printf("%ld\n", ptr->ino);
        printf("%ld\n", ptr->f_size);
        printf("%ld\n", ptr->a_tm);
        printf("%ld\n", ptr->m_tm);
        printf("%ld\n", ptr->c_tm);
        ptr = ptr->next;
    }
}

1 ответ

Вот код для создания связанного списка с помощью ftw

      #define _XOPEN_SOURCE 500
#include <stdio.h>
#include <libgen.h>
#include <ftw.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

typedef struct node{
    long ino;
    long f_size;
    long a_tm;
    long m_tm;
    long c_tm;
    struct node *next;
}node;

node *c, *tmp = NULL, *loc;
static node *head = NULL;

void printll(node *head);   //printing of linked list

static int disp(const char *fpath,
          const struct stat *s,
          int typeflag,
          struct FTW *ftw);

static int linked(const char *fpath,
          const struct stat *s,
          int typeflag,
          struct FTW *ftw); 

void add_at_end(node *p);

/* ------------------Main---------------------*/

int main(int argc, char *argv[]){
    int flags = 0;
    if(argc > 2 && strchr(argv[2], 'd') != NULL)
        flags |= FTW_DEPTH;

    printf("File_type\tF_size\t\tPath\t\t\t\t\t\t\tInode\n");

    if(nftw((argc < 2) ? "." : argv[1], disp, 20, flags) == -1) {
        perror("nftw");
        return -1;
    }
    nftw((argc < 2) ? "." : argv[1], linked, 20, flags);
    printf("\n");
    printll(tmp);
    int num, fd;
    char f_name[100], dest[100], str_ent[100];
    char c, dl;
    struct stat fb;
    while(1){
        printf("1. Add a file\n");
        printf("2. Delete a file\n");
        printf("3. Add a directory\n");
        printf("4. Delete a directory\n");
        printf("Enter the operation num to perform\n");
        scanf(" %d", &num);
        switch(num){
        case 1:
            printf("File Name: ");
            scanf("%s", f_name);
            printf("Destination: ");
            scanf("%s", dest);
            strcat(dest, f_name);
            open(dest, O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
            printf("File %s is successfully added.\n", f_name);
            printf("Do you want to write to this file (Y/N)? \n");
            scanf(" %c", &c);
            if(c == 'y' || c == 'Y'){
                FILE *f;
                f = fopen(dest, "w");
                printf("How many lines do you want to enter: ");
                scanf("%d", &num);
                printf("Enter content\n");
                for(int i = 0; i < num+1; i++){
                    fgets(str_ent, sizeof str_ent, stdin);
                    fputs(str_ent, f);
                }
                printf("The content you entered is written to the file\n");
                fclose(f);
                stat(dest, &fb);
                loc = malloc(sizeof(node));
                loc->ino    =   fb.st_ino;
                loc->f_size =   fb.st_size;
                loc->a_tm   =   fb.st_atime;
                loc->m_tm   =   fb.st_mtime;
                loc->c_tm   =   fb.st_ctime;
                loc->next   =   NULL;
                node *b;
                b = tmp;
                while(b->next != NULL)
                    b = b->next;
                b->next = loc;
                printf("File added to linked list successfully\n");
                break;
            } else if( c == 'n' || c == 'N'){
                stat(dest, &fb);
                loc = malloc(sizeof(node));
                loc->ino    =   fb.st_ino;
                loc->f_size =   fb.st_size;
                loc->a_tm   =   fb.st_atime;
                loc->m_tm   =   fb.st_mtime;
                loc->c_tm   =   fb.st_ctime;
                loc->next   =   NULL;
                node *b;
                b = tmp;
                while(b->next != NULL)
                    b = b->next;
                b->next = loc;
                printf("File added to linked list successfully\n");
                free(loc);
                break;
            }
        case 2:
            printf("File Name: ");
            scanf("%s", f_name);
            printf("Destination: ");
            scanf("%s", dest);
            strcat(dest, f_name);
            stat(dest, &fb);
            printf("The inode for removed file is: %ld\n", fb.st_ino);
            loc = malloc(sizeof(node));
            loc->ino    =   fb.st_ino;
            loc->f_size =   fb.st_size;
            loc->a_tm   =   fb.st_atime;
            loc->m_tm   =   fb.st_mtime;
            loc->c_tm   =   fb.st_ctime;
            loc->next   =   NULL;
            if(loc->ino == tmp->ino){
                tmp = tmp->next;
                printf("The node is shifted to next and break is here\n");
                break;
            } else {
                node *bu, *cu;
                bu = tmp;   //tmp
                cu = tmp;   //tmp2
                while(cu->ino != loc->ino){
                    bu = cu;
                    cu = cu->next;
                }
                bu->next = cu->next;
                free(cu);
                cu = NULL;
                unlink(dest);
                printf("File %s has been removed & linked list it updated.\n", f_name);
                break;
            }
        case 3:
            printf("Dir Name: ");
            scanf("%s", f_name);
            printf("\nDestination: ");
            scanf("%s", dest);
            strcat(dest, f_name);
            mkdir(dest, 00700);
            stat(dest, &fb);
            loc = malloc(sizeof(node));
            loc->ino    =   fb.st_ino;
            loc->f_size =   fb.st_size;
            loc->a_tm   =   fb.st_atime;
            loc->m_tm   =   fb.st_mtime;
            loc->c_tm   =   fb.st_ctime;
            loc->next   =   NULL;
            printf("Directory %s successfully added at %s\n", f_name, dest);
            break;
        case 4:
            printf("Dir Name: ");
            scanf("%s", f_name);
            printf("Destination: ");
            scanf("%s", dest);
            rmdir(dest);
            printf("The directory has been deleted successfully\n");
            break;
        default:
            printf("Operation doesn't exits\n");
            exit(0);
        }
        printf("Do you want to continue with file operations (Y/N)? ");
        scanf(" %c", &c);
        if(c == 'y' || c == 'Y')
            continue;
        else
            break;
    }
    while(1){
        printf("Do you want to print Director structure OR Linked List (D/L)? ");
        scanf(" %c", &dl);
        if(dl == 'd' || dl == 'D')
            nftw((argc < 2) ? "." : argv[1], disp, 20, flags);
        if(dl == 'l' || dl == 'L')
            printll(tmp);
        printf("Do you want to continue the print? ");
        scanf(" %c", &c);
        if(c == 'y' || c == 'Y')
            continue;
        else
            break;
        
    }
    free(tmp);
    exit(EXIT_SUCCESS);
}

/* ----------------Main exit--------------------*/

/* ----------------Display Dir tree structure --------------------*/


static int disp(const char *fpath,
      const struct stat *s,
      int typeflag,
      struct FTW *ftw){

    printf("%-3s\t\t%7jd\t\t%-40s\t\t%ld\n",
        (typeflag == FTW_D) ? "d" : (typeflag == FTW_F) ? "f": "???",
        s->st_size, fpath, s->st_ino);

    return 0;
}   

/* ----------------xx-xx-------------------*/

/* -----------------Linked list function ----------------- */

static int linked(const char *fpath,
      const struct stat *s,
      int typeflag,
      struct FTW *ftw){
        struct dirent *r;
        DIR *d; 
        int files = 0;
        if(typeflag == FTW_D){
            d= opendir(fpath);
            while((r = readdir(d)) != NULL)
                files++;
        }
        if(typeflag == FTW_F || files == 2){  
            if(head == NULL){
                head = malloc(sizeof(node));
                head->ino   =   s->st_ino;
                head->f_size    =   s->st_size;
                head->a_tm  =   s->st_atime;
                head->m_tm  =   s->st_mtime;
                head->c_tm  =   s->st_ctime;
                head->next  =   NULL;
                tmp = head;
            } else if(head != NULL) { 
                node *c = (struct node *)malloc(sizeof(node));
                c->ino      =   s->st_ino;
                c->f_size   =   s->st_size;
                c->a_tm     =   s->st_atime;
                c->m_tm     =   s->st_mtime;
                c->c_tm     =   s->st_ctime;
                c->next     =   NULL;
                add_at_end(c);
            }
        }
    return 0;
}

/* ------------------xx-------xx--------------------------- */

/* ---------------function to add at end ---------------- */

void add_at_end(node *p){
    node *c2 = (struct node *)malloc(sizeof(node));
    c2 = tmp;
    while(c2->next != NULL)
        c2 = c2->next;
    c2->next = p;
}

/* --------------------------x--x-------------------------*/

/* -----------------------Printing linked list ------------------------- */

void printll(node *head){
    node *ptr;
    if(head == NULL)
        printf("The linked list is NULL\n");
    ptr = head;
    while(ptr != NULL){
        printf("%ld\n", ptr->ino);
        printf("%ld\n", ptr->f_size);
        printf("%ld\n", ptr->a_tm);
        printf("%ld\n", ptr->m_tm);
        printf("%ld\n", ptr->c_tm);
        ptr = ptr->next;
        printf("\n");
    }
}

/* ------------------------x---x--------------------------------------- */
Другие вопросы по тегам