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."
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;
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With