001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018package org.apache.commons.net.examples.mail; 019 020import java.io.BufferedReader; 021import java.io.File; 022import java.io.FileOutputStream; 023import java.io.IOException; 024import java.io.OutputStreamWriter; 025import java.nio.charset.StandardCharsets; 026import java.text.SimpleDateFormat; 027import java.util.Date; 028import java.util.regex.Matcher; 029import java.util.regex.Pattern; 030 031import org.apache.commons.net.pop3.POP3Client; 032import org.apache.commons.net.pop3.POP3MessageInfo; 033import org.apache.commons.net.pop3.POP3SClient; 034 035/** 036 * This is an example program demonstrating how to use the POP3[S]Client class. This program connects to a POP3[S] server and writes the messages to an mbox 037 * file. 038 * <p> 039 * The code currently assumes that POP3Client decodes the POP3 data as iso-8859-1. The POP3 standard only allows for ASCII so in theory iso-8859-1 should be OK. 040 * However it appears that actual POP3 implementations may return 8bit data that is outside the ASCII range; this may result in loss of data when the mailbox is 041 * created. 042 * <p> 043 * See main() method for usage details 044 */ 045public final class POP3ExportMbox { 046 047 private static final Pattern PATFROM = Pattern.compile(">*From "); // unescaped From_ 048 049 public static void main(final String[] args) { 050 int argIdx; 051 String file = null; 052 for (argIdx = 0; argIdx < args.length; argIdx++) { 053 if (!args[argIdx].equals("-F")) { 054 break; 055 } 056 file = args[++argIdx]; 057 } 058 059 final int argCount = args.length - argIdx; 060 if (argCount < 3) { 061 System.err.println("Usage: POP3Mail [-F file/directory] <server[:port]> <username> <password|-|*|VARNAME> [TLS [true=implicit]]"); 062 System.exit(1); 063 } 064 065 final String arg0[] = args[argIdx++].split(":"); 066 final String server = arg0[0]; 067 final String username = args[argIdx++]; 068 String password = args[argIdx++]; 069 // prompt for the password if necessary 070 try { 071 password = Utils.getPassword(username, password); 072 } catch (final IOException e1) { 073 System.err.println("Could not retrieve password: " + e1.getMessage()); 074 return; 075 } 076 077 final String proto = argCount > 3 ? args[argIdx++] : null; 078 final boolean implicit = argCount > 4 && Boolean.parseBoolean(args[argIdx++]); 079 080 final POP3Client pop3; 081 082 if (proto != null) { 083 System.out.println("Using secure protocol: " + proto); 084 pop3 = new POP3SClient(proto, implicit); 085 } else { 086 pop3 = new POP3Client(); 087 } 088 089 final int port; 090 if (arg0.length == 2) { 091 port = Integer.parseInt(arg0[1]); 092 } else { 093 port = pop3.getDefaultPort(); 094 } 095 System.out.println("Connecting to server " + server + " on " + port); 096 097 // We want to timeout if a response takes longer than 60 seconds 098 pop3.setDefaultTimeout(60000); 099 100 try { 101 pop3.connect(server); 102 } catch (final IOException e) { 103 System.err.println("Could not connect to server."); 104 e.printStackTrace(); 105 return; 106 } 107 108 try { 109 if (!pop3.login(username, password)) { 110 System.err.println("Could not login to server. Check password."); 111 pop3.disconnect(); 112 return; 113 } 114 115 final POP3MessageInfo status = pop3.status(); 116 if (status == null) { 117 System.err.println("Could not retrieve status."); 118 pop3.logout(); 119 pop3.disconnect(); 120 return; 121 } 122 123 System.out.println("Status: " + status); 124 final int count = status.number; 125 if (file != null) { 126 System.out.println("Getting messages: " + count); 127 final File mbox = new File(file); 128 if (mbox.isDirectory()) { 129 System.out.println("Writing dir: " + mbox); 130 // Currently POP3Client uses iso-8859-1 131 for (int i = 1; i <= count; i++) { 132 try (final OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(new File(mbox, i + ".eml")), 133 StandardCharsets.ISO_8859_1)) { 134 writeFile(pop3, fw, i); 135 } 136 } 137 } else { 138 System.out.println("Writing file: " + mbox); 139 // Currently POP3Client uses iso-8859-1 140 try (final OutputStreamWriter fw = new OutputStreamWriter(new FileOutputStream(mbox), StandardCharsets.ISO_8859_1)) { 141 for (int i = 1; i <= count; i++) { 142 writeMbox(pop3, fw, i); 143 } 144 } 145 } 146 } 147 148 pop3.logout(); 149 pop3.disconnect(); 150 } catch (final IOException e) { 151 e.printStackTrace(); 152 return; 153 } 154 } 155 156 private static boolean startsWith(final String input, final Pattern pat) { 157 final Matcher m = pat.matcher(input); 158 return m.lookingAt(); 159 } 160 161 private static void writeFile(final POP3Client pop3, final OutputStreamWriter fw, final int i) throws IOException { 162 try (final BufferedReader r = (BufferedReader) pop3.retrieveMessage(i)) { 163 String line; 164 while ((line = r.readLine()) != null) { 165 fw.write(line); 166 fw.write("\n"); 167 } 168 } 169 } 170 171 private static void writeMbox(final POP3Client pop3, final OutputStreamWriter fw, final int i) throws IOException { 172 final SimpleDateFormat DATE_FORMAT // for mbox From_ lines 173 = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyy"); 174 final String replyTo = "MAILER-DAEMON"; // default 175 final Date received = new Date(); 176 try (final BufferedReader r = (BufferedReader) pop3.retrieveMessage(i)) { 177 fw.append("From "); 178 fw.append(replyTo); 179 fw.append(' '); 180 fw.append(DATE_FORMAT.format(received)); 181 fw.append("\n"); 182 String line; 183 while ((line = r.readLine()) != null) { 184 if (startsWith(line, PATFROM)) { 185 fw.write(">"); 186 } 187 fw.write(line); 188 fw.write("\n"); 189 } 190 fw.write("\n"); 191 } 192 } 193}