logoISU  

CS456 - Systems Programming

Spring 2023

Displaying ./code/midterm/filecount.c

/*

MIDTERM: PROGRAMMING PORTION:

This program will take a directory, and count the number of
files in the directory. 

It will print the total number of files, as well as the number
of directories, regular files, as well as symbolic links.

If the user inputs a file that is not a directory, let the user know that/

This will be 50% of your midterm grade.


*/
//include statements go here, add new ones as needed
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <dirent.h>

// typedef statements, to save on typing
typedef struct stat STAT;       // for the stat struct
typedef struct dirent DIRENT;   // 


int main(int argc, char **argv){

	// usage statement if no arguments entered 
	if(argc < 2){
		fprintf(stderr, "Usage: %s file\n", argv[0]);
		exit(1);
	}

	//declare variables
	DIR *mydir;      // for the directory stream
	DIRENT *file;    // for the directory entries structure
	STAT st;         // for the stat structure
	



	//call stat on the file that was specified by the user
	stat(argv[1], &st);


	//determine if that file is a directory
		//if not, print an error message then exit.
	if(S_ISDIR(st.st_mode) == 0) {
		fprintf(stderr, "%s is not a directory\n", argv[1]);
		exit(-1);
	}


	//open the directory
	mydir = opendir(argv[1]);
	
	//check return value of opendir
		//if NULL, say directory failed to open and then exit
	if(mydir == NULL){
		fprintf(stderr, "failed to open directory\n");
		exit(-1);
	}

	///initalize counts for the following
	int dir = 0;	// directories
	int reg = 0;	// regular files
	int lnk = 0;	// symbolic link
	int tot = 0;    // total files   

	//define another stat struct like above, (but obviously, with a different variable)
	STAT fi;
	int fd = dirfd(mydir);

	//loop through all of the files in the directory
	while((file = readdir(mydir)) != NULL){
		

		//call stat on the current file
			//hint: what entry would that be in the directory entries structure?
		fstatat(fd, file->d_name, &fi, 0);
		//use the appropriate macros to determine if a file is 
		if(S_ISDIR(fi.st_mode)) dir++;	//directory
		if(S_ISREG(fi.st_mode)) reg++;	//regular
		if(S_ISLNK(fi.st_mode)) lnk++;	//symbolic link

		//and increment the count where appropriate
		//also increment the total files
		tot++;

	}	

	//now print the counts of each
	printf("total files: %d\n", tot);
	printf("\tdirectories: %d\n", dir);
	printf("\tregular files: %d\n", reg);
	printf("\tsymbolic links: %d\n", lnk);

	//close the directory
	closedir(mydir);

	return 0;

}