Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums
Go Back   Code Forums > Application and Web Development > Standard C, C++
User Name
Password

Reply
 
LinkBack Thread Tools Display Modes
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
Old 10-03-2006, 01:21 PM   #2 (permalink)
Deliverance
C++ Beginner
 
Join Date: Jul 2005
Location: Ottawa
Posts: 73
Deliverance is on a distinguished road
Almost got it finished, there's just a few bugs, I'll post my solution within a few days
__________________
Deliverance is offline   Reply With Quote
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
Old 12-03-2006, 08:56 PM   #4 (permalink)
albtross
Recruit
 
Join Date: Nov 2006
Posts: 9
albtross is on a distinguished road
nice programs there, however it differs from what real du command outputs, i made a modification which matches what du command output, however, it only includes one -k option. now it takes a file or a directory. also, it can take no argument which by default it will be current directory, and it takes -k option which only display half size. lastly, i includes a small feature which when the sub directories go beyond 4 it will stop and print message, because we don't want to print a very unacceptable long path directory info.
Code:
#define NONE 0 #define ALL 1 #define SUM 2 #define F 3 #define G 4 #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> #include <errno.h> int optS( char* ); int noOpt( char*, int,char* ); int optK(char* , int,char*); int fopt( char* ); int main( int argc, char *argv[] ) { int c,type=NONE,lvl=0,blocksize=0; char ck[1000]; struct stat info; if (argc ==1) /* no argument */ {type = ALL;} if (argc ==2) { strcpy(ck, argv[1]); if(lstat(ck, &info) < 0) {printf( "Unable to stat: %s \n", ck); exit(1);} if(S_ISDIR(info.st_mode) == 0) /* it's a file */ { type = F; } } while( (c = getopt(argc, argv, "+k")) != -1 ) /*take option */ { switch( c ) { case 'k': /* option k */ strcpy(ck, argv[2]); if(lstat(ck, &info) < 0) {printf( "Unable to stat: %s \n", ck); exit(1);} if(S_ISDIR(info.st_mode) == 0) /* if it's a file */ {type = G;} else if( type == NONE ) type = SUM; else { return EXIT_FAILURE; } break; default: return EXIT_FAILURE; } } switch( type ) { case ALL: noOpt(".", lvl,NULL); /*no argument, so current dir is default setting*/ break; case SUM: while( optind < argc ) /*directory is taking option -k */ optK( argv[optind++], lvl, NULL ); break; case NONE: while( optind < argc ) /* normal one argument, directory*/ noOpt( argv[optind++], lvl,NULL ); break; case F: while( optind < argc ) /*argument is a file*/ { if( (blocksize=fopt(argv[optind])) != -1 ) printf( "%d%s%s\n", blocksize, "\t ", argv[optind++] ); } break; case G: while( optind < argc ) /*argument is a file and take -k option*/ { if( (blocksize=fopt(argv[optind])) != -1 ) printf( "%d%s%s\n", blocksize/2, "\t ", argv[optind++] ); } break; } return EXIT_SUCCESS; } /************************************************ Function optS calculate total blocksize and return value *************************************************/ int optS( char *dpath ) { DIR *pDir; struct dirent *dInfo; struct stat fInfo; char tempName[1000]; int blocksize = 0; if( (pDir = opendir(dpath)) == NULL) /*see if can stat or not*/ { perror("cannot open"); return 0; } while( (dInfo=readdir(pDir)) != NULL ) { if( strcmp(dInfo->d_name, ".") != 0 && strcmp(dInfo->d_name, "..") != 0 ) /*ignore .. and . */ { strcpy( tempName, dpath ); strcat( tempName, "/" ); strcat( tempName, dInfo->d_name ); if ((lstat(tempName,&fInfo)) == -1) printf( "Unable to lstat: %s\n", dInfo->d_name); else if( S_ISDIR(fInfo.st_mode) ) /*accumulate size and add directory size*/ {blocksize += fInfo.st_blocks; blocksize += optS (tempName);} else blocksize += fInfo.st_blocks; /*accumulate blocksize*/ } } closedir( pDir ); return blocksize; } /************************************************ function noOpt normal directory argument ************************************************/ int noOpt( char *dpath, int lvl,char *temp ) { DIR *pDir; struct dirent *dInfo; struct stat fInfo; char tempName[1000],tempchar[1000]; if( (pDir = opendir(dpath)) == NULL ) { perror("cannot open"); 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( lstat(tempName, &fInfo) == -1 ) printf( "Unable to stat: %s \n", tempName ); else if( S_ISDIR(fInfo.st_mode) ) /*if it's a nested directory loop through*/ { strcpy(tempchar, dInfo->d_name); if ( lvl > 2) /*set up a counter to monitor how many directory go through*/ {printf("encounter a deep path unable to print : %s.\n",temp);/*print message*/ return 0; } noOpt( tempName, lvl+1,tempchar ); } } } printf("%d%s%s\n", 2+optS(dpath), "\t", dpath); /* print final outcome for every loop*/ return 0; } /************************************************** function optK take directory as argument and take -k option **************************************************/ int optK(char *dpath, int lvl,char *temp ) { DIR *pDir; struct dirent *dInfo; struct stat fInfo; char tempName[1000], tempchar[1000]; if( (pDir = opendir(dpath)) == NULL ) { perror("cannot open"); 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( lstat(tempName, &fInfo) == -1 ) printf( "Unable to stat: %s \n", tempName ); else if( S_ISDIR(fInfo.st_mode) ) { strcpy(tempchar, dInfo->d_name); if ( lvl > 2) /*set up a counter to monitor how many directory go through*/ {printf("encounter a deep path unable to print : %s.\n",temp);/*print message*/ return 0; } /*loop through all directory inside */ optK( tempName, lvl+1,tempchar); } } } lvl = 0; /* clear it after loop*/ printf("%d%s%s\n", (2+optS(dpath))/2, "\t", dpath); /*the size is half of regular*/ return 0; } /************************************************ function fopt take argument as file *************************************************/ int fopt(char *dpath) { char tempName[1000]; int blocksize = 0; struct stat fInfo; strcpy( tempName, dpath ); if ((lstat(tempName,&fInfo)) == -1) printf( "Unable to lstat: %s\n", tempName); else blocksize = fInfo.st_blocks; return blocksize; }
__________________
albtross is offline   Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to use legacy C code in a C# application otakuj462 MS Technologies ( ASP, VB, C#, .NET ) 2 09-22-2005 07:18 PM
Some questions about C fp_unit Standard C, C++ 3 08-14-2005 06:22 PM
Kaat a talking bot in c nvictor Platform/API C++ 10 05-19-2005 01:16 PM
Starting out with C anon C 0 02-24-2003 01:06 PM
edit? anon Lounge 10 11-21-2002 03:02 PM


All times are GMT -8. The time now is 06:05 PM.


Powered by vBulletin Version 3.6.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0 RC8





Copyright © 2000-2006, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting
Open Circle