1 21 22 package org.jsmtpd.plugins.deliveryServices; 23 24 import java.io.File ; 25 import java.io.FileNotFoundException ; 26 import java.io.IOException ; 27 import java.io.RandomAccessFile ; 28 import java.util.List ; 29 30 import org.apache.commons.logging.Log; 31 import org.apache.commons.logging.LogFactory; 32 import org.jsmtpd.config.ReadConfig; 33 import org.jsmtpd.core.common.PluginInitException; 34 import org.jsmtpd.core.common.delivery.FatalDeliveryException; 35 import org.jsmtpd.core.common.delivery.IDeliveryService; 36 import org.jsmtpd.core.common.delivery.TemporaryDeliveryException; 37 import org.jsmtpd.core.mail.Email; 38 import org.jsmtpd.core.mail.Rcpt; 39 import org.jsmtpd.tools.ByteArrayTool; 40 import org.jsmtpd.tools.rights.IChown; 41 import org.jsmtpd.tools.rights.RightException; 42 import org.jsmtpd.tools.rights.UnixChown; 43 55 public class MaildirWriter implements IDeliveryService { 56 private String basePath="/var/mail"; 57 private String postPath=""; 58 private String host = ReadConfig.getInstance().getLocalDomain(); 59 private Log log = LogFactory.getLog(MaildirWriter.class); 60 private IChown chown = new UnixChown(); 61 private boolean tryChown=false; 62 private boolean crlf=false; 63 64 public void setCrlf(boolean crlf) { 65 this.crlf = crlf; 66 } 67 68 public void setChown(IChown chown) { 69 this.chown = chown; 70 } 71 72 public void doDelivery(Email in, List <Rcpt> rcpts) { 73 log.debug("Starting batch"); 74 for (Rcpt rcpt : rcpts) { 75 try { 76 deliver(in,rcpt); 77 rcpt.setDelivered(Rcpt.STATUS_DELIVERED); 78 log.debug("mail delivered to "+rcpt.getEmailAddress().toString()); 79 } catch (FatalDeliveryException e) { 80 rcpt.setDelivered(Rcpt.STATUS_ERROR_FATAL); 81 log.debug("fatal delivery error for "+rcpt.getEmailAddress().toString()); 82 } catch (TemporaryDeliveryException e) { 83 rcpt.setDelivered(Rcpt.STATUS_ERROR_NOT_FATAL); 84 log.debug("temporary delivery error for "+rcpt.getEmailAddress().toString()); 85 } catch (RightException e) { 86 log.debug("Fatal delivery error for rcpt (right error)"+rcpt.getEmailAddress().toString()); 87 rcpt.setDelivered(Rcpt.STATUS_ERROR_FATAL); 88 } 89 } 90 log.debug("ending batch"); 91 } 92 93 public String getPluginName() { 94 return "Maildir Writer for Jsmtpd"; 95 } 96 97 public void initPlugin() throws PluginInitException { 98 File fl = new File (basePath); 99 fl.mkdir(); 100 } 101 102 public void shutdownPlugin() { 103 } 104 105 private void deliver (Email in, Rcpt rcpt) throws TemporaryDeliveryException,FatalDeliveryException, RightException { 106 String user = rcpt.getEmailAddress().getUser().toLowerCase(); 108 String mpath = basePath+"/"+rcpt.getEmailAddress().getUser()+"/"+postPath+"/"; 110 File fl = new File (mpath); 111 if (!fl.exists()) { 113 fl.mkdirs(); 114 if (tryChown) 115 chown.recursiveChown(fl.toString(),user); 116 } 117 File tmp = new File (mpath+"/tmp/"); 118 if (!tmp.exists()) { 119 tmp.mkdirs(); 120 if (tryChown) 121 chown.recursiveChown(tmp.toString(),user); 122 } 123 File cur = new File (mpath+"/cur/"); 124 if (!cur.exists()) { 125 cur.mkdirs(); 126 if (tryChown) 127 chown.recursiveChown(cur.toString(),user); 128 } 129 File newF = new File (mpath+"/new/"); 130 if (!newF.exists()) { 131 newF.mkdirs(); 132 if (tryChown) 133 chown.chown(newF.toString(),user); 134 } 135 136 String fileName = makeUid(); 138 File target = new File (tmp.getAbsolutePath()+"/"+fileName); 139 RandomAccessFile raf; 140 try { 141 raf = new RandomAccessFile (target,"rw"); 142 raf.seek(0); 143 if (crlf) { 147 raf.write(ByteArrayTool.replaceBytes(in.getDataAsByte(),ByteArrayTool.LF,ByteArrayTool.CRLF)); 148 byte[] lf = new byte[2]; 149 lf[0] = 13; 150 lf[1] = 10; 151 raf.write(lf); 152 } 153 else { 154 raf.write(ByteArrayTool.replaceBytes(in.getDataAsByte(),ByteArrayTool.CRLF,ByteArrayTool.LF)); 155 byte[] lf = new byte[1]; 156 lf[0] = 10; 157 raf.write(lf); 158 } 159 160 raf.close(); 161 } catch (FileNotFoundException e) { 162 log.error("File not found: "+e); 163 throw new TemporaryDeliveryException(e); 164 } catch (IOException e) { 165 log.error("Io error ",e); 166 throw new TemporaryDeliveryException (e); 167 } 168 169 if (tryChown) 170 chown.chown(target.toString(),user); 171 172 File commit = new File (cur.getAbsolutePath()+"/"+fileName); 174 target.renameTo(commit); 175 } 176 177 181 private String makeUid () { 182 return ""+System.currentTimeMillis()+"."+Thread.currentThread().getId()+"."+host; 183 } 184 185 189 public void setBasePath(String basePath) { 190 this.basePath = basePath; 191 } 192 193 197 public void setPostPath(String postPath) { 198 this.postPath = postPath; 199 } 200 201 public void setTryChown(boolean tryChown) { 202 this.tryChown = tryChown; 203 } 204 205 } 206 | Popular Tags |