Skip to content

Repository files navigation

POP3 Vacation Auto-Responder


This program is a vacation auto-responder as part of computer networks module at the University of Pretoria. When you are away, it runs on your computer in the background, periodically checking your mailbox via POP3. If it finds a new email with the subject prac7, it automatically sends an SMTP reply to the sender informing the sender that you are on vacation.


File Structure

/
├── Main.java               Entry point — loads config, starts polling loop
├── VacationResponder.java  Core logic — polling, filtering, reply decisions
├── POP3Client.java         RFC 1939 POP3 protocol implementation
├── SMTPClient.java         RFC 5321 SMTP protocol implementation
├── EmailMessage.java       RFC 2822 message header parser
├── config.properties       Server configuration (edit before running)
└── build.sh                Compile and package script

How to Build & Run

Step 0 — Create the test mailbox user

The values in config.properties (pop3.username, pop3.password, and my.email) need to correspond to a real local mail account. Create one as follows:

sudo useradd -m prac7user
sudo passwd prac7user

Set the password to whatever you put in config.properties under pop3.password (replace the yourpasswordhere placeholder with this same value before running the program).

This creates the mailbox prac7user@localhost, matching my.email in the config file.

Step 1 — Make sure services are running

sudo systemctl start dovecot
sudo systemctl start postfix

Step 2 — Build the program

chmod +x build.sh
./build.sh

You should see:

Build successful. Run with:
  java -cp prac7.jar Main config.properties

Step 3 — Run the program

java -cp prac7.jar Main config.properties

Step 4 — Stop the program

Press Ctrl+C at any time.


Terminal 2 — Send test emails

Test 1 — Basic auto-reply (subject = prac7)

echo "Hello, are you there?" | mail -s "prac7" prac7user@localhost

Wait up to 10 seconds and watch Terminal 1. You will see:

[HH:MM:SS] Mailbox contains 1 messages.
[HH:MM:SS] Message Number: 1: From: root@... Subject= prac7
[HH:MM:SS]     SEND: sending vacation reply to root@...
[HH:MM:SS]     DONE: reply sent and address recorded.
[HH:MM:SS] Session closed - no messages deleted.

Verify the reply was received:

mail

Press 1 to read the first message. You will see:

From: prac7user@localhost
Subject: Re: Re: prac7
Auto-Submitted: auto-replied
Precedence: bulk

I am currently on vacation and will not be able to respond...

Test 2 — Reply-once rule (same sender, second email)

echo "Are you back yet?" | mail -s "prac7" prac7user@localhost

Watch Terminal 1. You will see:

[HH:MM:SS]     SKIP: already replied to root@...

The sender gets no second reply. This prevents reply storms.


Test 3 — Subject filter (wrong subject)

echo "Random email" | mail -s "hello" prac7user@localhost

Watch Terminal 1. You will see:

[HH:MM:SS]     SKIP: subject is not 'prac7'

The program ignores all mail that isn't specifically prac7.


Test 4 — Mail is never deleted

Check the Dovecot log to prove messages were fetched with TOP, not RETR, and that nothing was deleted:

sudo tail -5 /var/log/mail.log

Look for this line in the Dovecot disconnect log:

top=3/1389, retr=0/0, del=0/3
  • top=3 — 3 messages fetched using TOP (headers only)
  • retr=0 — zero full messages downloaded
  • del=0 — zero messages deleted

Restart the process to retest everything:

If you want to show Test 1 again from scratch, delete the replied-to history:

rm -f replied_to.txt

Then restart the program. It will reply again as if it has never received mail from the sender.


Bonus Features Implemented

TOP command — RFC 1939 Instead of RETR (which downloads the full message including attachments), the program uses TOP n 0 to fetch only the headers with zero body lines. The message body is never downloaded. This is proven by the Dovecot log showing retr=0/0 after every session.

UIDL command — RFC 1939 POP3Client implements UIDL, which returns a unique ID per message that persists across sessions — unlike message numbers, which can change.

RSET command — RFC 1939 Implemented in POP3Client for error recovery — un-marks any DELE marks without waiting for QUIT.

RFC 1939 Three-State Session Machine Every session explicitly goes through:

  • AUTHORIZATION — USER + PASS
  • TRANSACTION — STAT, LIST, TOP
  • UPDATE — QUIT (with no DELE, so nothing is removed)

Reply-To preference — RFC 2822 EmailMessage.getEffectiveReplyAddress() uses the Reply-To header over From when present, as the RFC specifies.

Auto-Submitted: auto-replied on outgoing mail — RFC 3834 Every auto-reply includes this header. Any compliant vacation program that receives our reply will see it and not reply back — preventing infinite loops between two vacation programs talking to each other.

About

A Java vacation auto-responder that polls a mailbox via raw POP3 and sends SMTP auto-replies, it implements TOP, UIDL, RSET, and RFC-compliant reply-loop prevention.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages