View Single Post
Old 10-02-2006, 01:57 PM   #1 (permalink)
Deliverance
C++ Beginner
 
Join Date: Jul 2005
Location: Ottawa
Posts: 73
Deliverance is on a distinguished road
DU command adapted in C

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
__________________
Deliverance is offline   Reply With Quote