#! /usr/bin/ksh ########################################################################## # Shellscript: popc.ksh - example of an POP3 e-mail client # Author : Heiner Steven # Date : 2002-02-12 # Category : Mail, Internet # SCCS-Id. : @(#) popc.ksh 1.1 02/02/26 ########################################################################## # Description # This example implements the "LIST" command to list all messages, # "RETR" to retrieve a message text by number, and "DELE" to delete # a message by number. # # Refer to RFC 1939 (http://www.ietf.org/rfc/rfc1939.txt) for a full # description of the POP3 protocol. # # Needs the non-standard program "netcat" (aka "nc") to establish a # TCP connection. You could use "socket(1)" instead, if installed. ########################################################################## PN=${0##*/} # Program name VER='1.1' : ${NETCAT:=netcat} : ${NETCATFLAGS:=} DEF_HOST=localhost DEF_PORT=110 : ${DEF_USER:=${USER:-$LOGNAME}} : ${DEF_PASSWD:=$POP3_PASSWORD} function Usage { print -u2 "$PN - example of an POP3 e-mail client, $VER usage: $PN [-h host] [-p port] [-U user] [-P password] -h: mail server (POP3) host name (default is \"$DEF_HOST\") -p: mail server port number (default is $DEF_PORT) -U: mail account user name (default is $DEF_USER) -P: mail account password (no default)" exit 1 } function Msg { print -u2 "$PN:" "$@" } function Fatal { Msg "$@"; exit 1; } while getopts :h:p:U:P: opt do case "$opt" in # your flags here #f) argument=$OPTARG;; h) host=$OPTARG;; p) port=$OPTARG;; U) user=$OPTARG;; P) pass=$OPTARG;; ?) Usage;; esac done shift OPTIND-1 : ${host:=$DEF_HOST} # Name or address of POP3 server : ${port:=$DEF_PORT} # POP3 port (standard is 110) : ${user:=$DEF_USER} : ${pass:=$DEF_PASSWD} typeset -u pop_status # Global last status { "+OK" | "-ERR" } typeset pop_msg # Global last server status message function Fatal { print -u2 "$@"; exit 1; } # sendline - send one line to co-process function sendline { print -p -- "$@"; } # getack - get positive or negative acknowledgement from server # # The server will answer with either "+OK ..." or "-ERR ...". We # evaluate the first word read from the server, and set the # return value accordingly function getack { read -p -r pop_status pop_msg; print -u2 "DEBUG: $pop_status $pop_msg" [[ $pop_status == '+OK' ]] && return 0 print -u2 -- "$pop_status $pop_msg" return 1 } # getlist - get multi-line response from server # # Multi-line responses are terminated by a line consisting only of # a period '.' function getlist { typeset line while read -p -r line do line=${line%+(?)} # Remove trailing CR (ASCII 13) [[ $line == '.' ]] && break # End of list #print -- "<$line>" print -- "$line" done } function ListCmd { sendline "LIST" getack && getlist } function DeleteCmd { integer msgno read msgno?"DELETE message Number: " sendline "DELE $msgno" && getack } function RetrieveCmd { integer msgno read msgno?"Retrieve message Number: " sendline "RETR $msgno" getack && getlist } # Startup the server as a co-process. We will use "print -p" # and "read -p" to write and read data. "$NETCAT" $NETCATFLAGS "$host" "$port" |& popdpid=$! # Check if the server is ready getack || Fatal "cannot start POP3 server $host:$port" # Authentication set -e # First error terminates script sendline "USER $user" && getack sendline "PASS $pass" && getack set +e print -u2 "Authentication successful" PS3="POP3 command (RETURN prints menu): " select choice in List Retrieve Delete Quit do case "$choice" in (List) ListCmd ;; (Retrieve) RetrieveCmd ;; (Delete) DeleteCmd ;; (Quit) break;; esac done # Shut down co-process exec 3<&p 3>&p # redirect co-process fd to fd 3 exec 3<&- 3>&- # close fd 3 kill $popdpid >/dev/null 2>&1 # if the above does not work... exit 0