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# $FreeBSD$ 2764a82bcdSEnji Cooper 2864a82bcdSEnji Cooperatf_test_case F_flag 2964a82bcdSEnji CooperF_flag_head() 3064a82bcdSEnji Cooper{ 3164a82bcdSEnji Cooper atf_set "descr" "Verify the output format for -F" 3264a82bcdSEnji Cooper} 3364a82bcdSEnji CooperF_flag_body() 3464a82bcdSEnji Cooper{ 3564a82bcdSEnji Cooper # TODO: socket, whiteout file 3664a82bcdSEnji Cooper atf_check touch a 3764a82bcdSEnji Cooper atf_check mkdir b 3864a82bcdSEnji Cooper atf_check install -m 0777 /dev/null c 3964a82bcdSEnji Cooper atf_check ln -s a d 4064a82bcdSEnji Cooper atf_check mkfifo f 4164a82bcdSEnji Cooper 4264a82bcdSEnji Cooper atf_check -o match:'.* a' stat -Fn a 4364a82bcdSEnji Cooper atf_check -o match:'.* b/' stat -Fn b 4464a82bcdSEnji Cooper atf_check -o match:'.* c\*' stat -Fn c 4564a82bcdSEnji Cooper atf_check -o match:'.* d@' stat -Fn d 4664a82bcdSEnji Cooper atf_check -o match:'.* f\|' stat -Fn f 4764a82bcdSEnji Cooper} 4864a82bcdSEnji Cooper 4964a82bcdSEnji Cooperatf_test_case l_flag 5064a82bcdSEnji Cooperl_flag_head() 5164a82bcdSEnji Cooper{ 5264a82bcdSEnji Cooper atf_set "descr" "Verify the output format for -l" 5364a82bcdSEnji Cooper} 5464a82bcdSEnji Cooperl_flag_body() 5564a82bcdSEnji Cooper{ 5664a82bcdSEnji Cooper atf_check touch a 5764a82bcdSEnji Cooper atf_check ln a b 5864a82bcdSEnji Cooper atf_check ln -s a c 5964a82bcdSEnji Cooper atf_check mkdir d 6064a82bcdSEnji Cooper 6164a82bcdSEnji Cooper paths="a b c d" 6264a82bcdSEnji Cooper 63*faef91faSEnji Cooper ls_out=ls.output 64*faef91faSEnji Cooper stat_out=stat.output 65*faef91faSEnji Cooper 6664a82bcdSEnji Cooper # NOTE: 6764a82bcdSEnji Cooper # - Even though stat -l claims to be equivalent to `ls -lT`, the 6864a82bcdSEnji Cooper # whitespace is a bit more liberal in the `ls -lT` output. 6964a82bcdSEnji Cooper # - `ls -ldT` is used to not recursively list the contents of 7064a82bcdSEnji Cooper # directories. 7164a82bcdSEnji Cooper for path in $paths; do 72*faef91faSEnji Cooper atf_check -o save:$ls_out ls -ldT $path 73*faef91faSEnji Cooper cat $ls_out 74*faef91faSEnji Cooper atf_check -o save:$stat_out stat -l $path 75*faef91faSEnji Cooper cat $stat_out 76*faef91faSEnji Cooper echo "Comparing normalized whitespace" 77*faef91faSEnji Cooper atf_check sed -i '' -E -e 's/[[:space:]]+/ /g' $ls_out 78*faef91faSEnji Cooper atf_check sed -i '' -E -e 's/[[:space:]]+/ /g' $stat_out 79*faef91faSEnji Cooper atf_check cmp $ls_out $stat_out 8064a82bcdSEnji Cooper done 8164a82bcdSEnji Cooper} 8264a82bcdSEnji Cooper 8364a82bcdSEnji Cooperatf_test_case n_flag 8464a82bcdSEnji Coopern_flag_head() 8564a82bcdSEnji Cooper{ 8664a82bcdSEnji Cooper atf_set "descr" "Verify that -n suppresses newline output for lines" 8764a82bcdSEnji Cooper} 8864a82bcdSEnji Coopern_flag_body() 8964a82bcdSEnji Cooper{ 9064a82bcdSEnji Cooper atf_check touch a b 9164a82bcdSEnji Cooper atf_check -o inline:"$(stat a | tr -d '\n')" stat -n a 9264a82bcdSEnji Cooper atf_check -o inline:"$(stat a b | tr -d '\n')" stat -n a b 9364a82bcdSEnji Cooper} 9464a82bcdSEnji Cooper 9564a82bcdSEnji Cooperatf_test_case q_flag 9664a82bcdSEnji Cooperq_flag_head() 9764a82bcdSEnji Cooper{ 9864a82bcdSEnji Cooper atf_set "descr" "Verify that -q suppresses error messages from l?stat(2)" 9964a82bcdSEnji Cooper} 10064a82bcdSEnji Cooperq_flag_body() 10164a82bcdSEnji Cooper{ 10264a82bcdSEnji Cooper ln -s nonexistent broken-link 10364a82bcdSEnji Cooper 10464a82bcdSEnji Cooper atf_check -s exit:1 stat -q nonexistent 10564a82bcdSEnji Cooper atf_check -s exit:1 stat -q nonexistent 10664a82bcdSEnji Cooper atf_check -o not-empty stat -q broken-link 10764a82bcdSEnji Cooper atf_check -o not-empty stat -qL broken-link 10864a82bcdSEnji Cooper} 10964a82bcdSEnji Cooper 11064a82bcdSEnji Cooperatf_test_case r_flag 11164a82bcdSEnji Cooperr_flag_head() 11264a82bcdSEnji Cooper{ 11364a82bcdSEnji Cooper atf_set "descr" "Verify that -r displays output in 'raw mode'" 11464a82bcdSEnji Cooper} 11564a82bcdSEnji Cooperr_flag_body() 11664a82bcdSEnji Cooper{ 11764a82bcdSEnji Cooper atf_check touch a 11864a82bcdSEnji Cooper # TODO: add more thorough checks. 11964a82bcdSEnji Cooper atf_check -o not-empty stat -r a 12064a82bcdSEnji Cooper} 12164a82bcdSEnji Cooper 12264a82bcdSEnji Cooperatf_test_case s_flag 12364a82bcdSEnji Coopers_flag_head() 12464a82bcdSEnji Cooper{ 12564a82bcdSEnji Cooper atf_set "descr" "Verify the output format for -s" 12664a82bcdSEnji Cooper} 12764a82bcdSEnji Coopers_flag_body() 12864a82bcdSEnji Cooper{ 12964a82bcdSEnji Cooper atf_check touch a 13064a82bcdSEnji Cooper atf_check ln a b 13164a82bcdSEnji Cooper atf_check ln -s a c 13264a82bcdSEnji Cooper atf_check mkdir d 13364a82bcdSEnji Cooper 13464a82bcdSEnji Cooper paths="a b c d" 13564a82bcdSEnji Cooper 13664a82bcdSEnji Cooper # The order/name of each of the fields is specified by stat(1) manpage. 13764a82bcdSEnji Cooper fields="st_dev st_ino st_mode st_nlink" 13864a82bcdSEnji Cooper fields="$fields st_uid st_gid st_rdev st_size" 13964a82bcdSEnji Cooper fields="$fields st_uid st_gid st_mode" 14064a82bcdSEnji Cooper fields="$fields st_atime st_mtime st_ctime st_birthtime" 14164a82bcdSEnji Cooper fields="$fields st_blksize st_blocks st_flags" 14264a82bcdSEnji Cooper 14364a82bcdSEnji Cooper # NOTE: the following... 14464a82bcdSEnji Cooper # - ... relies on set -eu to ensure that the fields are set, as 14564a82bcdSEnji Cooper # documented, in stat(1). 14664a82bcdSEnji Cooper # - ... uses a subshell to ensure that the eval'ed variables don't 14764a82bcdSEnji Cooper # pollute the next iteration's behavior. 14864a82bcdSEnji Cooper for path in $paths; do 14964a82bcdSEnji Cooper ( 15064a82bcdSEnji Cooper set -eu 15164a82bcdSEnji Cooper eval $(stat -s $path) 15264a82bcdSEnji Cooper for field in $fields; do 15364a82bcdSEnji Cooper eval "$field=\$$field" 15464a82bcdSEnji Cooper done 15564a82bcdSEnji Cooper ) || atf_fail 'One or more fields not set by stat(1)' 15664a82bcdSEnji Cooper done 15764a82bcdSEnji Cooper} 15864a82bcdSEnji Cooper 15964a82bcdSEnji Cooperatf_test_case t_flag 16064a82bcdSEnji Coopert_flag_head() 16164a82bcdSEnji Cooper{ 16264a82bcdSEnji Cooper atf_set "descr" "Verify the output format for -t" 16364a82bcdSEnji Cooper} 16464a82bcdSEnji Cooper 16564a82bcdSEnji Coopert_flag_body() 16664a82bcdSEnji Cooper{ 16764a82bcdSEnji Cooper atf_check touch foo 16864a82bcdSEnji Cooper atf_check touch -d 1970-01-01T00:00:42 foo 16964a82bcdSEnji Cooper atf_check -o inline:'42\n' \ 17064a82bcdSEnji Cooper stat -t '%s' -f '%a' foo 17164a82bcdSEnji Cooper atf_check -o inline:'1970-01-01 00:00:42\n' \ 17264a82bcdSEnji Cooper stat -t '%F %H:%M:%S' -f '%Sa' foo 17364a82bcdSEnji Cooper} 17464a82bcdSEnji Cooper 17564a82bcdSEnji Cooperx_output_date() 17664a82bcdSEnji Cooper{ 1775e8e7af3SEnji Cooper local date_format='%a %b %e %H:%M:%S %Y' 17864a82bcdSEnji Cooper 17964a82bcdSEnji Cooper stat -t "$date_format" "$@" 18064a82bcdSEnji Cooper} 18164a82bcdSEnji Cooper 18264a82bcdSEnji Cooperx_output() 18364a82bcdSEnji Cooper{ 18464a82bcdSEnji Cooper local path=$1; shift 18564a82bcdSEnji Cooper 18664a82bcdSEnji Cooper local atime_s=$(x_output_date -f '%Sa' $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 20964a82bcdSEnji CooperEOF 21064a82bcdSEnji Cooper} 21164a82bcdSEnji Cooper 21264a82bcdSEnji Cooperatf_test_case x_flag 21364a82bcdSEnji Cooperx_flag_head() 21464a82bcdSEnji Cooper{ 21564a82bcdSEnji Cooper atf_set "descr" "Verify the output format for -x" 21664a82bcdSEnji Cooper} 21764a82bcdSEnji Cooperx_flag_body() 21864a82bcdSEnji Cooper{ 21964a82bcdSEnji Cooper atf_check touch a 22064a82bcdSEnji Cooper atf_check ln a b 22164a82bcdSEnji Cooper atf_check ln -s a c 22264a82bcdSEnji Cooper atf_check mkdir d 22364a82bcdSEnji Cooper 22464a82bcdSEnji Cooper paths="a b c d" 22564a82bcdSEnji Cooper 22664a82bcdSEnji Cooper for path in $paths; do 22764a82bcdSEnji Cooper atf_check -o "inline:$(x_output $path)\n" stat -x $path 22864a82bcdSEnji Cooper done 22964a82bcdSEnji Cooper} 23064a82bcdSEnji Cooper 23164a82bcdSEnji Cooperatf_init_test_cases() 23264a82bcdSEnji Cooper{ 23364a82bcdSEnji Cooper atf_add_test_case F_flag 23464a82bcdSEnji Cooper #atf_add_test_case H_flag 23564a82bcdSEnji Cooper #atf_add_test_case L_flag 23664a82bcdSEnji Cooper #atf_add_test_case f_flag 23764a82bcdSEnji Cooper atf_add_test_case l_flag 23864a82bcdSEnji Cooper atf_add_test_case n_flag 23964a82bcdSEnji Cooper atf_add_test_case q_flag 24064a82bcdSEnji Cooper atf_add_test_case r_flag 24164a82bcdSEnji Cooper atf_add_test_case s_flag 24264a82bcdSEnji Cooper atf_add_test_case t_flag 24364a82bcdSEnji Cooper atf_add_test_case x_flag 24464a82bcdSEnji Cooper} 245