#!/usr/bin/ksh93 ################################################################ function usagemsg_ls_k93 { print -- " Program: ls_k93 The Korn Shell ls_k93 function/command writes to standard output the contents of each specified Directory parameter or the name of each specified File parameter, along with any other information you ask for with the flags. If you do not specify a File or Directory parameter, the ls_k93 function/command displays the contents of the current directory. Usage: ${1##*/} [-vV] [-1adlrF] [FILE]... Where: -1 = Single column output -a = Lists all entries in the directory, including the entries that begin with a . (dot). -d = Displays only the information for the directory named. Directories are treated like files, which is helpful when using the -l flag to get the status of a directory. -l = Limited Long listing output ( does NOT correspond to the \"ls\" long listing output). Shows the file type, permissions as they relate to the current user, and the file name. -r = Reverses the order of the sort, giving reverse alphabetic. -F = Puts a / (slash) after each file name if the file is a directory, an * (asterisk) if the file can be executed, an = (equal sign) if the file is a socket, a | (pipe) sign if the file is a FIFO, and an @ for a symbolic link. -v = Verbose mode -V = Very Verbose mode Author: Dana French (dfrench@mtxia.com) Copyright 2004 \"AutoContent\" enabled" return 0 } ################################################################ #### #### Description: #### #### The Korn Shell ls_k93 function/command writes to #### standard output the contents of each specified Directory #### parameter or the name of each specified File parameter, #### along with any other information you ask for with the #### flags. If you do not specify a File or Directory #### parameter, the ls_k93 function/command displays the #### contents of the current directory. #### #### Assumptions: #### #### Dependencies: #### #### Products: #### #### Configured Usage: #### #### Details: #### ################################################################ function ls_k93 { typeset TRUE="0" typeset FALSE="1" typeset VERBOSE="${FALSE}" typeset VERYVERB="${FALSE}" typeset DOTFILES="${FALSE}" typeset FILETAG="${FALSE}" typeset REVERSE="${FALSE}" typeset DIREXPAND="${TRUE}" typeset LONGLIST="${FALSE}" typeset LONGLINE="" typeset SCRWID="80" typeset IIDX IPOS ILEN typeset JIDX JPOS JLEN typeset TAG while getopts ":1adlrF" OPTION do case "${OPTION}" in '1') SCRWID="0";; 'a') DOTFILES="${TRUE}";; 'd') DIREXPAND="${FALSE}";; 'l') LONGLIST="${TRUE}";; 'F') FILETAG="${TRUE}";; 'r') REVERSE="${TRUE}";; 'v') VERBOSE="${TRUE}";; 'V') VERYVERB="${TRUE}";; '?') usagemsg_ls_k93 "${0}" && return 1 ;; esac done shift $(( ${OPTIND} - 1 )) ################################################################ #### #### If a list of files and/or directories were specified on the #### command, assign this list of files and dirs to an array, #### one array element per file/directory. #### If no files or directories were specified on the command #### line, and the '-a' option was specified, gather a list #### of all files in the current directory including the #### 'dot' files. If the -a option was not specified, then #### don't include the 'dot' files. #### IFS="" (( ${#} != 0 )) && FILELIST=( "${@}" ) (( ${#} == 0 )) && (( DOTFILES == TRUE )) && FILELIST=( . .. .[!.]* * ) (( ${#} == 0 )) && (( DOTFILES == FALSE )) && FILELIST=( * ) IFS=$' \t\n' #### #### If there were no 'dot' files in the current directory, #### the third array position may contain a literal #### representation of the korn shell pattern used to attempt #### to gather the 'dot' files. If so reset this array #### position to NULL. Also determine the number of #### elements in the array for use in an arithmetic for loop. #### [[ "_${FILELIST[2]##*/}" = '_.[!.]*' ]] && FILELIST[2]="" ILEN="${#FILELIST[*]}" #### Loop through each array position to display each file in #### the list. Begin at array element 0 and continue through #### to the last array position. for (( IIDX=0; IIDX<ILEN; ++IIDX )) do #### #### Assign an array index position variable to the current #### loop index number, but if the '-r' option (reverse #### order) was used on the command line, reset the array #### index position variable to the end of the array and #### count backwards through each array element. #### IPOS="${IIDX}" (( REVERSE == TRUE )) && (( IPOS = ILEN - IPOS - 1 )) #### Set a variable to contain the filename of the current #### array element. If this element is NULL, continue with #### the next iteration of the arithmetic for loop. FILE="${FILELIST[IPOS]}" [[ "_${FILE}" = "_" ]] && continue #### If the current file is a directory and the '-d' command #### line option was NOT used, then expand the contents of #### this directory. if [[ -d "${FILE}" ]] && (( DIREXPAND == TRUE )) then #### Check to see if the current file is the current #### directory or the parent directory. if [[ "_${FILE}" = _+([.]) ]] then #### If the current file is the parent directory '..' and #### this directory was specified in the list of files on the #### command line, then print this filename and continue with #### the next iteration of the loop. if [[ "_${@}" = _[[:blank]]..[[:blank:]] ]] then TAG="" (( FILETAG == TRUE )) && TAG="/" print "${FILE}${TAG}" continue fi #### #### If the current file is either the current directory or #### the parent directory, and it was not specifed as a file #### on the command line, then print this filename and #### continue with the next iteration of the arithmetic #### for loop. #### if [[ "_${@}" = "_" ]] then TAG="" (( FILETAG == TRUE )) && TAG="/" print "${FILE}${TAG}" continue fi fi #### Save the current directory in preparation for changing #### directories to directory specified by the current #### array element. If unable to change to this #### directory, issue an error message and continue with the #### next iteration of the arithmetic for loop. OLDPWD="${PWD}" if ! cd "${FILE}" > /dev/null 2>&1 then print -u 2 "ls_k93: ${FILE}: Permission denied" continue fi #### Generate a list of files in the new directory and save #### this list to a new array. unset DIRLIST IFS="" (( DOTFILES == TRUE )) && DIRLIST=( . .. .[!.]* * ) || DIRLIST=( * ) #### #### If there were no 'dot' files in the new directory, #### the third array position may contain a literal #### representation of the korn shell pattern used to attempt #### to gather the 'dot' files. If so reset this array #### position to NULL. Also determine the number of #### elements in the array for use in an arithmetic for loop. #### [[ "_${DIRLIST[2]##*/}" = '_.[!.]*' ]] && DIRLIST[2]="" JLEN="${#DIRLIST[*]}" #### Loop through each array position to display each file in #### the list. Begin at array element 0 and continue through #### to the last array position. for (( JIDX=0; JIDX<JLEN; ++JIDX )) do #### #### Assign another array index position variable to the current #### loop index number, but if the '-r' option (reverse #### order) was used on the command line, reset the new array #### index position variable to the end of the new array and #### count backwards through each new array element. #### JPOS="${JIDX}" (( REVERSE == TRUE )) && (( JPOS = JLEN - JPOS - 1 )) DIRFILE="${DIRLIST[JPOS]}" #### #### Set a variable to contain the filename of the new #### array element. If this element is NULL, continue with #### the next iteration of the arithmetic for loop. #### [[ "_${DIRFILE}" = "_" ]] && continue #### #### If the '-F' option was used on the command line, #### determine the file type of the current file and save #### the type indicator in a variable to append to the end of #### the file name. #### TAG="" if (( FILETAG == TRUE )) then TAG=$( lsFileTag_k93 "${DIRFILE}" ) fi #### #### If the '-l' option was used on the command line, #### determine the file type, permissions, etc and save #### these values in a variable to use when listing the file #### name. #### LONGLINE="" if (( LONGLIST == TRUE )) then LONGLINE=$( lsLongLine_k93 "${DIRFILE}" ) fi #### #### Print the file name, with long listing information and #### file tag, if present. #### print -r -- "${LONGLINE}${FILE%/}/${DIRFILE}${TAG}" #### #### Continue with the next iteration of the new array from #### the subdirectory. #### done #### #### Return to the previous directory and the original file #### list. #### cd "${OLDPWD}" #### #### If the current file is NOT a directory or the '-d' command #### line option was used, then the contents of this #### directory are not expanded, only directory names will be #### printed, not their contents. #### else #### #### If the '-F' option was used on the command line, #### determine the file type of the current file and save #### the type indicator in a variable to append to the end of #### the file name. #### TAG="" if (( FILETAG == TRUE )) then TAG=$( lsFileTag_k93 "${FILE}" ) fi #### #### If the '-l' option was used on the command line, #### determine the file type, permissions, etc and save #### these values in a variable to use when listing the file #### name. #### LONGLINE="" if (( LONGLIST == TRUE )) then LONGLINE=$( lsLongLine_k93 "${FILE}" ) fi #### #### Print the file name, with long listing information and #### file tag, if present. #### print -r -- "${LONGLINE}${FILE}${TAG}" fi #### #### Continue with the next iteration of the arithmetic for #### loop and the next file in the list. #### done return 0 } ################################################################ function lsLongLine_k93 { #### #### Function to determine file types, permissions, sticky #### bits, SUID, and SGID bits in a long listing output of a #### file name. #### typeset FILE="${1}" typeset LONGLINE="+" #### If the file doesn't exist return with an error. [[ ! -e "${FILE}" ]] && return 1 #### If the file is a regular file, set the file type to '-' [[ -f "${FILE}" ]] && LONGLINE="-" #### If the file is a symbolic link, set the file type to 'l' [[ -L "${FILE}" ]] && LONGLINE="l" #### If the file is a directory, set the file type to 'd' [[ -d "${FILE}" ]] && LONGLINE="d" #### If the file is a block device, set the file type to 'b' [[ -b "${FILE}" ]] && LONGLINE="b" #### If the file is a character device, set the file type to 'c' [[ -c "${FILE}" ]] && LONGLINE="c" #### If the file is a socket, set the file type to 's' [[ -S "${FILE}" ]] && LONGLINE="s" #### If the file is a pipe, set the file type to 'p' [[ -p "${FILE}" ]] && LONGLINE="p" #### If the file is readable by the current user [[ -r "${FILE}" ]] && LONGLINE="${LONGLINE}r" || LONGLINE="${LONGLINE}-" #### If the file is writeable by the current user [[ -w "${FILE}" ]] && LONGLINE="${LONGLINE}w" || LONGLINE="${LONGLINE}-" #### If the SUID bit is set and the file is executeable if [[ -u "${FILE}" ]] then [[ -x "${FILE}" ]] && LONGLINE="${LONGLINE}s" || LONGLINE="${LONGLINE}S" else #### If the SUID bit is NOT set and the file is executeable [[ -x "${FILE}" ]] && LONGLINE="${LONGLINE}x" || LONGLINE="${LONGLINE}-" fi #### If the SGID bit is set... [[ -g "${FILE}" ]] && LONGLINE="${LONGLINE}..S" || LONGLINE="${LONGLINE}..." #### If the sticky/tacky bit is set... [[ -k "${FILE}" ]] && LONGLINE="${LONGLINE}..T" || LONGLINE="${LONGLINE}..." #### Print the assembled long listing information. print -r -- "${LONGLINE} " return 0 } ################################################################ function lsFileTag_k93 { #### #### This functions provides the appended file tags #### provided when the user specifies the '-F' command line #### option to the 'ls_k93' command. #### typeset FILE="${1}" typeset TAG="" #### If the file doesn't exist return with an error. [[ ! -e "${FILE}" ]] && return 1 #### If the file is executeable, set the TAG to * [[ -x "${FILE}" ]] && TAG="*" #### If the file is a symbolic link, set the TAG to @ [[ -L "${FILE}" ]] && TAG="@" #### If the file is a directory, set the TAG to / [[ -d "${FILE}" ]] && TAG="/" print -r -- "${TAG}" return 0 } ################################################################ ls_k93 "${@}"