1 5 package com.oreilly.servlet; 6 7 import java.io.*; 8 import java.net.*; 9 import java.util.*; 10 11 75 public class MailMessage { 76 77 String host; 78 String from; 79 Vector to, cc; 80 Hashtable headers; 81 MailPrintStream out; 82 BufferedReader in; 83 Socket socket; 84 85 91 public MailMessage() throws IOException { 92 this("localhost"); 93 } 94 95 102 public MailMessage(String host) throws IOException { 103 this.host = host; 104 to = new Vector(); 105 cc = new Vector(); 106 headers = new Hashtable(); 107 setHeader("X-Mailer", "com.oreilly.servlet.MailMessage (www.servlets.com)"); 108 connect(); 109 sendHelo(); 110 } 111 112 118 public void from(String from) throws IOException { 119 sendFrom(from); 120 this.from = from; 121 } 122 123 129 public void to(String to) throws IOException { 130 sendRcpt(to); 131 this.to.addElement(to); 132 } 133 134 140 public void cc(String cc) throws IOException { 141 sendRcpt(cc); 142 this.cc.addElement(cc); 143 } 144 145 151 public void bcc(String bcc) throws IOException { 152 sendRcpt(bcc); 153 } 155 156 160 public void setSubject(String subj) { 161 headers.put("Subject", subj); 162 } 163 164 168 public void setHeader(String name, String value) { 169 headers.put(name, value); 171 } 172 173 180 public PrintStream getPrintStream() throws IOException { 181 setFromHeader(); 182 setToHeader(); 183 setCcHeader(); 184 sendData(); 185 flushHeaders(); 186 return out; 187 } 188 189 void setFromHeader() { 190 setHeader("From", from); 191 } 192 193 void setToHeader() { 194 setHeader("To", vectorToList(to)); 195 } 196 197 void setCcHeader() { 198 if (!cc.isEmpty()) { setHeader("Cc", vectorToList(cc)); 200 } 201 } 202 203 String vectorToList(Vector v) { 204 StringBuffer buf = new StringBuffer (); 205 Enumeration e = v.elements(); 206 while (e.hasMoreElements()) { 207 buf.append(e.nextElement()); 208 if (e.hasMoreElements()) { 209 buf.append(", "); 210 } 211 } 212 return buf.toString(); 213 } 214 215 void flushHeaders() throws IOException { 216 Enumeration e = headers.keys(); 218 while (e.hasMoreElements()) { 219 String name = (String ) e.nextElement(); 220 String value = (String ) headers.get(name); 221 out.println(name + ": " + value); 222 } 223 out.println(); 224 out.flush(); 225 } 226 227 233 public void sendAndClose() throws IOException { 234 sendDot(); 235 disconnect(); 236 } 237 238 static String sanitizeAddress(String s) { 241 int paramDepth = 0; 242 int start = 0; 243 int end = 0; 244 int len = s.length(); 245 246 for (int i = 0; i < len; i++) { 247 char c = s.charAt(i); 248 if (c == '(') { 249 paramDepth++; 250 if (start == 0) { 251 end = i; } 253 } 254 else if (c == ')') { 255 paramDepth--; 256 if (end == 0) { 257 start = i + 1; } 259 } 260 else if (paramDepth == 0 && c == '<') { 261 start = i + 1; 262 } 263 else if (paramDepth == 0 && c == '>') { 264 end = i; 265 } 266 } 267 268 if (end == 0) { 269 end = len; 270 } 271 272 return s.substring(start, end); 273 } 274 275 277 void connect() throws IOException { 278 socket = new Socket(host, 25); 279 out = new MailPrintStream( 280 new BufferedOutputStream( 281 socket.getOutputStream())); 282 in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 283 getReady(); 284 } 285 286 void getReady() throws IOException { 287 String response = in.readLine(); 288 int[] ok = { 220 }; 289 if (!isResponseOK(response, ok)) { 290 throw new IOException( 291 "Didn't get introduction from server: " + response); 292 } 293 } 294 295 void sendHelo() throws IOException { 296 String local = InetAddress.getLocalHost().getHostName(); 297 int[] ok = { 250 }; 298 send("HELO " + local, ok); 299 } 300 301 void sendFrom(String from) throws IOException { 302 int[] ok = { 250 }; 303 send("MAIL FROM: " + "<" + sanitizeAddress(from) + ">", ok); 304 } 305 306 void sendRcpt(String rcpt) throws IOException { 307 int[] ok = { 250, 251 }; 308 send("RCPT TO: " + "<" + sanitizeAddress(rcpt) + ">", ok); 309 } 310 311 void sendData() throws IOException { 312 int[] ok = { 354 }; 313 send("DATA", ok); 314 } 315 316 void sendDot() throws IOException { 317 int[] ok = { 250 }; 318 send("\r\n.", ok); } 320 321 void sendQuit() throws IOException { 322 int[] ok = { 221 }; 323 send("QUIT", ok); 324 } 325 326 void send(String msg, int[] ok) throws IOException { 327 out.rawPrint(msg + "\r\n"); String response = in.readLine(); 330 if (!isResponseOK(response, ok)) { 332 throw new IOException( 333 "Unexpected reply to command: " + msg + ": " + response); 334 } 335 } 336 337 boolean isResponseOK(String response, int[] ok) { 338 for (int i = 0; i < ok.length; i++) { 340 if (response.startsWith("" + ok[i])) { 341 return true; 342 } 343 } 344 return false; 345 } 346 347 void disconnect() throws IOException { 348 if (out != null) out.close(); 349 if (in != null) in.close(); 350 if (socket != null) socket.close(); 351 } 352 } 353 354 class MailPrintStream extends PrintStream { 358 359 int lastChar; 360 361 public MailPrintStream(OutputStream out) { 362 super(out, true); } 364 365 public void write(int b) { 368 if (b == '\n' && lastChar != '\r') { 369 rawWrite('\r'); rawWrite(b); 371 } 372 else if (b == '.' && lastChar == '\n') { 373 rawWrite('.'); rawWrite(b); 375 } 376 else if (b != '\n' && lastChar == '\r') { rawWrite('\n'); 378 rawWrite(b); 379 if (b == '.') { 380 rawWrite('.'); } 382 } 383 else { 384 rawWrite(b); 385 } 386 lastChar = b; 387 } 388 389 public void write(byte buf[], int off, int len) { 390 for (int i = 0; i < len; i++) { 391 write(buf[off + i]); 392 } 393 } 394 395 void rawWrite(int b) { 396 super.write(b); 397 } 398 399 void rawPrint(String s) { 400 int len = s.length(); 401 for (int i = 0; i < len; i++) { 402 rawWrite(s.charAt(i)); 403 } 404 } 405 } 406 | Popular Tags |