164a82bcdSEnji Cooper# 264a82bcdSEnji Cooper# Copyright (c) 2017 Dell EMC 364a82bcdSEnji Cooper# All rights reserved. 464a82bcdSEnji Cooper# 564a82bcdSEnji Cooper# Redistribution and use in source and binary forms, with or without 664a82bcdSEnji Cooper# modification, are permitted provided that the following conditions 764a82bcdSEnji Cooper# are met: 864a82bcdSEnji Cooper# 1. Redistributions of source code must retain the above copyright 964a82bcdSEnji Cooper# notice, this list of conditions and the following disclaimer. 1064a82bcdSEnji Cooper# 2. Redistributions in binary form must reproduce the above copyright 1164a82bcdSEnji Cooper# notice, this list of conditions and the following disclaimer in the 1264a82bcdSEnji Cooper# documentation and/or other materials provided with the distribution. 1364a82bcdSEnji Cooper# 1464a82bcdSEnji Cooper# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1564a82bcdSEnji Cooper# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1664a82bcdSEnji Cooper# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1764a82bcdSEnji Cooper# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1864a82bcdSEnji Cooper# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1964a82bcdSEnji Cooper# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2064a82bcdSEnji Cooper# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2164a82bcdSEnji Cooper# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2264a82bcdSEnji Cooper# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2364a82bcdSEnji Cooper# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2464a82bcdSEnji Cooper# SUCH DAMAGE. 2564a82bcdSEnji Cooper# 2664a82bcdSEnji Cooper 2764a82bcdSEnji Cooperatf_test_case F_flag 2864a82bcdSEnji CooperF_flag_head() 2964a82bcdSEnji Cooper{ 3064a82bcdSEnji Cooper atf_set "descr" "Verify the output format for -F" 3164a82bcdSEnji Cooper} 3264a82bcdSEnji CooperF_flag_body() 3364a82bcdSEnji Cooper{ 3464a82bcdSEnji Cooper # TODO: socket, whiteout file 3564a82bcdSEnji Cooper atf_check touch a 3664a82bcdSEnji Cooper atf_check mkdir b 3764a82bcdSEnji Cooper atf_check install -m 0777 /dev/null c 3864a82bcdSEnji Cooper atf_check ln -s a d 3964a82bcdSEnji Cooper atf_check mkfifo f 4064a82bcdSEnji Cooper 4164a82bcdSEnji Cooper atf_check -o match:'.* a' stat -Fn a 4264a82bcdSEnji Cooper atf_check -o match:'.* b/' stat -Fn b 4364a82bcdSEnji Cooper atf_check -o match:'.* c\*' stat -Fn c 4464a82bcdSEnji Cooper atf_check -o match:'.* d@' stat -Fn d 4564a82bcdSEnji Cooper atf_check -o match:'.* f\|' stat -Fn f 4664a82bcdSEnji Cooper} 4764a82bcdSEnji Cooper 4864a82bcdSEnji Cooperatf_test_case l_flag 4964a82bcdSEnji Cooperl_flag_head() 5064a82bcdSEnji Cooper{ 5164a82bcdSEnji Cooper atf_set "descr" "Verify the output format for -l" 5264a82bcdSEnji Cooper} 5364a82bcdSEnji Cooperl_flag_body() 5464a82bcdSEnji Cooper{ 5564a82bcdSEnji Cooper atf_check touch a 5664a82bcdSEnji Cooper atf_check ln a b 5764a82bcdSEnji Cooper atf_check ln -s a c 5864a82bcdSEnji Cooper atf_check mkdir d 5964a82bcdSEnji Cooper 6064a82bcdSEnji Cooper paths="a b c d" 6164a82bcdSEnji Cooper 62faef91faSEnji Cooper ls_out=ls.output 63faef91faSEnji Cooper stat_out=stat.output 64faef91faSEnji Cooper 6564a82bcdSEnji Cooper # NOTE: 6664a82bcdSEnji Cooper # - Even though stat -l claims to be equivalent to `ls -lT`, the 6764a82bcdSEnji Cooper # whitespace is a bit more liberal in the `ls -lT` output. 6864a82bcdSEnji Cooper # - `ls -ldT` is used to not recursively list the contents of 6964a82bcdSEnji Cooper # directories. 7064a82bcdSEnji Cooper for path in $paths; do 71faef91faSEnji Cooper atf_check -o save:$ls_out ls -ldT $path 72faef91faSEnji Cooper cat $ls_out 73faef91faSEnji Cooper atf_check -o save:$stat_out stat -l $path 74faef91faSEnji Cooper cat $stat_out 75faef91faSEnji Cooper echo "Comparing normalized whitespace" 76faef91faSEnji Cooper atf_check sed -i '' -E -e 's/[[:space:]]+/ /g' $ls_out 77faef91faSEnji Cooper atf_check sed -i '' -E -e 's/[[:space:]]+/ /g' $stat_out 78faef91faSEnji Cooper atf_check cmp $ls_out $stat_out 7964a82bcdSEnji Cooper done 8064a82bcdSEnji Cooper} 8164a82bcdSEnji Cooper 8264a82bcdSEnji Cooperatf_test_case n_flag 8364a82bcdSEnji Coopern_flag_head() 8464a82bcdSEnji Cooper{ 8564a82bcdSEnji Cooper atf_set "descr" "Verify that -n suppresses newline output for lines" 8664a82bcdSEnji Cooper} 8764a82bcdSEnji Coopern_flag_body() 8864a82bcdSEnji Cooper{ 8964a82bcdSEnji Cooper atf_check touch a b 9064a82bcdSEnji Cooper atf_check -o inline:"$(stat a | tr -d '\n')" stat -n a 9164a82bcdSEnji Cooper atf_check -o inline:"$(stat a b | tr -d '\n')" stat -n a b 9264a82bcdSEnji Cooper} 9364a82bcdSEnji Cooper 9464a82bcdSEnji Cooperatf_test_case q_flag 9564a82bcdSEnji Cooperq_flag_head() 9664a82bcdSEnji Cooper{ 9764a82bcdSEnji Cooper atf_set "descr" "Verify that -q suppresses error messages from l?stat(2)" 9864a82bcdSEnji Cooper} 9964a82bcdSEnji Cooperq_flag_body() 10064a82bcdSEnji Cooper{ 10164a82bcdSEnji Cooper ln -s nonexistent broken-link 10264a82bcdSEnji Cooper 10364a82bcdSEnji Cooper atf_check -s exit:1 stat -q nonexistent 10464a82bcdSEnji Cooper atf_check -s exit:1 stat -q nonexistent 10564a82bcdSEnji Cooper atf_check -o not-empty stat -q broken-link 10664a82bcdSEnji Cooper atf_check -o not-empty stat -qL broken-link 10764a82bcdSEnji Cooper} 10864a82bcdSEnji Cooper 10964a82bcdSEnji Cooperatf_test_case r_flag 11064a82bcdSEnji Cooperr_flag_head() 11164a82bcdSEnji Cooper{ 11264a82bcdSEnji Cooper atf_set "descr" "Verify that -r displays output in 'raw mode'" 11364a82bcdSEnji Cooper} 11464a82bcdSEnji Cooperr_flag_body() 11564a82bcdSEnji Cooper{ 11664a82bcdSEnji Cooper atf_check touch a 11764a82bcdSEnji Cooper # TODO: add more thorough checks. 11864a82bcdSEnji Cooper atf_check -o not-empty stat -r a 11964a82bcdSEnji Cooper} 12064a82bcdSEnji Cooper 12164a82bcdSEnji Cooperatf_test_case s_flag 12264a82bcdSEnji Coopers_flag_head() 12364a82bcdSEnji Cooper{ 12464a82bcdSEnji Cooper atf_set "descr" "Verify the output format for -s" 12564a82bcdSEnji Cooper} 12664a82bcdSEnji Coopers_flag_body() 12764a82bcdSEnji Cooper{ 12864a82bcdSEnji Cooper atf_check touch a 12964a82bcdSEnji Cooper atf_check ln a b 13064a82bcdSEnji Cooper atf_check ln -s a c 13164a82bcdSEnji Cooper atf_check mkdir d 13264a82bcdSEnji Cooper 13364a82bcdSEnji Cooper paths="a b c d" 13464a82bcdSEnji Cooper 13564a82bcdSEnji Cooper # The order/name of each of the fields is specified by stat(1) manpage. 13664a82bcdSEnji Cooper fields="st_dev st_ino st_mode st_nlink" 13764a82bcdSEnji Cooper fields="$fields st_uid st_gid st_rdev st_size" 13864a82bcdSEnji Cooper fields="$fields st_uid st_gid st_mode" 13964a82bcdSEnji Cooper fields="$fields st_atime st_mtime st_ctime st_birthtime" 14064a82bcdSEnji Cooper fields="$fields st_blksize st_blocks st_flags" 14164a82bcdSEnji Cooper 14264a82bcdSEnji Cooper # NOTE: the following... 14364a82bcdSEnji Cooper # - ... relies on set -eu to ensure that the fields are set, as 14464a82bcdSEnji Cooper # documented, in stat(1). 14564a82bcdSEnji Cooper # - ... uses a subshell to ensure that the eval'ed variables don't 14664a82bcdSEnji Cooper # pollute the next iteration's behavior. 14764a82bcdSEnji Cooper for path in $paths; do 14864a82bcdSEnji Cooper ( 14964a82bcdSEnji Cooper set -eu 15064a82bcdSEnji Cooper eval $(stat -s $path) 15164a82bcdSEnji Cooper for field in $fields; do 15264a82bcdSEnji Cooper eval "$field=\$$field" 15364a82bcdSEnji Cooper done 15464a82bcdSEnji Cooper ) || atf_fail 'One or more fields not set by stat(1)' 15564a82bcdSEnji Cooper done 15664a82bcdSEnji Cooper} 15764a82bcdSEnji Cooper 15864a82bcdSEnji Cooperatf_test_case t_flag 15964a82bcdSEnji Coopert_flag_head() 16064a82bcdSEnji Cooper{ 16164a82bcdSEnji Cooper atf_set "descr" "Verify the output format for -t" 16264a82bcdSEnji Cooper} 16364a82bcdSEnji Cooper 16464a82bcdSEnji Coopert_flag_body() 16564a82bcdSEnji Cooper{ 16664a82bcdSEnji Cooper atf_check touch foo 16764a82bcdSEnji Cooper atf_check touch -d 1970-01-01T00:00:42 foo 16864a82bcdSEnji Cooper atf_check -o inline:'42\n' \ 16964a82bcdSEnji Cooper stat -t '%s' -f '%a' foo 17064a82bcdSEnji Cooper atf_check -o inline:'1970-01-01 00:00:42\n' \ 17164a82bcdSEnji Cooper stat -t '%F %H:%M:%S' -f '%Sa' foo 17264a82bcdSEnji Cooper} 17364a82bcdSEnji Cooper 17464a82bcdSEnji Cooperx_output_date() 17564a82bcdSEnji Cooper{ 1765e8e7af3SEnji Cooper local date_format='%a %b %e %H:%M:%S %Y' 17764a82bcdSEnji Cooper 17864a82bcdSEnji Cooper stat -t "$date_format" "$@" 17964a82bcdSEnji Cooper} 18064a82bcdSEnji Cooper 18164a82bcdSEnji Cooperx_output() 18264a82bcdSEnji Cooper{ 18364a82bcdSEnji Cooper local path=$1; shift 18464a82bcdSEnji Cooper 18564a82bcdSEnji Cooper local atime_s=$(x_output_date -f '%Sa' $path) 186*98ce554aSEdward Tomasz Napierala local btime_s=$(x_output_date -f '%SB' $path) 18764a82bcdSEnji Cooper local ctime_s=$(x_output_date -f '%Sc' $path) 18864a82bcdSEnji Cooper local devid=$(stat -f '%Hd,%Ld' $path) 18964a82bcdSEnji Cooper local file_type_s=$(stat -f '%HT' $path) 19064a82bcdSEnji Cooper local gid=$(stat -f '%5g' $path) 19164a82bcdSEnji Cooper local groupname=$(stat -f '%8Sg' $path) 19264a82bcdSEnji Cooper local inode=$(stat -f '%i' $path) 19364a82bcdSEnji Cooper local mode=$(stat -f '%Mp%Lp' $path) 19464a82bcdSEnji Cooper local mode_s=$(stat -f '%Sp' $path) 19564a82bcdSEnji Cooper local mtime_s=$(x_output_date -f '%Sm' $path) 19664a82bcdSEnji Cooper local nlink=$(stat -f '%l' $path) 19764a82bcdSEnji Cooper local size_a=$(stat -f '%-11z' $path) 19864a82bcdSEnji Cooper local uid=$(stat -f '%5u' $path) 19964a82bcdSEnji Cooper local username=$(stat -f '%8Su' $path) 20064a82bcdSEnji Cooper 20164a82bcdSEnji Cooper cat <<EOF 20264a82bcdSEnji Cooper File: "$path" 20364a82bcdSEnji Cooper Size: $size_a FileType: $file_type_s 20464a82bcdSEnji Cooper Mode: ($mode/$mode_s) Uid: ($uid/$username) Gid: ($gid/$groupname) 20564a82bcdSEnji CooperDevice: $devid Inode: $inode Links: $nlink 20664a82bcdSEnji CooperAccess: $atime_s 20764a82bcdSEnji CooperModify: $mtime_s 20864a82bcdSEnji CooperChange: $ctime_s 209*98ce554aSEdward Tomasz Napierala Birth: $btime_s 21064a82bcdSEnji CooperEOF 21164a82bcdSEnji Cooper} 21264a82bcdSEnji Cooper 21364a82bcdSEnji Cooperatf_test_case x_flag 21464a82bcdSEnji Cooperx_flag_head() 21564a82bcdSEnji Cooper{ 21664a82bcdSEnji Cooper atf_set "descr" "Verify the output format for -x" 21764a82bcdSEnji Cooper} 21864a82bcdSEnji Cooperx_flag_body() 21964a82bcdSEnji Cooper{ 22064a82bcdSEnji Cooper atf_check touch a 22164a82bcdSEnji Cooper atf_check ln a b 22264a82bcdSEnji Cooper atf_check ln -s a c 22364a82bcdSEnji Cooper atf_check mkdir d 22464a82bcdSEnji Cooper 22564a82bcdSEnji Cooper paths="a b c d" 22664a82bcdSEnji Cooper 22764a82bcdSEnji Cooper for path in $paths; do 22864a82bcdSEnji Cooper atf_check -o "inline:$(x_output $path)\n" stat -x $path 22964a82bcdSEnji Cooper done 23064a82bcdSEnji Cooper} 23164a82bcdSEnji Cooper 23264a82bcdSEnji Cooperatf_init_test_cases() 23364a82bcdSEnji Cooper{ 23464a82bcdSEnji Cooper atf_add_test_case F_flag 23564a82bcdSEnji Cooper #atf_add_test_case H_flag 23664a82bcdSEnji Cooper #atf_add_test_case L_flag 23764a82bcdSEnji Cooper #atf_add_test_case f_flag 23864a82bcdSEnji Cooper atf_add_test_case l_flag 23964a82bcdSEnji Cooper atf_add_test_case n_flag 24064a82bcdSEnji Cooper atf_add_test_case q_flag 24164a82bcdSEnji Cooper atf_add_test_case r_flag 24264a82bcdSEnji Cooper atf_add_test_case s_flag 24364a82bcdSEnji Cooper atf_add_test_case t_flag 24464a82bcdSEnji Cooper atf_add_test_case x_flag 24564a82bcdSEnji Cooper} 246