#!/usr/bin/ksh93 ################################################################ function usagemsg_fortune { print " Program: fortune This script displays a fortune from either the file specified by the \"FileName\" parameter or by default from the \${HOME}/.fortunes file. After displaying the fortune, the fortune command exits. Usage: ${1##*/} [-?vVqdf] [-n #] [FileName ] Where: -v = Verbose mode - displays fortune file info -V = Very Verbose Mode - debug output displayed -q = Quiet mode - fortune not displayed -d = Data mode - displays the fortune file info in record format -f = Display the fortune number at the end of the fortune -n # = Display a specific fortune by it's numerical position in the fortune data file FileName = FileName containing fortunes (Default: \${HOME}/.fortunes) Author: Dana French (dfrench@mtxia.com) Copyright 2004 \"AutoContent\" enabled " } ################################################################ #### #### Description: #### #### This script reads data from a "fortunes" formatted file #### and writes a "stanza" of information from that file to #### standard output. Each stanza of information from the #### "fortunes" file is delimited by a percent sign (%) on a #### line by itself. #### #### Assumptions: #### #### This script assumes the fortunes data file contains #### lines of text, delimited into stanzas by a percent sign #### (%) on a line by itself. Each stanza represents a #### "fortune" that is displayed randomly by this script. #### #### Dependencies: #### #### This script is dependent upon the unix utilities "grep", #### "cut", and "sed". These utilities must be in the PATH #### in order for this script to work properly. #### #### Products: #### #### This script reads a data file and outputs a random stanza of #### information from the data file. Options to this script #### can control which stanza is displayed, and information about #### the randomly selected stanza. #### #### Configured Usage: #### #### This script can be executed from the command line, #### startup script, or as a function from within another #### script. The most typical usage would be from a startup #### script. #### #### Details: #### ################################################################ function fortune { typeset VERSION="1.1" typeset TRUE="1" typeset FALSE="0" typeset EXITCODE="0" typeset DATAMODE="${FALSE}" typeset QUIET="${FALSE}" typeset VERBOSE="${FALSE}" typeset VERYVERB="${FALSE}" typeset FORTBYNO="${FALSE}" typeset FORTNUMB="0" typeset FORTDISP="${FALSE}" typeset ARY typeset NUM while getopts ":vVqdfn#" OPTION do case "${OPTION}" in 'n') FORTBYNO="${TRUE}" FORTNUMB="${OPTARG}";; 'd') DATAMODE="${TRUE}";; 'f') FORTDISP="${TRUE}";; 'q') QUIET="${TRUE}";; 'v') VERBOSE="${TRUE}";; 'V') VERYVERB="${TRUE}";; '?') usagemsg_fortune "${0}" && exit 1 ;; ':') usagemsg_fortune "${0}" && exit 1 ;; esac done shift $(( ${OPTIND} - 1 )) typeset FORTFILE="${1:-${HOME}/.fortunes}" trap "usagemsg_fortune ${0}" EXIT if [[ "_${FORTFILE}" = "_" ]] then (( QUIET == FALSE )) && print -u 2 "ERROR: Fortunes Filename not specified" exit 3 fi trap "-" EXIT (( VERBOSE == TRUE )) && print "# Version: ${VERSION}" (( VERYVERB == TRUE )) && set -x ################################################################ #### #### Check to see if the fortunes data file is readable, if not #### issue an error message and exit. #### if [[ ! -r ${FORTFILE} ]] then print -u 2 "# ERROR: Can't read fortunes FILE \"${FORTFILE}\"!" return 1 fi #### #### Obtain a list of beginning line numbers for each #### fortune. Each fortune is delimited by a line beginning #### with one or more "%". Save the beginning line numbers #### to an array for later use. #### ARY=( 1 $( grep -n "^%%*[ ]*$" "${FORTFILE}" | cut -d: -f1 ) ) #### #### If there are no fortunes in the data file, issue an #### error message and exit. #### if (( ${#ARY[*]} == 0 )) then print -u 2 "# ERROR: No fortunes in FILE \"${FORTFILE}\"!" return 2 fi #### #### Randomly select a fortune number by chosing and array element #### containing the beginning line number of a fortune from the data #### file. #### (( NUM = RANDOM % ${#ARY[*]} )) #### #### If the -n option was specified on the command line, then compare the #### fortune number specfied by the user against the number of fortunes in #### the data file. If the user specfied number is greater than the number #### of fortunes in the data file, issue an error message and return with an #### unsuccessful return code; otherwise set the fortune number to the #### user specified number. #### if (( FORTBYNO == TRUE )) then if (( FORTNUMB < 0 )) || (( FORTNUMB > ( ${#ARY[*]} - 1 ) )) then print -u 2 "# ERROR: Invalid fortune number" print -u 2 "# ERROR: Valid fortune numbers: 0 - $(( ${#ARY[*]} - 1 ))" return 3 fi NUM="${FORTNUMB}" fi #### If VERBOSE mode is on, display some information about the #### selected fortune. (( VERBOSE == TRUE )) && print -r -- "# Fortune File: ${FORTFILE}" (( VERBOSE == TRUE )) && print "# No. of fortunes in fortunes file: ${#ARY[*]}" (( VERBOSE == TRUE )) && print "# Fortune No.: ${NUM}" (( VERBOSE == TRUE )) && print "# Beginning line No.: ${ARY[NUM]}" #### #### If the use specified DATA mode, display some information about #### the selected fortune formatted as a data record separated by #### colon ":" delimeters. The fortune itself is not displayed. #### if (( DATAMODE == TRUE )) then print -u 2 "# fortfile:fortcnt:fortnumb:fortline" print -r -- "${FORTFILE}:${#ARY[*]}:${NUM}:${ARY[NUM]}" return 0 fi #### If QUIET mode was specified by the user on the command line, #### do not display the fortune, simply return with a successful #### return code. (( QUIET == TRUE )) && return 0 #### #### Display one single fortune by using beginning line number of #### the fortune and displaying all lines until the next #### fortune delimeter "%" is found, or end of file. #### (( FORTDISP == TRUE )) && print "Fortune ${NUM} of ${#ARY[*]}" sed -e "${ARY[NUM]},/^%%*[ ]*$/ !d;s/^%.*//" "${FORTFILE}" return 0 } ################################################################ fortune "${@}"