This is a Korn shell script that implements a menu-driven calendar program. It supports addition, deletion, modification, and listing of calendar entries. It also provides the ability to find the calendar entry for the current day and list all calendar entries.
#!/bin/ksh # # kcal - Korn Shell calendar program # # Process errors function error { print ${1:-"unexplained error encountered"} exit ${2} } # Check arguments if (($# > 0)) then error "Usage: $0" 1 fi # Use environment variable setting or default : ${CALFILE:=$HOME/.calfile} # Create calendar file if non-existent; flag # creation error if [[ ! -f $CALFILE ]] then print "Creating default $HOME/.calfile" > $HOME/.calfile || error "$HOME/.calfile: cannot create" 1 fi # Variable declaration/assignment typeset DATE= LINE= ENTRY= REPLY="yes" PAGER=$(whence more) CLEAR=$(whence clear) # Set trap to not allow interrupts trap '$CLEAR; print "aInterrupt ignored - use menu to quit. Press <Return> to continue."; read TMP; $CLEAR' INT QUIT # Set EXIT trap - perform cleanup trap 'rm -rf /tmp/.FOUND$$ /tmp/.CHANGE$$ /tmp/.DEL$$' EXIT # Check the date function checkdate { while true do # Prompt for date read DATE?"Enter date in mmdd[yy] format (default today):" case $DATE in # Default - use todays date "" ) DATE=$(date +%m-%d-%y) break ;; # Check the given date +([0-9]) ) case ${#DATE} in 4|6)# Set month to first 2 chars typeset -L2 MO=$DATE # Check length for year; # 4 = mmdd, 6 = mmddyy if ((${#DATE} == 6)) then # Set TMP to get date typeset -L4 TMP=$DATE # Get day typeset -R2 DA=$TMP # Get year typeset -R2 YR=$DATE else # Get day typeset -R2 DA=$DATE # Set to current year YR=$(date +%y) DATE=$DATE$YR fi # Now check indiv values # Day must be in range 01-31 if ((DA < 01 || DA > 31)) then print "$DA: invalid day format - try again" continue fi # Month must be 01-12 if ((MO < 01 || MO > 12)) then print "$MO: invalid month format - try again" continue fi # Set date format mm-dd-yy DATE=$MO-$DA-$YR break ;; * ) # Invalid format print "$DATE: invalid date format - try again" ;; esac ;; # Invalid date given * ) print "$DATE: invalid format - try again" ;; esac done } # Add new calendar entry function addentry { $CLEAR ENTRY="$DATE" # For existent entry, just add more data COUNT=$(grep -c "^$DATE" $CALFILE) if ((COUNT > 0)) then changeentry return fi # Prompt for input print "Enter info for $DATE: (enter <Return> by itself when finished)" while true do read LINE?"=>" if [[ -n $LINE ]] then ENTRY="$ENTRY,$LINE" else break fi done # Append to calendar file print $ENTRY>>$CALFILE # Sort the calendar file sort -o $CALFILE $CALFILE } function formatentry { $CLEAR typeset IFS="," BORDER="**************************************" BORDER1="* *" FILE=$1 if [[ -s $FILE ]] then # Open calendar file for reading, and # format output (exec 0<$FILE while read -r ENTRY do print "$BORDER $BORDER1" set $ENTRY typeset -L35 LINE="DATE: $1" print "* $LINE*" shift print "$BORDER1" for i do LINE="$i" print "* $LINE*" done print "$BORDER1" done print "$BORDER" ) | $PAGER else print "No entries found." fi # Prompt to continue until [[ $REPLY = "" ]] do read REPLY?"Enter <Return> to continue..." done } # Find specific entry function findentry { $CLEAR # Check for entry - put it in temp found file grep $DATE $CALFILE >/tmp/.FOUND$$ # Format found entries formatentry /tmp/.FOUND$$ } # Change an entry function changeentry { # Find specific entry - put it in temp found file grep $DATE $CALFILE | tr ',' ' 12'>/tmp/.FOUND$$ # Return if no entry was found if [[ ! -s /tmp/.FOUND$$ ]] then $CLEAR read TMP?"Entry for $DATE not found - press <Return> to continue" return fi # Prompt again for change while [[ $REPLY != "" ]] do read REPLY?"Change/Add to entry for <$DATE>?" case $REPLY in [yY]* | "" ) break ;; [nN]* ) print "Ok, aborting entry change" return ;; *) print "Invalid reply - try again." ;; esac done # Edit the temporary found file ${EDITOR:-vi} /tmp/.FOUND$$ # Remove the specified original entry grep -v $DATE $CALFILE > /tmp/.CHANGE$$ # Put back new change in record format. # Add trailing (cat /tmp/.FOUND$$ | tr ' 12' ',' ; print ) >>/tmp/.CHANGE$$ # Put back new file cat /tmp/.CHANGE$$ > $CALFILE # Clean up tmp files rm -rf /tmp/.CHANGE$$ /tmp/.FOUND$$ } # Remove specific entry function delentry { # Look for entry grep $DATE $CALFILE >/tmp/.FOUND$$ # Return if not found if [[ ! -s /tmp/.FOUND$$ ]] then $CLEAR read TMP?"Entry for $DATE not found - press <Return> to continue" return fi # Prompt to delete while [[ $REPLY != "" ]] do read REPLY?"Delete entry for <$DATE>?" case $REPLY in [yY]* | "") break ;; [nN]*) print "ok, aborting delete"; return ;; *) print "Invalid reply - try again." ;; esac done # Merge changes - put them in temporary file grep -v $DATE $CALFILE > /tmp/.DEL$$ # Put back new file cat /tmp/.DEL$$ > $CALFILE # Clean up tmp files rm -rf /tmp/.DEL$$ /tmp/.FOUND$$ } Set menu selection prompt PS3="Enter selection or <Return> for default menu:" # Display menu while true do $CLEAR select i in "Add calendar entry" "Delete calendar entry" "Change calendar entry" "Find calendar entry" "List all calendar entries" "List todays calendar entry" "Exit" do case $i in "Add calendar entry") checkdate addentry $CLEAR ;; "Delete calendar entry") checkdate delentry $CLEAR ;; "Change calendar entry") checkdate changeentry $CLEAR ;; "Find calendar entry") checkdate findentry $CLEAR ;; "List all calendar entries") formatentry $CALFILE $CLEAR ;; "List todays calendar entry") DATE=$(date +%m-%d-%y) findentry $CLEAR ;; "Exit") exit ;; * ) print "aInvalid selection c" read TMP?"- press <Return> to continue" $CLEAR continue ;; esac done done
18.224.31.41