mdfind 'kMDItemFSSize > 52428800'
mdfind "kMDItemFSSize > $[50*1024*1024]"
mdfind "kMDItemFSSize > $[100*1024*1024]"
df -ah
mount -v
diskutil list
diskutil info /
diskutil info disk0
/usr/bin/stat -x /
/usr/bin/stat -x /dev
/usr/bin/stat -x ~
/usr/bin/stat -x /Volumes/*
/usr/bin/stat -x /Volumes/* | sed -E "s/(Device)/$(printf '\e[1m\\1\e[m')/"
/usr/bin/stat -x /Volumes/* | sed -E "s/(Device: [[:digit:]]+,?[[:digit:]]* )/$(printf '\e[1m\\1\e[m')/"
/usr/bin/stat -x /Volumes/* | sed -E "s/(Device: [[:digit:],]+ )/$(printf '\e[1m\\1\e[m')/"
/usr/bin/stat -x / ~ /dev /Volumes /Volumes/* | sed -E "s/(File: .+$|Device: [[:digit:],]+ )/$(printf '\e[1m\\1\e[m')/" | nl
/usr/bin/stat -x / ~ /dev /Volumes /Volumes/* | sed -E -e "s/(File: .+)/$(printf '\e[1m\\1\e[m')/" -e "s/(Device: [[:digit:],]+ )/$(printf '\e[1;31m\\1\e[m')/" | nl
/usr/bin/stat -x /dev/* | sed -E "s/(File: .+$|Device: [[:digit:],]+ )/$(printf '\e[1m\\1\e[m')/" | nl
/usr/bin/stat -x /dev/* | sed -E -e "s/(File: .+)/$(printf '\e[1m\\1\e[m')/" -e "s/(Device: [[:digit:],]+ )/$(printf '\e[1;31m\\1\e[m')/" | nl
/usr/bin/find /dev | nl
/usr/bin/find /dev -not -type d | nl
/usr/bin/find -x /dev -not -type d | nl
/usr/bin/find -x /dev -not -type d -ls | nl
/usr/bin/sudo -H -i
/usr/bin/find / -not \( -type d -path '/dev' -prune \) -type f -size +$[50*1024*1024]c -ls 2>/dev/null | /usr/bin/sort -rn -k 7,7 | /usr/bin/head | /usr/bin/nl
/usr/bin/find -x / -type f -size +$[50*1024*1024]c -ls 2>/dev/null | /usr/bin/sort -rn -k 7,7 | /usr/bin/head | /usr/bin/nl
exit
/bin/df -l | /usr/bin/sed -E -e 1d -e 's/^([^ ]+[ ]+)[^\/]+//' | /usr/bin/sort -u
/bin/df -l | /usr/bin/sed -E -e 1d -e '/^\/dev\/disk0/!d' -e 's/^([^ ]+[ ]+)[^\/]+//' | /usr/bin/sort -u
/usr/bin/sudo -H -i
declare IFS=$'\n'
for volume in $(/bin/df -l | /usr/bin/sed -E -e 1d -e '/^\/dev\/disk0/!d' -e 's/^([^ ]+[ ]+)[^\/]+//' | /usr/bin/sort -u); do
echo
echo "... scanning volume: ${volume}"
/usr/bin/find -x "${volume}" -type f -size +$[50*1024*1024]c -ls 2>/dev/null | /usr/bin/sort -rn -k 7,7 | /usr/bin/head | /usr/bin/nl
done
declare IFS=$' \t\n'
exit
# store file paths of files > 50 MB in array (only skip /dev)
/usr/bin/sudo -H -i
man ruby | less -p 777
IFS=$'\777'
#array=( $(/usr/bin/find / -not \( -type d -path '/dev' -prune \) -type f -size +$[50*1024*1024]c -exec printf "%s\777" '{}' \; 2>/dev/null) )
array=( $(/usr/bin/find / -not \( -type d -path '/dev' -prune \) -type f -size +$[50*1024*1024]c -exec printf "%s\777" '{}' + 2>/dev/null) )
IFS=$' \t\n'
echo ${#array[@]}
printf "%s\n" "${array[@]}" | nl
echo "${array[0]}"
exit
# store all file paths of files > 50 MB on local hard drive in array (only scan local hard drive partitions)
/usr/bin/sudo -H -i
declare -a array tmparray
declare IFS=$'\n'
for volume in $(/bin/df -l | /usr/bin/sed -E -e 1d -e '/^\/dev\/disk0/!d' -e 's/^([^ ]+[ ]+)[^\/]+//' | /usr/bin/sort -u); do
echo
echo "... scanning volume: ${volume}"
IFS=$'\777'
#tmparray=( $(/usr/bin/find -x "${volume}" -type f -size +$[50*1024*1024]c -exec printf "%s\777" '{}' \; 2>/dev/null) )
#tmparray=( $(/opt/local/bin/gfind "${volume}" -xdev -type f -size +$[50*1024*1024]c -exec printf "%s\777" '{}' + 2>/dev/null) )
tmparray=( $(/usr/bin/find -x "${volume}" -type f -size +$[50*1024*1024]c -exec printf "%s\777" '{}' + 2>/dev/null) )
array=( "${array[@]}" "${tmparray[@]}" )
unset -v tmparray
declare -a tmparray
IFS=$'\n'
done
# this will truncate file paths containing spaces
printf "%s\000" "${array[@]}" | xargs -0 /usr/bin/stat -f $'%z\t\t%N' | sort -rn | awk '{print $1/(1024*1024.0),$2;}'
# this will truncate file paths containing newlines \n
printf "%s\000" "${array[@]}" | xargs -0 /usr/bin/stat -f $'%z\t\t%N' | sort -rn -k 1,1 -t $'\t' | \
awk -F $'\t' '{printf "MB: %-20s", $1/(1024*1024.0); for (i=2;i<NF+1;i++) {printf "%s",$i}; print ""}'
# encode newlines \n as NEWLINE
# cf. Sorting arrays in Bash, http://codesnippets.joyent.com/posts/show/1592
printf "%s\000\n" "${array[@]}" | sed -e :a -e '$!N; s/\n/NEWLINE/g; ta' | ruby -n -e 'p $_.to_s'
printf "%s\000\n" "${array[@]}" | sed -e :a -e '$!N; s/\n/NEWLINE/g; ta' | tr '\000' '\n' | ruby -n -e 'p $_.to_s'
printf "%s\000\n" "${array[@]}" | sed -e :a -e '$!N; s/\n/NEWLINE/g; ta' | tr '\000' '\n' | sed -e 's/^NEWLINE//' | ruby -n -e 'p $_.to_s'
printf "%s\000\n" "${array[@]}" | sed -e :a -e '$!N; s/\n/NEWLINE/g; ta' | tr '\000' '\n' | sed -e 's/^NEWLINE//' -e s/NEWLINE/$'\\\n'/ | ruby -n -e 'p $_.to_s'
# In the first two commands (printf, stat) use \000 and \777 to mark the end of each file path, then ... :
# - encode embedded newlines \n as NEWLINE (sed)
# - convert \777 into \n again (tr)
# - delete the last line (sed)
# - sort the resulting lines according to the first column of bytes (sort)
# - use awk to add line numbers and convert bytes into megabytes (awk)
# - and finally restore embedded newline characters in file paths (sed)
printf "%s\000" "${array[@]}" | xargs -0 /usr/bin/stat -n -f $'%z\t\t%N\777' | /usr/bin/sed -e :a -e '$!N; s/\n/NEWLINE/g; ta' | tr $'\777' $'\n' | sed '$d' | \
sort -rn -k 1,1 -t $'\t' | awk -F "\t" '{printf "%s\t%-20s", NR, $1/(1024*1024.0); for (i=2;i<NF+1;i++) {printf "%s",$i}; print ""}' | sed -e $'s/NEWLINE/\\\n/'
# same as previous command sequence except that the awk command (cf. ORS) marks the end of each file path with \777 again
printf "%s\000" "${array[@]}" | xargs -0 /usr/bin/stat -n -f $'%z\t\t%N\777' | /usr/bin/sed -e :a -e '$!N; s/\n/NEWLINE/g; ta' | tr $'\777' $'\n' | sed '$d' | \
sort -rn -k 1,1 -t $'\t' | awk -F "\t" -v ORS="\777" '{printf "%-20s", $1/(1024*1024.0); for (i=2;i<NF+1;i++) {printf "%s",$i}; print ""}' | sed -e $'s/NEWLINE/\\\n/'
# use the previous command sequence to read the sorted list of file paths into an array again
IFS=$'\777'
result=(
$(
printf "%s\000" "${array[@]}" | xargs -0 /usr/bin/stat -n -f $'%z\t\t%N\777' | /usr/bin/sed -e :a -e '$!N; s/\n/NEWLINE/g; ta' | tr $'\777' $'\n' | sed '$d' | \
sort -rn -k 1,1 -t $'\t' | awk -F "\t" -v ORS="\777" '{printf "%-20s", $1/(1024*1024.0); for (i=2;i<NF+1;i++) {printf "%s",$i}; print ""}' | sed -e $'s/NEWLINE/\\\n/'
)
)
IFS=$'\n'
# print sorted list of file sizes (in MB) with file paths
for ((i=0; i < ${#result[@]}; i++)); do printf "%-5s %s\n" "$[i+1]" "${result[${i}]}"; done
exit # sudo shell
#----------------------------------------------------------------------------------------------------
# ... testing weird file paths
mkfile 10m ${HOME}/Desktop/'te:st\file:'
# convert file sizes to megabyte with awk (> 1 MB)
/usr/bin/find -x ~/Desktop -type f -size +$[1*1024*1024]c -print0 2>/dev/null | xargs -0 stat -f "%z: %N" | \
sort -rn | awk -F: '{printf "%-20s", $1/(1024*1024.0); for (i=2;i<NF+1;i++) {printf "%s%s",$i,(i==NF) ? "\n" : ":"}}'
# find the 10 largest directories in the current directory
/usr/bin/find -x . -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 du -hs
/usr/bin/find -x . -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 du -ks | sort -rn | head
# awk: print the first field and from the second field to the end (just in case there are file paths with spaces)
/usr/bin/find -x . -mindepth 1 -maxdepth 1 -type d -print0 | xargs -0 du -ks | sort -rn | head | \
awk -F' ' '{printf "%-20s", $1/1024.0; for (i=2;i<NF+1;i++) {printf "%s ",$i}; print ""}'
#----------------------------------------------------------------------------------------------------
# sort file sizes & file paths containing newlines \n
# cf. Sorting arrays in Bash, http://codesnippets.joyent.com/posts/show/1592
mkfile 10m ${HOME}/Desktop/'te:st\file'.txt
mkfile 10m ${HOME}/Desktop/'te:st\file:'
mkfile 10m ${HOME}/Desktop/$'te:s\nt\\file:'
declare -a file_path_array
man ruby | less -p '777'
IFS=$'\777'
file_path_array=($(/usr/bin/find -x ~/Desktop -type f -size +$[1*1024*1024]c -print0 2>/dev/null | xargs -0 -n 500 printf "%s\777"))
IFS=$' \t\n'
echo "${#file_path_array[@]}"
echo "${file_path_array[@]}"
printf "%s\n" "${file_path_array[@]}" | ruby -n -e 'p $_.to_s'
declare -a file_path_array2
for ((i=0; i < "${#file_path_array[@]}"; i++)); do
mbyte=$(/usr/bin/stat -f "%z" "${file_path_array[$i]}" | awk '{print $1/(1024*1024.0);}')
file_path_array2[${i}]="${mbyte}: ${file_path_array[$i]}"
done
echo "${#file_path_array2[@]}"
echo "${file_path_array2[@]}"
IFS=$'\n'
declare -a file_path_array2_sorted
file_path_array2_sorted=( $(printf "%s\000\n" "${file_path_array2[@]}" | sed -e :a -e '$!N; s/\n/NEWLINE/g; ta' | tr '\000' '\n' | \
sed -e 's/^NEWLINE//' | sort -rn -t . -k 1,1 -k 2,2) )
IFS=$' \t\n'
for ((i=0; i < "${#file_path_array2_sorted[@]}"; i++)); do printf "%s\n" "${file_path_array2_sorted[$i]//NEWLINE/$'\n'}"; done | nl
for ((i=0; i < "${#file_path_array2_sorted[@]}"; i++)); do printf "%s\n" "${file_path_array2_sorted[$i]//NEWLINE/\n}"; done | nl
for ((i=0; i < "${#file_path_array2_sorted[@]}"; i++)); do
printf "%s" "${file_path_array2_sorted[$i]//NEWLINE/\n}" | ruby -0777 -n -e 'p $_.to_s'
done | nl
#----------------------------------------------------------------------------------------------------
# alternative
declare -i i=0
declare -a file_path_array
while read -d $'\000' filepath; do
mbyte=$(/usr/bin/stat -f "%z" "${filepath}" | awk '{print $1/(1024*1024.0);}')
file_path_array[${i}]="${mbyte}: ${filepath}"
let i++
done < <(/usr/bin/find -x ~/Desktop -type f -size +$[1*1024*1024]c -print0 2>/dev/null | sed -E '/\\/s/\\/\\\\/g')
IFS=$'\n'
declare -a file_path_array_sorted
file_path_array_sorted=( $(printf "%s\000\n" "${file_path_array[@]}" | sed -e :a -e '$!N; s/\n/NEWLINE/g; ta' | tr '\000' '\n' | \
sed -e 's/^NEWLINE//' | sort -rn -t . -k 1,1 -k 2,2) )
IFS=$' \t\n'
for ((i=0; i < "${#file_path_array_sorted[@]}"; i++)); do printf "%s\n" "${file_path_array_sorted[$i]//NEWLINE/$'\n'}"; done | nl
for ((i=0; i < "${#file_path_array_sorted[@]}"; i++)); do printf "%s\n" "${file_path_array_sorted[$i]//NEWLINE/\n}"; done | nl
for ((i=0; i < "${#file_path_array_sorted[@]}"; i++)); do
printf "%s" "${file_path_array_sorted[$i]//NEWLINE/\n}" | ruby -0777 -n -e 'p $_.to_s'
done | nl
#----------------------------------------------------------------------------------------------------
# same for directory paths containing possible newlines \n
declare -i i=0
declare -a dir_path_array
while read -d $'\000' dirpath; do
dir_size=$(/usr/bin/du -ks "${dirpath}" | /usr/bin/awk '/^[[:digit:]]+/{print $1/1024.0}')
dir_path_array[${i}]="${dir_size} ${dirpath}"
let i++
done < <(/usr/bin/find -x . -mindepth 1 -maxdepth 1 -type d -print0 2>/dev/null | sed -E '/\\/s/\\/\\\\/g')
echo "${#dir_path_array[@]}"
echo "${dir_path_array[@]}"
printf "%s\n" "${dir_path_array[@]}" | ruby -n -e 'p $_.to_s'
IFS=$'\n'
declare -a dir_path_array_sorted
dir_path_array_sorted=( $(printf "%s\000\n" "${dir_path_array[@]}" | sed -e :a -e '$!N; s/\n/NEWLINE/g; ta' | tr '\000' '\n' | \
sed -e 's/^NEWLINE//' | sort -rn -t . -k 1,1 -k 2,2) )
IFS=$' \t\n'
for ((i=0; i < "${#dir_path_array_sorted[@]}"; i++)); do printf "%s\n" "${dir_path_array_sorted[$i]//NEWLINE/$'\n'}"; done | nl
for ((i=0; i < "${#dir_path_array_sorted[@]}"; i++)); do printf "%s\n" "${dir_path_array_sorted[$i]//NEWLINE/\n}"; done | nl
for ((i=0; i < "${#dir_path_array_sorted[@]}"; i++)); do
printf "%s" "${dir_path_array_sorted[$i]//NEWLINE/\n}" | ruby -0777 -n -e 'p $_.to_s'
done | nl
#----------------------------------------------------------------------------------------------------
# get file sizes via ls command
ls -alS
ls -alSr
ls -ahlS
ls -ahlSr
ls -alSrR
#----------------------------------------------------------------------------------------------------
# bigfiles (see below)
# scan local hard disk (/dev/disk0*)
IFS=$'\n'
bigfiles -v -m 10 $(/bin/df -l | /usr/bin/sed -E -e 1d -e '/^\/dev\/disk0/!d' -e 's/^([^ ]+[ ]+)[^\/]+//' | /usr/bin/sort -u)
IFS=$' \t\n'
IFS=$'\777'
bigfiles $(localvols -7) # localvols (see below)
IFS=$' \t\n'
bigfiles.c:
/*
*
* bigfiles -- list big files in given directories
*
* License: The MIT License, http://www.opensource.org/licenses/mit-license.php
* Copyright (c) 2009 jv
*
* compile with: gcc -std=c99 -Wall -Wextra -pedantic -O3 -o bigfiles bigfiles.c
*
* For how to implement recursive directory scanning please see:
* "fts(3) or Avoiding to Reinvent the Wheel",
* http://keramida.wordpress.com/2009/07/05/fts3-or-avoiding-to-reinvent-the-wheel/
*
*
* man 2 stat:
*
* struct stat {
* ...
* off_t st_size; // file size, in bytes
* ...
* }
*
*
* egrep -Irs --color 'typedef.*[[:space:]]off_t([[:space:];]|$)' /usr/include
* egrep -Irs --color 'typedef.*[[:space:]]__darwin_off_t([[:space:];]|$)' /usr/include
* egrep -Irs --color 'typedef.*[[:space:]]__int64_t([[:space:];]|$)' /usr/include
*
* typedef __darwin_off_t off_t;
* typedef __int64_t __darwin_off_t; // [???] Used for file sizes
* typedef long long __int64_t;
*
*
*
* usage example to scan local hard disk:
* IFS=$'\n'
* ~/Desktop/bigfiles -v -m 10 $(/bin/df -l | /usr/bin/sed -E -e 1d -e '/^\/dev\/disk0/!d' -e 's/^([^ ]+[ ]+)[^\/]+//' | /usr/bin/sort -u)
* IFS=$' \t\n'
*
*
*/
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fts.h>
#include <unistd.h> // getopt
#include <limits.h> // PATH_MAX
#define MAX_FILEPATH_LENGTH 2 * PATH_MAX // 2048 (in 2009)
#define STRUCTS_IN_ARRAY 15000
static int ptree(char * const argv[], int argc, int megabytes, unsigned long long int print, int printfid, int verbose);
static void usage()
{
static char const *usageinfo[] = {
"bigfiles -- list big files in given directories",
"Usage:",
"bigfiles [-0] [-7] [-hv] [-m mbytes] [-n num] [ [dir1] [dir2] ...]",
"-0: print each item to stdout in the following format: size\\777path\\777\\000",
"-7: print each item to stdout in the following format: size\\777path\\777",
"-h: help",
"-m: megabytes (default: 50, min size: 2)",
"-n: print n items (file size in MB & file path; default: 20)",
"-n 0: print all items",
"-v: verbose",
"Note:",
"- Files named '.' or '..' get scanned.",
"- File search will not descend into directories that have a different device number than the file from which the descent began.",
"- fts_options: FTS_COMFOLLOW | FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV | FTS_SEEDOT (see man 3 fts)"
};
fprintf(stderr, "\n%s\n\n%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n",
usageinfo[0], usageinfo[1], usageinfo[2], usageinfo[3], usageinfo[4],
usageinfo[5], usageinfo[6], usageinfo[7], usageinfo[8], usageinfo[9],
usageinfo[10], usageinfo[11], usageinfo[12], usageinfo[13]
);
}
int main(int argc, char * const argv[])
{
int megabytes = 50;
unsigned long long int print = 20;
int verbose = 0;
int printfid = 10; // defaults to newline character \n; cf. man ascii (decimal set)
if ( argc == 1 ) { usage(); return 0; }
int ch;
while ((ch = getopt(argc, (char **)argv, "m:n:07hv")) != -1)
{
switch (ch)
{
case '0':
printfid = 0;
break;
case '7':
printfid = 7;
break;
case 'h':
usage();
return 0;
case 'm':
megabytes = atoi(optarg);
break;
case 'n':
print = atoi(optarg);
break;
case 'v':
verbose = 1;
break;
case '?':
default:
usage();
return 1;
}
}
argc -= optind;
argv += optind;
if ( megabytes < 2 )
megabytes = 2;
int rc;
if ((rc = ptree(argv, argc, megabytes, print, printfid, verbose)) != 0)
rc = 1;
return rc;
}
void copystr (char *srcstr, char *tgtstr)
{
while ( *srcstr ) { *tgtstr++ = *srcstr++; }
*tgtstr = '\0';
}
struct file_size_path
{
unsigned long long int file_size;
char *file_path;
};
// VLA (variable length array) in C99
// For some VLA links see: Xcode now defaults to use C99 - so what's C99?,
// http://www.cocoabuilder.com/archive/message/xcode/2008/5/30/21989
struct file_size_path array_file_size_path[STRUCTS_IN_ARRAY];
// qsort / mergesort struct comparison function (file_size field)
int struct_cmp_by_filesize(const void *a, const void *b)
{
struct file_size_path *ia = (struct file_size_path *)a;
struct file_size_path *ib = (struct file_size_path *)b;
// return 1 or -1 if file_size members are not equal
//if (ia->file_size > ib->file_size) return 1;
//if (ia->file_size < ib->file_size) return -1;
if (ia->file_size < ib->file_size) return 1;
if (ia->file_size > ib->file_size) return -1;
// return 0 if file_size members are equal
return 0;
}
// struct array printing function
void print_struct_array(struct file_size_path *array, unsigned long long int nitems, int printfid)
{
unsigned long long int i;
for(i=0; i < nitems; i++)
{
switch (printfid)
{
case 0:
printf("%llu\777%s\777", array[i].file_size, array[i].file_path);
putchar(0);
break;
case 7:
printf("%llu\777%s\777", array[i].file_size, array[i].file_path);
break;
case 10:
printf("%-12llu %s\n", array[i].file_size, array[i].file_path);
break;
default:
break;
}
}
}
static int ptree(char * const argv[], int argc, int megabytes, unsigned long long int print, int printfid, int verbose)
{
int i = 0;
unsigned long long int x = 0;
long long int bytes = megabytes * 1024 * 1024;
unsigned long long int print_n_items = print;
void copystr (char *srcstr, char *tgtstr);
char filepathstr[MAX_FILEPATH_LENGTH];
unsigned long long int file_count = 0;
unsigned long long int array_index = 0;
unsigned long long int number_of_array_items = 0;
FTS *ftsp;
FTSENT *p, *chp;
//int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR | FTS_SEEDOT;
//int fts_options = FTS_COMFOLLOW | FTS_LOGICAL | FTS_NOCHDIR | FTS_XDEV | FTS_SEEDOT;
int fts_options = FTS_COMFOLLOW | FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV | FTS_SEEDOT;
int rval;
rval = 0;
if ((ftsp = fts_open(argv, fts_options, NULL)) == NULL)
{
warn("fts_open");
return -1;
}
// Initialize ftsp with as many argv[] parts as possible.
chp = fts_children(ftsp, 0);
//if (chp == NULL) return 0; // no files to traverse
if (chp == NULL)
{
fprintf(stderr, "No files to traverKKKse. See -h option. Exiting ...\n");
return 1;
}
while ((p = fts_read(ftsp)) != NULL)
{
switch (p->fts_info)
{
/*
// cf. man 3 fts
case FTS_DNR:
//printf("directory which cannot be read: %s\n", p->fts_path);
break;
case FTS_DC:
//printf("directory that causes a cycle in the tree: %s\n", p->fts_path);
break;
case FTS_D:
//printf("directory: %s\n", p->fts_path);
break;
case FTS_SLNONE:
//printf("symbolic link with a non-existent target: %s\n", p->fts_path);
break;
case FTS_SL:
//printf("symbolic link: %s\n", p->fts_path);
break;
*/
case FTS_F:
file_count++;
if ( p->fts_statp->st_size < bytes ) break; // ignore files < bytes
// convert bytes to megabytes
array_file_size_path[array_index].file_size = p->fts_statp->st_size / (1024*1024);
//printf("path: %s\n", p->fts_path);
//printf("size: %jd\n", (intmax_t)p->fts_statp->st_size);
copystr(p->fts_path, filepathstr);
array_file_size_path[array_index].file_path = calloc( strlen(filepathstr) + 1, sizeof(char) );
if (array_file_size_path[array_index].file_path == NULL) exit(1);
strcpy(array_file_size_path[array_index].file_path, filepathstr);
array_index++; // we will increment array_index one too many here in the last while loop
break;
default:
break;
} // switch
} // while
fts_close(ftsp);
if (array_index == 0)
{
printf("\nNo files found.\nSee -h option to modify search parameters.\n\n");
if (verbose == 1)
{
printf("\nSearching for files larger than: %i MB\n", megabytes);
printf("\nPrint %llu sorted items (file size in MB & file path).\n", print_n_items);
printf("\nNumber of files scanned: %llu\n", file_count);
printf("\nNumber of files found: %llu\n", array_index);
printf("\nDirectories scanned:\n\n");
for(i=0; i < argc; i++)
{
printf("%i: %s\n", i+1, argv[i]);
}
printf("\n\n\n");
}
return 0;
}
number_of_array_items = array_index;
array_index = number_of_array_items - 1;
size_t structs_len = number_of_array_items;
//size_t structs_len = sizeof(array_file_size_path) / sizeof(struct file_size_path);
// sort array using qsort functions
//qsort(array_file_size_path, structs_len, sizeof(struct file_size_path), struct_cmp_by_filesize);
mergesort(array_file_size_path, structs_len, sizeof(struct file_size_path), struct_cmp_by_filesize);
if ( (print_n_items == 0) || (print_n_items > number_of_array_items) )
print_n_items = number_of_array_items;
if (verbose == 1)
{
printf("\nSearching for files larger than: %i MB\n", megabytes);
printf("\nPrint %llu sorted items (file size in MB & file path).\n", print_n_items);
printf("\nNumber of files scanned: %llu\n", file_count);
printf("\nNumber of files found: %llu\n", number_of_array_items);
printf("\nDirectories scanned:\n\n");
for(i=0; i < argc; i++)
{
printf("%i: %s\n", i+1, argv[i]);
}
printf("\n\n\n");
}
// print sorted struct array
print_struct_array(array_file_size_path, print_n_items, printfid);
// free memory
for( x=0; x < number_of_array_items; x++ )
{
//memset(array_file_size_path[x].file_path, 0, sizeof(array_file_size_path[x].file_path));
//memset(array_file_size_path[x].file_path, 0, strlen(array_file_size_path[x].file_path) + 1);
bzero(array_file_size_path[x].file_path, sizeof(array_file_size_path[x].file_path));
free (array_file_size_path[x].file_path);
}
return 0;
} // ptree
localvols.c:
// localvols - list local hfs & ufs volumes (file systems) on Mac OS X
// License: The MIT License, http://www.opensource.org/licenses/mit-license.php
// Copyright (c) 2009 jv
// compile with: gcc -Wall -O3 -o localvols localvols.c
static void usage()
{
static char const *usageinfo[] = {
"localvols -- list locally mounted hfs & ufs volumes (file systems) on Mac OS X",
"Usage:",
"localvols [-0] [-7] [-afhu]",
"-0: print volume paths to stdout in the following format: vol1\\000vol2\\000vol3\\000 (-print0)",
"-7: print volume paths to stdout in the following format: vol1\\777vol2\\777vol3\\777 (-print7)",
"-a: list all locally mounted hfs & ufs file systems",
"-f: list all locally mounted hfs file systems only",
"-h: help",
"-u: list all locally mounted ufs file systems only",
"Note:",
"- file systems: hfs, ufs",
"- default: list the local hard drive disk partitions mounted on /Volumes/*",
"Examples:",
"localvols",
"localvols -7 | ruby -0777 -n -e 'p $_.to_s'",
"IFS=$'\\777'",
"lvols=( $(localvols) )",
"IFS=$' \\t\\n'",
"echo \"${lvols[0]}\"",
"echo \"${lvols[1]}\"",
"echo \"${lvols[@]}\"",
"IFS=$'\\777'",
"bigfiles $(localvols -7)",
"IFS=$' \\t\\n'"
};
fprintf(stderr, "\n%s\n\n%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n\t%s\n\n\n%s\n\n\t%s\n\n\t%s\n\n\
\n%s\n\n\t%s\n\n\t%s\n\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n\n\t%s\n\t%s\n\t%s\n\n",
usageinfo[0], usageinfo[1], usageinfo[2], usageinfo[3], usageinfo[4],
usageinfo[5], usageinfo[6], usageinfo[7], usageinfo[8], usageinfo[9],
usageinfo[10], usageinfo[11], usageinfo[12], usageinfo[13], usageinfo[14],
usageinfo[15], usageinfo[16], usageinfo[17], usageinfo[18], usageinfo[19],
usageinfo[20], usageinfo[21], usageinfo[22], usageinfo[23]
);
}
void printfid_function(int printfid, const char * volpath)
{
switch (printfid)
{
case 0:
printf("%s", volpath);
putchar(0);
break;
case 7:
//printf("%s\777", volpath);
printf("%s", volpath);
putchar('\777');
break;
case 10:
printf("%s\n", volpath);
break;
default:
break;
}
}
int main(int argc, const char **argv)
{
struct statfs *mountlist;
int ch, n, i;
int all = 0;
int all_hfs = 0;
int all_ufs = 0;
int printfid = 10; // defaults to newline character \n; cf. man ascii (decimal set)
while ((ch = getopt(argc, (char **)argv, "07afhu")) != -1)
{
switch (ch)
{
case '0':
printfid = 0;
break;
case '7':
printfid = 7;
break;
case 'a':
all = 1;
break;
case 'f':
all_hfs = 1;
break;
case 'h':
usage();
return 0;
case 'u':
all_ufs = 1;
break;
case '?':
default:
usage();
return 1;
}
}
argc -= optind;
argv += optind;
if (argc > 0) { usage(); return 1; }
//n = getmntinfo(&mountlist, 0);
//n = getmntinfo(&mountlist, MNT_NOWAIT);
n = getmntinfo(&mountlist, MNT_WAIT); // see man 3 getmntinfo and man 2 getfsstat
if (n < 0)
{
fprintf(stderr, "getmntinfo failed: %s\n", strerror(errno));
exit(1);
}
if (all == 1)
{
for(i=0; i<n; i++)
{
if ( ( (mountlist[i].f_flags & MNT_LOCAL) == MNT_LOCAL ) &&
( (strcmp(mountlist[i].f_fstypename, "hfs") == 0) || (strcmp(mountlist[i].f_fstypename, "ufs") == 0) )
)
{
printfid_function(printfid, mountlist[i].f_mntonname);
}
}
return 0;
}
if (all_hfs == 1)
{
for(i=0; i<n; i++)
{
if ( ((mountlist[i].f_flags & MNT_LOCAL) == MNT_LOCAL ) && (strcmp(mountlist[i].f_fstypename, "hfs") == 0) )
{
printfid_function(printfid, mountlist[i].f_mntonname);
}
}
return 0;
}
if (all_ufs == 1)
{
for(i=0; i<n; i++)
{
if ( ((mountlist[i].f_flags & MNT_LOCAL) == MNT_LOCAL ) && (strcmp(mountlist[i].f_fstypename, "ufs") == 0) )
{
printfid_function(printfid, mountlist[i].f_mntonname);
}
}
return 0;
}
// default
// get the device node entry (/dev/disk*, 10 characters) of the root path /
// see: man 8 diskutil | less -p DEVICES
char root_path_device_node[11]; // can store up to 11 chars; the last index: 10 is used for the terminating '\0' char below
//printf("%s\n", root_path_device_node);
//printf("sizeof(root_path_device_node): %zu\n", sizeof(root_path_device_node));
for(i=0; i<n; i++)
{
if ( (strcmp(mountlist[i].f_mntonname, "/") == 0) )
{
strncpy(root_path_device_node, mountlist[i].f_mntfromname, 10);
root_path_device_node[10] = '\0';
break;
}
}
for(i=0; i<n; i++)
{
if (
( (mountlist[i].f_flags & MNT_LOCAL) == MNT_LOCAL ) &&
( (strcmp(mountlist[i].f_fstypename, "hfs") == 0) || (strcmp(mountlist[i].f_fstypename, "ufs") == 0) ) &&
(strncmp(mountlist[i].f_mntfromname, root_path_device_node, 10) == 0) &&
( (strcmp(mountlist[i].f_mntonname, "/") == 0) || (strncmp(mountlist[i].f_mntonname, "/Volumes/", 9) == 0) )
)
{
printfid_function(printfid, mountlist[i].f_mntonname);
} // if
} // for
return 0;
}