|
C++ Beginner
Join Date: Jul 2005
Location: Ottawa
Posts: 73
|
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" );
}
__________________
|