2023-10-21 15:05:49 +03:00
# include <stdio.h>
# include <errno.h>
# include <string.h>
# include <stdlib.h>
# include <unistd.h>
# include <dirent.h>
2023-10-31 12:53:32 +03:00
# include "get_stat.h"
# include "make_path.h"
2023-10-21 15:05:49 +03:00
unsigned int h_flag ;
unsigned int s_flag ;
unsigned int b_flag ;
unsigned int m_flag ;
2023-10-29 12:27:44 +03:00
void print ( double size , const char * filename ) {
char c = 0 ;
if ( h_flag ) {
2023-11-05 18:45:11 +03:00
if ( size < 1048576 & & ! m_flag ) {
2023-11-05 18:31:17 +03:00
size = size / 1024 ;
2023-10-29 12:27:44 +03:00
c = ' K ' ;
2023-11-05 18:31:17 +03:00
}
2023-10-29 12:27:44 +03:00
else if ( size < 1073741824 ) {
size = size / 1048576 ;
c = ' M ' ;
}
else if ( size < 1099511627776 ) {
size = size / 1073741824 ;
c = ' G ' ;
}
}
2023-10-21 15:05:49 +03:00
/* Kb */
2023-10-29 12:27:44 +03:00
else if ( ! b_flag )
2023-10-21 15:05:49 +03:00
size = size / 1024 ;
/* Mb */
else if ( m_flag )
size = size / 1048576 ;
2023-11-05 18:31:17 +03:00
printf ( " %.1f%c %s \n " , size , c , filename ) ;
2023-10-21 15:05:49 +03:00
}
2023-10-29 12:27:44 +03:00
double du ( const char * path , int recurs_flag ) {
double sum = 0 ;
2023-10-21 15:05:49 +03:00
struct stat sb ;
2023-10-31 12:53:32 +03:00
if ( mu_get_lstat ( " du " , path , & sb ) )
2023-11-06 23:52:48 +03:00
return 0 ;
2023-10-21 15:05:49 +03:00
if ( S_ISDIR ( sb . st_mode ) ) {
DIR * dp = opendir ( path ) ;
if ( ! dp ) {
fprintf ( stderr , " du: %s \n " , strerror ( errno ) ) ;
return 0 ;
}
struct dirent * ep ;
while ( ( ep = readdir ( dp ) ) ! = NULL ) {
if ( ! strcmp ( ep - > d_name , " . " ) | | ! strcmp ( ep - > d_name , " .. " ) )
continue ;
2023-10-31 12:53:32 +03:00
char * new_path = mu_make_path ( " du " , path , ep - > d_name ) ;
2023-10-21 15:05:49 +03:00
if ( new_path = = NULL )
2023-11-06 23:52:48 +03:00
return 0 ;
2023-10-21 15:05:49 +03:00
2023-10-21 15:27:42 +03:00
sum + = du ( new_path , 1 ) ;
2023-10-21 15:05:49 +03:00
free ( new_path ) ;
}
closedir ( dp ) ;
2023-10-21 15:27:42 +03:00
2023-10-21 16:02:07 +03:00
if ( ! s_flag & & recurs_flag ) {
print ( sum , path ) ;
return sum ;
2023-10-21 15:27:42 +03:00
}
2023-10-21 16:02:07 +03:00
/* Silent mode */
else if ( ! recurs_flag )
2023-10-21 15:27:42 +03:00
print ( sum , path ) ;
2023-10-21 15:05:49 +03:00
}
2023-10-21 15:27:42 +03:00
else {
sum = sb . st_size ;
if ( ! recurs_flag )
print ( sum , path ) ;
}
2023-10-21 15:05:49 +03:00
return sum ;
}
2023-11-06 23:52:48 +03:00
int main ( int argc , char * * argv ) {
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
int opt ;
while ( ( opt = getopt ( argc , argv , " hsbm " ) ) ! = - 1 ) {
switch ( opt ) {
case ' h ' :
h_flag = 1 ;
break ;
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
case ' s ' :
s_flag = 1 ;
break ;
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
case ' b ' :
b_flag = 1 ;
break ;
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
case ' m ' :
b_flag = 1 ;
m_flag = 1 ;
break ;
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
default :
2023-11-07 16:21:46 +03:00
printf ( " du [file1 file2...] \n \t [-h Sizes in human readable format] \n \t [-s Display only a total for each argument] \n \t [-b Apparent size] [-m Size in megabyte] \n " ) ;
2023-11-06 23:52:48 +03:00
return 0 ;
2023-10-21 15:05:49 +03:00
}
}
2023-11-06 23:52:48 +03:00
if ( argv [ optind ] = = NULL )
2023-10-21 15:27:42 +03:00
du ( " . " , 0 ) ;
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
else {
argv + = optind ;
argc - = optind ;
for ( int i = 0 ; i < argc ; i + + )
2023-10-21 15:27:42 +03:00
du ( argv [ i ] , 0 ) ;
2023-10-21 15:05:49 +03:00
2023-11-06 23:52:48 +03:00
}
2023-10-21 15:05:49 +03:00
return 0 ;
}
2023-11-06 23:52:48 +03:00