Your goDir()
function never opens a new directory, or closes the directory once it has finished. That is going to lead to problems — basically, you are not traversing down your directory hierarchy.
You'll need to make dir
a local (non-static
) variable in the goDir()
function; you'll open and close directories; and instead of passing argv
, you'll pass a directory name, etc.
While you're at it, you should change goDir()
to return the size it finds, and lose the static
variable total_size
.
This code looks semi-plausible:
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#ifndef NAME_MAX
#define NAME_MAX 1024
#endif
static long goDir(char *dirname)
{
DIR *dir = opendir(dirname);
if (dir == 0)
return 0;
struct dirent *dit;
struct stat st;
long size = 0;
long total_size = 0;
char filePath[NAME_MAX];
while ((dit = readdir(dir)) != NULL)
{
if ( (strcmp(dit->d_name, ".") == 0) || (strcmp(dit->d_name, "..") == 0) )
continue;
sprintf(filePath, "%s/%s", dirname, dit->d_name);
if (lstat(filePath, &st) != 0)
continue;
size = st.st_size;
if (S_ISDIR(st.st_mode))
{
long dir_size = goDir(filePath) + size;
printf("DIR\t");
printf("MODE: %lo\t", (unsigned long) st.st_mode);
printf("SIZE: %ld\t", dir_size);
printf("%s\n", filePath);
total_size += dir_size;
}
else
{
total_size += size;
printf("FILES\t");
printf("MODE: %lo\t", (unsigned long) st.st_mode);
printf("SIZE: %ld\t", size);
printf("%s\n", filePath);
}
}
return total_size;
}
int main(int argc, char *argv[])
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s <Directory>\n", argv[0]);
return 1;
}
long size = goDir(argv[1]);
printf("Total size: %ld\n", size);
return 0;
}
It compiles and runs. It does not give the same answer as du -k
, mainly because it does not round up the size of files to an integral number of disk blocks. You'd need to look at st_blksize
and/or st_blocks
in the struct stat
to get that information.