Hey guys, i've been working on this program for about a week or two (this is a linux application programming class), it's supposed to pretty much perform what the du command does, but make it a little nicer, specifically show in a tree format. usage is as follows:
./du3 -[asLhi:t] [directory-name(s)]
where
a = output line for each file and directory in current directorie(s)
s = summary - only total of for each specified name arguments to be given
h = help...provide usage
L = follow symbolic links
t = tree format (default indent of 3 for files within directory)
in= where n is the indentation if you want it different from default of 3.
if a and s are both specified, call help, if no directory, default to current directory...i think that's it for requirements....now to the questions:
I'm to make use of a makefile to link everything together, using these compile options at minimum: -ansi -pedantic -Wall -Wextra -02
It's near completion, i just need some clarification on a few things: they are as follows:
if I do a du -ac . I get a listing similar to what my program would show, -c shows the total blocksize for the directory. When I run my program with the -ai5 let's say, i get a near identical display but all the blocksizes are doubled! (there's question # 1), i don't know why I receive this result...i've tried it on several systems (fedora, ubuntu).
Question 2: Inside my optS function, where I am only displaying the total for each one, I can't seem to figure out how to display a total for each specified argument....i just get the first...and then nothing else...I can't seem to follow my error on this one.
Makefile
Code:
CFLAGS=-ansi -pedantic -Wall -Wextra -g
du3: main.o optA.o optS.o
gcc ${CFLAGS} -o du3 main.o optA.o optS.o
main.o: main.c du3.h
gcc ${CFLAGS} -c main.c
optA.o: optA.c du3.h
gcc ${CFLAGS} -c optA.c
optS.o: optS.c du3.h
gcc ${CFLAGS} -c optS.c
clean:
rm -f core *.o
header file du3.h:
Code:
#ifndef __includes_
#define __includes_
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <getopt.h>
#include <string.h>
#endif
main function:
Code:
int main( int argc, char *argv[] )
{
int c,type=0,indent=0;
while( (c = getopt(argc, argv, "ai:hLst")) != -1 )
{
switch( c )
{
case 'a':
type = 1;
break;
case 'h':
printf( "option h\n" );
return 0;
case 'i':
indent = atoi( optarg );
break;
case 'L':
printf( "option L\n" );
break;
case 's':
type = 2;
break;
case 't':
indent = 3;
break;
case '?':
printf( "Unknown option!\n" );
return 0;
default:
printf( "default is to print usage\n" );
break;
}
}
if (type == 1)
{
while( optind < argc )
optA( argv[optind++], type, indent );
}
if (type == 2)
{
while (optind < argc)
optS(argv[optind++],1,indent);
}
return 0;
}
Function optA:
Code:
#include "du3.h"
int optA( char *dpath, int type, int indent )
{
DIR *pDir;
struct dirent *dInfo;
struct stat fInfo;
char tempName[1000];
if( (pDir = opendir(dpath)) == NULL)
{
printf( "Unable to open path: %s\n", dpath );
return 1;
}
while( (dInfo=readdir(pDir)) != NULL )
{
if( strcmp(dInfo->d_name, ".") != 0 && strcmp(dInfo->d_name, "..") != 0 )
{
strcpy( tempName, dpath );
strcat( tempName, "/" );
strcat( tempName, dInfo->d_name );
if( (stat(tempName, &fInfo)) == -1 )
printf( "Unable to stat: %s", dInfo->d_name);
else if( (type == 0) && S_ISDIR(fInfo.st_mode) )
printf( "%-*d%-20s\n", indent, (int)fInfo.st_blocks, dInfo->d_name );
else if( (type == 1) && S_ISDIR(fInfo.st_mode) )
{
printf( "%-*d%-20s\n", indent, (int)fInfo.st_blocks, dInfo->d_name );
optA( tempName, type, indent+3 );
}
else if( type == 1 )
printf( "%-*d%-20s\n", indent, (int)fInfo.st_blocks, dInfo->d_name );
}
}
closedir( pDir );
return 0;
}
function optS
Code:
#include "du3.h"
/* Function to display total at the end */
void DisplayTotal(char *temppath,int indent,int total)
{
printf("%-*d%-20s\n",indent,total,temppath);
}
int optS( char *dpath, int type, int indent )
{
DIR *pDir;
struct dirent *dInfo;
struct stat fInfo;
char tempName[1000];
int blocksize;
blocksize = 0;
if( (pDir = opendir(dpath)) == NULL)
{
printf( "Unable to open path: %s\n", dpath );
return 1;
}
while( (dInfo=readdir(pDir)) != NULL )
{
if( strcmp(dInfo->d_name, ".") != 0 && strcmp(dInfo->d_name, "..") != 0 )
{
strcpy( tempName, dpath );
strcat( tempName, "/" );
strcat( tempName, dInfo->d_name );
if( (stat(tempName, &fInfo)) == -1 )
printf( "Unable to stat: %s", dInfo->d_name);
else if( (type == 0) && S_ISDIR(fInfo.st_mode) ){}
/* printf( "%-*d%-20s\n", indent, (int)fInfo.st_blocks, dInfo->d_name );*/
else if( (type == 1) && S_ISDIR(fInfo.st_mode) )
{
/* printf( "%-*d%-20s\n", indent, (int)fInfo.st_blocks, dInfo->d_name ); */
optS( tempName, type, indent+3 );
}
else if( type == 1 )
{
/* printf( "%-*d%-20s\n", indent, (int)fInfo.st_blocks, dInfo->d_name ); */
blocksize += fInfo.st_blocks;
}
}
}
/* printf("Total: %d\n",blocksize); */
closedir( pDir );
DisplayTotal(dpath,indent,blocksize);
return 0;
}
I apologize for the amount of code

running make should provide no errors on the files specified so i have a logic problem at hand....play around if anyone has time...my -a is working fine i believe except for displaying double the blocksize, I can't seem to figure it out since i'm just retrieving it's blocksize from dirent struct with a stat...
my option s seems to work when I specify only one directory (that is it gives me exactly double the total if i do a du - s [directory])...and only works with the first given argument...any help would be appreciated...
other thing i've noticed: if i do a ./du3 -si5 ..
i get the total of .. to be smaller than that of . which in my case was 136 blocks...i got .. as a blocksize of 112 !? Well i'm rambling....maybe i'll shed my own light in the meantime