1 /* 2 * Copyright (c) 1997-2012 Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 import java.util.*; 33 import java.io.*; 34 import javax.mail.*; 35 import javax.mail.event.*; 36 import javax.mail.internet.*; 37 38 /* 39 * Demo app that exercises the Message interfaces. 40 * Show information about and contents of messages. 41 * 42 * @author John Mani 43 * @author Bill Shannon 44 */ 45 46 public class msgshow { 47 48 static String protocol; 49 static String host = null; 50 static String user = null; 51 static String password = null; 52 static String mbox = null; 53 static String url = null; 54 static int port = -1; 55 static boolean verbose = false; 56 static boolean debug = false; 57 static boolean showStructure = false; 58 static boolean showMessage = false; 59 static boolean showAlert = false; 60 static boolean saveAttachments = false; 61 static int attnum = 1; 62 main(String argv[])63 public static void main(String argv[]) { 64 int optind; 65 InputStream msgStream = System.in; 66 67 for (optind = 0; optind < argv.length; optind++) { 68 if (argv[optind].equals("-T")) { 69 protocol = argv[++optind]; 70 } else if (argv[optind].equals("-H")) { 71 host = argv[++optind]; 72 } else if (argv[optind].equals("-U")) { 73 user = argv[++optind]; 74 } else if (argv[optind].equals("-P")) { 75 password = argv[++optind]; 76 } else if (argv[optind].equals("-v")) { 77 verbose = true; 78 } else if (argv[optind].equals("-D")) { 79 debug = true; 80 } else if (argv[optind].equals("-f")) { 81 mbox = argv[++optind]; 82 } else if (argv[optind].equals("-L")) { 83 url = argv[++optind]; 84 } else if (argv[optind].equals("-p")) { 85 port = Integer.parseInt(argv[++optind]); 86 } else if (argv[optind].equals("-s")) { 87 showStructure = true; 88 } else if (argv[optind].equals("-S")) { 89 saveAttachments = true; 90 } else if (argv[optind].equals("-m")) { 91 showMessage = true; 92 } else if (argv[optind].equals("-a")) { 93 showAlert = true; 94 } else if (argv[optind].equals("--")) { 95 optind++; 96 break; 97 } else if (argv[optind].startsWith("-")) { 98 System.out.println( 99 "Usage: msgshow [-L url] [-T protocol] [-H host] [-p port] [-U user]"); 100 System.out.println( 101 "\t[-P password] [-f mailbox] [msgnum ...] [-v] [-D] [-s] [-S] [-a]"); 102 System.out.println( 103 "or msgshow -m [-v] [-D] [-s] [-S] [-f msg-file]"); 104 System.exit(1); 105 } else { 106 break; 107 } 108 } 109 110 try { 111 // Get a Properties object 112 Properties props = System.getProperties(); 113 114 // Get a Session object 115 Session session = Session.getInstance(props, null); 116 session.setDebug(debug); 117 118 if (showMessage) { 119 MimeMessage msg; 120 if (mbox != null) 121 msg = new MimeMessage(session, 122 new BufferedInputStream(new FileInputStream(mbox))); 123 else 124 msg = new MimeMessage(session, msgStream); 125 dumpPart(msg); 126 System.exit(0); 127 } 128 129 // Get a Store object 130 Store store = null; 131 if (url != null) { 132 URLName urln = new URLName(url); 133 store = session.getStore(urln); 134 if (showAlert) { 135 store.addStoreListener(new StoreListener() { 136 public void notification(StoreEvent e) { 137 String s; 138 if (e.getMessageType() == StoreEvent.ALERT) 139 s = "ALERT: "; 140 else 141 s = "NOTICE: "; 142 System.out.println(s + e.getMessage()); 143 } 144 }); 145 } 146 store.connect(); 147 } else { 148 if (protocol != null) 149 store = session.getStore(protocol); 150 else 151 store = session.getStore(); 152 153 // Connect 154 if (host != null || user != null || password != null) 155 store.connect(host, port, user, password); 156 else 157 store.connect(); 158 } 159 160 161 // Open the Folder 162 163 Folder folder = store.getDefaultFolder(); 164 if (folder == null) { 165 System.out.println("No default folder"); 166 System.exit(1); 167 } 168 169 if (mbox == null) 170 mbox = "INBOX"; 171 folder = folder.getFolder(mbox); 172 if (folder == null) { 173 System.out.println("Invalid folder"); 174 System.exit(1); 175 } 176 177 // try to open read/write and if that fails try read-only 178 try { 179 folder.open(Folder.READ_WRITE); 180 } catch (MessagingException ex) { 181 folder.open(Folder.READ_ONLY); 182 } 183 int totalMessages = folder.getMessageCount(); 184 185 if (totalMessages == 0) { 186 System.out.println("Empty folder"); 187 folder.close(false); 188 store.close(); 189 System.exit(1); 190 } 191 192 if (verbose) { 193 int newMessages = folder.getNewMessageCount(); 194 System.out.println("Total messages = " + totalMessages); 195 System.out.println("New messages = " + newMessages); 196 System.out.println("-------------------------------"); 197 } 198 199 if (optind >= argv.length) { 200 // Attributes & Flags for all messages .. 201 Message[] msgs = folder.getMessages(); 202 203 // Use a suitable FetchProfile 204 FetchProfile fp = new FetchProfile(); 205 fp.add(FetchProfile.Item.ENVELOPE); 206 fp.add(FetchProfile.Item.FLAGS); 207 fp.add("X-Mailer"); 208 folder.fetch(msgs, fp); 209 210 for (int i = 0; i < msgs.length; i++) { 211 System.out.println("--------------------------"); 212 System.out.println("MESSAGE #" + (i + 1) + ":"); 213 dumpEnvelope(msgs[i]); 214 // dumpPart(msgs[i]); 215 } 216 } else { 217 while (optind < argv.length) { 218 int msgnum = Integer.parseInt(argv[optind++]); 219 System.out.println("Getting message number: " + msgnum); 220 Message m = null; 221 222 try { 223 m = folder.getMessage(msgnum); 224 dumpPart(m); 225 } catch (IndexOutOfBoundsException iex) { 226 System.out.println("Message number out of range"); 227 } 228 } 229 } 230 231 folder.close(false); 232 store.close(); 233 } catch (Exception ex) { 234 System.out.println("Oops, got exception! " + ex.getMessage()); 235 ex.printStackTrace(); 236 System.exit(1); 237 } 238 System.exit(0); 239 } 240 dumpPart(Part p)241 public static void dumpPart(Part p) throws Exception { 242 if (p instanceof Message) 243 dumpEnvelope((Message)p); 244 245 /** Dump input stream .. 246 247 InputStream is = p.getInputStream(); 248 // If "is" is not already buffered, wrap a BufferedInputStream 249 // around it. 250 if (!(is instanceof BufferedInputStream)) 251 is = new BufferedInputStream(is); 252 int c; 253 while ((c = is.read()) != -1) 254 System.out.write(c); 255 256 **/ 257 258 String ct = p.getContentType(); 259 try { 260 pr("CONTENT-TYPE: " + (new ContentType(ct)).toString()); 261 } catch (ParseException pex) { 262 pr("BAD CONTENT-TYPE: " + ct); 263 } 264 String filename = p.getFileName(); 265 if (filename != null) 266 pr("FILENAME: " + filename); 267 268 /* 269 * Using isMimeType to determine the content type avoids 270 * fetching the actual content data until we need it. 271 */ 272 if (p.isMimeType("text/plain")) { 273 pr("This is plain text"); 274 pr("---------------------------"); 275 if (!showStructure && !saveAttachments) 276 System.out.println((String)p.getContent()); 277 } else if (p.isMimeType("multipart/*")) { 278 pr("This is a Multipart"); 279 pr("---------------------------"); 280 Multipart mp = (Multipart)p.getContent(); 281 level++; 282 int count = mp.getCount(); 283 for (int i = 0; i < count; i++) 284 dumpPart(mp.getBodyPart(i)); 285 level--; 286 } else if (p.isMimeType("message/rfc822")) { 287 pr("This is a Nested Message"); 288 pr("---------------------------"); 289 level++; 290 dumpPart((Part)p.getContent()); 291 level--; 292 } else { 293 if (!showStructure && !saveAttachments) { 294 /* 295 * If we actually want to see the data, and it's not a 296 * MIME type we know, fetch it and check its Java type. 297 */ 298 Object o = p.getContent(); 299 if (o instanceof String) { 300 pr("This is a string"); 301 pr("---------------------------"); 302 System.out.println((String)o); 303 } else if (o instanceof InputStream) { 304 pr("This is just an input stream"); 305 pr("---------------------------"); 306 InputStream is = (InputStream)o; 307 int c; 308 while ((c = is.read()) != -1) 309 System.out.write(c); 310 } else { 311 pr("This is an unknown type"); 312 pr("---------------------------"); 313 pr(o.toString()); 314 } 315 } else { 316 // just a separator 317 pr("---------------------------"); 318 } 319 } 320 321 /* 322 * If we're saving attachments, write out anything that 323 * looks like an attachment into an appropriately named 324 * file. Don't overwrite existing files to prevent 325 * mistakes. 326 */ 327 if (saveAttachments && level != 0 && p instanceof MimeBodyPart && 328 !p.isMimeType("multipart/*")) { 329 String disp = p.getDisposition(); 330 // many mailers don't include a Content-Disposition 331 if (disp == null || disp.equalsIgnoreCase(Part.ATTACHMENT)) { 332 if (filename == null) 333 filename = "Attachment" + attnum++; 334 pr("Saving attachment to file " + filename); 335 try { 336 File f = new File(filename); 337 if (f.exists()) 338 // XXX - could try a series of names 339 throw new IOException("file exists"); 340 ((MimeBodyPart)p).saveFile(f); 341 } catch (IOException ex) { 342 pr("Failed to save attachment: " + ex); 343 } 344 pr("---------------------------"); 345 } 346 } 347 } 348 dumpEnvelope(Message m)349 public static void dumpEnvelope(Message m) throws Exception { 350 pr("This is the message envelope"); 351 pr("---------------------------"); 352 Address[] a; 353 // FROM 354 if ((a = m.getFrom()) != null) { 355 for (int j = 0; j < a.length; j++) 356 pr("FROM: " + a[j].toString()); 357 } 358 359 // REPLY TO 360 if ((a = m.getReplyTo()) != null) { 361 for (int j = 0; j < a.length; j++) 362 pr("REPLY TO: " + a[j].toString()); 363 } 364 365 // TO 366 if ((a = m.getRecipients(Message.RecipientType.TO)) != null) { 367 for (int j = 0; j < a.length; j++) { 368 pr("TO: " + a[j].toString()); 369 InternetAddress ia = (InternetAddress)a[j]; 370 if (ia.isGroup()) { 371 InternetAddress[] aa = ia.getGroup(false); 372 for (int k = 0; k < aa.length; k++) 373 pr(" GROUP: " + aa[k].toString()); 374 } 375 } 376 } 377 378 // SUBJECT 379 pr("SUBJECT: " + m.getSubject()); 380 381 // DATE 382 Date d = m.getSentDate(); 383 pr("SendDate: " + 384 (d != null ? d.toString() : "UNKNOWN")); 385 386 // FLAGS 387 Flags flags = m.getFlags(); 388 StringBuffer sb = new StringBuffer(); 389 Flags.Flag[] sf = flags.getSystemFlags(); // get the system flags 390 391 boolean first = true; 392 for (int i = 0; i < sf.length; i++) { 393 String s; 394 Flags.Flag f = sf[i]; 395 if (f == Flags.Flag.ANSWERED) 396 s = "\\Answered"; 397 else if (f == Flags.Flag.DELETED) 398 s = "\\Deleted"; 399 else if (f == Flags.Flag.DRAFT) 400 s = "\\Draft"; 401 else if (f == Flags.Flag.FLAGGED) 402 s = "\\Flagged"; 403 else if (f == Flags.Flag.RECENT) 404 s = "\\Recent"; 405 else if (f == Flags.Flag.SEEN) 406 s = "\\Seen"; 407 else 408 continue; // skip it 409 if (first) 410 first = false; 411 else 412 sb.append(' '); 413 sb.append(s); 414 } 415 416 String[] uf = flags.getUserFlags(); // get the user flag strings 417 for (int i = 0; i < uf.length; i++) { 418 if (first) 419 first = false; 420 else 421 sb.append(' '); 422 sb.append(uf[i]); 423 } 424 pr("FLAGS: " + sb.toString()); 425 426 // X-MAILER 427 String[] hdrs = m.getHeader("X-Mailer"); 428 if (hdrs != null) 429 pr("X-Mailer: " + hdrs[0]); 430 else 431 pr("X-Mailer NOT available"); 432 } 433 434 static String indentStr = " "; 435 static int level = 0; 436 437 /** 438 * Print a, possibly indented, string. 439 */ pr(String s)440 public static void pr(String s) { 441 if (showStructure) 442 System.out.print(indentStr.substring(0, level * 2)); 443 System.out.println(s); 444 } 445 } 446