View Single Post
Old 10-05-2006, 05:49 AM   #3 (permalink)
Deliverance
C++ Beginner
 
Join Date: Jul 2005
Location: Ottawa
Posts: 73
Deliverance is on a distinguished road
Here's my final solution to this problem. I'm pretty sure I have it all working out, if anyone wants to try and crack it and see if I've overlooked anything feel free. I think the only new thing which I may not have mentioned in my original post is that all options must precede directories...

Any suggestions are welcome
-------------------------------

Makefile
Code:
CFLAGS=-ansi -pedantic -Wall -Wextra -g du3: optA.o optS.o noOpt.o help.o main.o gcc ${CFLAGS} -o du3 optA.o optS.o noOpt.o help.o main.o optA.o: optA.c du3.h gcc ${CFLAGS} -c optA.c optS.o: optS.c du3.h gcc ${CFLAGS} -c optS.c noOpt.o: noOpt.c du3.h gcc ${CFLAGS} -c noOpt.c help.o: help.c du3.h gcc ${CFLAGS} -c help.c main.o: main.c du3.h gcc ${CFLAGS} -c main.c clean: rm -f core *.o
du3 header file:
Code:
#ifndef __includes_ #define __includes_ #define _GNU_SOURCE #define NONE 0 #define ALL 1 #define SUM 2 #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
Function main:
Code:
#include "du3.h" int optA( char*, int, int, int ); int optS( char*, int ); int noOpt( char*, int, int, int ); void help(); int main( int argc, char *argv[] ) { int c,type=NONE,indent=0,lvl=0; int followlinks=0,blocksize=0; while( (c = getopt(argc, argv, "+ai:hLst")) != -1 ) { switch( c ) { case 'a': if( type == NONE ) type = ALL; else { printf( "You cannot specify options 'a' and 's' together\n" ); return EXIT_FAILURE; } break; case 'h': help(); return EXIT_SUCCESS; case 'i': if( atoi(optarg) >= 2 && atoi(optarg) <= 8 ) indent = atoi( optarg ); else { printf( "You must specify an indent between 2 and 8!\n" ); return EXIT_FAILURE; } break; case 'L': followlinks = 1; break; case 's': if( type == NONE ) type = SUM; else { printf( "You cannot specify options 'a' and 's' together\n" ); return EXIT_FAILURE; } break; case 't': indent = 3; break; case '?': help(); return EXIT_FAILURE; default: help(); return EXIT_FAILURE; } } switch( type ) { case ALL: while( optind < argc && argv[optind][0] != '-' ) optA( argv[optind++], indent, lvl, followlinks ); break; case SUM: while( optind < argc ) { if( (blocksize=optS(argv[optind],followlinks)) != -1 ) printf( "%d%*s%s\n", blocksize, indent, " ", argv[optind++] ); } break; case NONE: while( optind < argc ) noOpt( argv[optind++], indent, lvl, followlinks ); break; } return EXIT_SUCCESS; }
function optA.c
Code:
#include "du3.h" int optS( char*, int ); int optA( char *dpath, int indent, int lvl, int followlinks ) { DIR *pDir; struct dirent *dInfo; struct stat fInfo; char tempName[1000]; int total_size = 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( followlinks ) { if( ( stat(tempName, &fInfo)) == -1 ) printf( "Unable to stat: %s",tempName ); else if( S_ISDIR(fInfo.st_mode) ) { printf( "%d%*s%s\n", optS(tempName,followlinks) , (indent*lvl)+1, " ", dInfo->d_name ); optA( tempName, indent, lvl+1, followlinks ); } else { printf( "%d%*s%s\n", (int)fInfo.st_blocks, (indent*lvl)+1, " ", dInfo->d_name ); total_size += (int)fInfo.st_blocks; } } else { if( ( lstat(tempName, &fInfo)) == -1 ) printf( "Unable to stat: %s",tempName ); else if( S_ISDIR(fInfo.st_mode) ) { printf( "%d%*s%s\n", optS(tempName,followlinks), (indent*lvl)+1, " ", dInfo->d_name ); optA( tempName, indent, lvl+1, followlinks ); } else { printf( "%d%*s%s\n", (int)fInfo.st_blocks, (indent*lvl)+1, " ", dInfo->d_name ); total_size += (int)fInfo.st_blocks; } } } } closedir( pDir ); return 0; }
function optS.c
Code:
#include "du3.h" /************************************************ Function optS *************************************************/ int optS( char *dpath, int followlinks ) { DIR *pDir; struct dirent *dInfo; struct stat fInfo; char tempName[1000]; int 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 (followlinks) { if( (stat(tempName, &fInfo)) == -1 ) printf( "Unable to stat: %s", dInfo->d_name); else if( S_ISDIR(fInfo.st_mode) ) { blocksize += optS( tempName, followlinks ); } else { blocksize = blocksize + fInfo.st_blocks; } } else { if ((lstat(tempName,&fInfo)) == -1) printf( "Unable to lstat: %s\n", dInfo->d_name); else if( S_ISDIR(fInfo.st_mode) ) blocksize += optS (tempName, followlinks); else blocksize += fInfo.st_blocks; } } } closedir( pDir ); return blocksize; }
Function noOpt.c
Code:
#include "du3.h" int noOpt( char *dpath, int indent, int lvl, int followlinks ) { 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( followlinks ) { if( stat(tempName, &fInfo) == -1 ) printf( "Unable to stat: %s", tempName ); else if( S_ISDIR(fInfo.st_mode) ) { /* summerize(); */ printf( "%d%*s%s\n", (int)fInfo.st_blocks, (indent*lvl)+1, " ", dInfo->d_name ); noOpt( tempName, indent, lvl+1, followlinks ); } } else { if( lstat(tempName, &fInfo) == -1 ) printf( "Unable to stat: %s", tempName ); else if( S_ISDIR(fInfo.st_mode) ) { /* summerize(); */ printf( "%d%*s%s\n", (int)fInfo.st_blocks, (indent*lvl)+1, " ", dInfo->d_name ); noOpt( tempName, indent, lvl+1, followlinks ); } } } } return 0; }
function help.h
Code:
#include "du3.h" void help() { printf( "NAME\n\tdu3 - estimate block usage in tree format\n\n" ); printf( "SYNOPSIS\n\tdu [OPTION]... [FILE]...\n\n" ); printf( "DESCRIPTION\n\tDisplay block count of each FILE, recursively for directories.\n\n" ); printf( "\t-a\n\t\twrite block count for all files, not just directories\n\n" ); printf( "\t-s\n\t\twrite total block count\n\n" ); printf( "\t-t\n\t\tuse an indent of 3 to display tree\n\n" ); printf( "\t-i[n]\n\t\tuse an indent of 'n' to display tree\n\n" ); printf( "\t-L\n\t\tfollow symbolic links\n\n" ); printf( "\t-h\n\t\tdisplay thios help and exit\n\n" ); }
__________________
Deliverance is offline   Reply With Quote