Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

loop through a file and print file attributes in C

I am very new to programming in C. I need this program to loop through all the files in a folder and print these attributes for each file. At this point it is printing the attributes of just the folder.

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <dirent.h>

int main(int argc, char *argv[])
{
    DIR *dp;
    struct stat file_stats;

    if (argc != 2) {
        fprintf(stderr, "Usage: fstat FILE...\n");
        return EXIT_FAILURE;
    }

    if ((stat(argv[1], &file_stats)) == -1) {
        perror("fstat");
        return EXIT_FAILURE;
    }

    dp = opendir("./");
    if (dp == NULL) {
        perror("couldn't open directory");
        return EXIT_FAILURE;
    }

    while (readdir(dp)) {
        printf("filename: %s\n", argv[1]);
        printf(" device: %lld\n",
                file_stats.st_dev);
        printf(" protection: %o\n",
                file_stats.st_mode);
        printf(" number of hard links: %d\n",
                file_stats.st_nlink);
        printf(" user ID of owner: %d\n",
                file_stats.st_uid);
        printf(" group ID of owner: %d\n",
                file_stats.st_gid);
        printf(" device type (if inode device): %lld\n",
                file_stats.st_rdev);
        printf(" total size, in bytes: %ld\n",
                file_stats.st_size);
        printf(" blocksize for filesystem I/O: %ld\n",
                file_stats.st_blksize);
        printf(" inode number: %lu\n",
                file_stats.st_ino);
        printf(" time of last access: %ld : %s",
                file_stats.st_atime,
                ctime(&file_stats.st_atime));
        printf(" time of last change: %ld : %s",
                file_stats.st_ctime,
                ctime(&file_stats.st_ctime));
        closedir(dp);
    }

    return EXIT_SUCCESS;
}

I think I need to move the struct into the while loop but when I do that the compiler says "file_stats undeclared."

like image 549
MikeT Avatar asked Apr 09 '15 20:04

MikeT


Video Answer


1 Answers

In addition to Valentin's answer, you also should move closedir() out of the loop.

UPDATE: also you need to replace stat(argv[1], ...) with stat(ep->d_name, ...) to obtain information about actual file. But before that you need to enter argv[1] directory (using chdir() system call).

Completely working code:

#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <dirent.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    DIR *dp;
    struct stat file_stats;
    struct dirent *ep;
    int ret = EXIT_SUCCESS;
    int ret2;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s FILE...\n", argv[0]);
        return EXIT_FAILURE;
    }

    dp = opendir(argv[1]);
    if (dp == NULL) {
        perror("Couldn't open directory");
        return EXIT_FAILURE;
    }

    ret2 = chdir(argv[1]);
    if (ret2 == -1) {
        perror("Unable to change directory");
        ret = EXIT_FAILURE;
        goto out1;
    }

    while ((ep = readdir(dp))) {
        printf("filename: %s\n", ep->d_name);

        if ((stat(ep->d_name, &file_stats)) == -1) {
            perror("fstat");
            ret = EXIT_FAILURE;
            goto out2;
        }

        printf(" device: %lld\n",
                file_stats.st_dev);
        printf(" protection: %o\n",
                file_stats.st_mode);
        printf(" number of hard links: %d\n",
                file_stats.st_nlink);
        printf(" user ID of owner: %d\n",
                file_stats.st_uid);
        printf(" group ID of owner: %d\n",
                file_stats.st_gid);
        printf(" device type (if inode device): %lld\n",
                file_stats.st_rdev);
        printf(" total size, in bytes: %ld\n",
                file_stats.st_size);
        printf(" blocksize for filesystem I/O: %ld\n",
                file_stats.st_blksize);
        printf(" inode number: %lu\n",
                file_stats.st_ino);
        printf(" time of last access: %ld : %s",
                file_stats.st_atime,
                ctime(&file_stats.st_atime));
        printf(" time of last change: %ld : %s\n",
                file_stats.st_ctime,
                ctime(&file_stats.st_ctime));
    }

out2:
    ret2 = chdir("..");
    if (ret2 == -1) {
        perror("Unable to change directory back");
        ret = EXIT_FAILURE;
        goto out1;
    }

out1:
    closedir(dp);
    return ret;
}
like image 188
Sam Protsenko Avatar answered Sep 29 '22 05:09

Sam Protsenko