incubator-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hamm...@apache.org
Subject cvs commit: incubator-ftpserver/src/manifest ftp-admin.mf
Date Mon, 31 Mar 2003 06:50:36 GMT
hammant     2003/03/30 22:50:36

  Added:       src/java/org/apache/ftpserver/util RegularExpr.java
                        StreamConnector.java StreamConnectorObserver.java
                        StringUtils.java VirtualDirectory.java
               src/manifest ftp-admin.mf
  Log:
  Initial cut of FtpServer
  
  Revision  Changes    Path
  1.1                  incubator-ftpserver/src/java/org/apache/ftpserver/util/RegularExpr.java
  
  Index: RegularExpr.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *    "This product includes software developed by the
   *    Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software
   *    itself, if and wherever such third-party acknowledgments
   *    normally appear.
   *
   * 4. The names "Incubator", "FtpServer", and "Apache Software Foundation"
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation. For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: RegularExpr.java,v 1.1 2003/03/31 06:50:36 hammant Exp $
   */
  package org.apache.ftpserver.util;
  
  /**
   * This is a simplified regular character mattching class.
   * Supports *?^[]- pattern characters.
   *
   * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
   */
  public
  class RegularExpr {
  
      private char[] mcPattern;
  
      /**
       * Constructor.
       * @param pattern regular expression
       */
      public RegularExpr(String pattern) {
          mcPattern = pattern.toCharArray();
      }
  
      /**
       * Compare string with a regular expression.
       */
      public boolean isMatch(String name) {
  
          // common pattern - *
          if( (mcPattern.length == 1) && (mcPattern[0] == '*') ) {
              return true;
          }
  
          return isMatch(name.toCharArray(), 0, 0);
      }
  
  
      /**
       * Is a match?
       */
      private boolean isMatch(char[] strName, int strIndex, int patternIndex) {
  
          while(true) {
  
              // no more pattern characters
              // if no more strName characters - return true
              if(patternIndex >= mcPattern.length) {
                 return strIndex == strName.length;
              }
  
              char pc = mcPattern[patternIndex++];
              switch(pc) {
  
                  // Match a single character in the range
                  // If no more strName character - return false
                  case '[' :
  
                      // no more string character - returns false
                      // example : pattern = ab[^c] and string = ab
                      if(strIndex >= strName.length) {
                          return false;
                      }
  
                      char fc = strName[strIndex++];
                      char lastc = 0;
                      boolean bMatch = false;
                      boolean bNegete = false;
                      boolean bFirst = true;
  
                      while(true) {
  
                          // single character match
                          // no more pattern character - error condition.
                          if(patternIndex>=mcPattern.length) {
                              return false;
                          }
                          pc = mcPattern[patternIndex++];
  
                          // end character - break out the loop
                          // if end bracket is the first character - always a match.
                          // example pattern - [], [^]
                          if(pc == ']') {
                              if (bFirst) {
                                  bMatch = true;
                              }
                              break;
                          }
  
                          // if already matched - just read the rest till we get ']'.
                          if(bMatch) {
                              continue;
                          }
  
                          // if the first character is the negete
                          // character - inverse the matching condition
                          if((pc == '^') && bFirst) {
                             bNegete = true;
                             continue;
                          }
                          bFirst = false;
  
                          // '-' range check
                          if(pc == '-') {
  
                              // pattern string is [a-  error condition.
                              if(patternIndex>=mcPattern.length) {
                                  return false;
                              }
  
                              // read the high range character and compare.
                              pc = mcPattern[patternIndex++];
                              bMatch = (fc>=lastc) && (fc<=pc);
                              lastc = pc;
                          }
  
                          // Single character match check. It might also be the
                          // low range character.
                          else {
                              lastc = pc;
                              bMatch = (pc == fc);
                          }
                      }
  
                      // no match - return false.
                      if(bNegete) {
                          if(bMatch) {
                              return false;
                          }
                      }
                      else {
                          if(!bMatch) {
                              return false;
                          }
                      }
                      break;
  
  
                  // * - skip zero or more characters
                  // No more patern character - return true
                  // Increment strIndex till the rest of the pattern matches.
                  case '*' :
  
                      // no more string character remaining  - returns true
                      if(patternIndex >= mcPattern.length) {
                          return true;
                      }
  
                      // compare rest of the string
                      do {
                        if(isMatch(strName, strIndex++, patternIndex)) {
                            return true;
                        }
                      }
                      while(strIndex < strName.length);
  
                      // Example pattern is (a*b) and the string is (adfdc).
                      return false;
  
  
                  // ? - skip one character - increment strIndex.
                  // If no more strName character - return false.
                  case '?' :
  
                      // already at the end - no more character - returns false
                      if(strIndex >= strName.length) {
                          return false;
                      }
                      strIndex++;
                      break;
  
  
                  // match character.
                  default:
  
                      // already at the end - no match
                      if (strIndex >= strName.length) {
                          return false;
                      }
  
                      // the characters are not equal - no match
                      if(strName[strIndex++] != pc) {
                          return false;
                      }
                      break;
              }
          }
      }
  
  }
  
  
  
  1.1                  incubator-ftpserver/src/java/org/apache/ftpserver/util/StreamConnector.java
  
  Index: StreamConnector.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *    "This product includes software developed by the
   *    Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software
   *    itself, if and wherever such third-party acknowledgments
   *    normally appear.
   *
   * 4. The names "Incubator", "FtpServer", and "Apache Software Foundation"
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation. For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: StreamConnector.java,v 1.1 2003/03/31 06:50:36 hammant Exp $
   */
  package org.apache.ftpserver.util;
  
  import java.io.InputStream;
  import java.io.OutputStream;
  
  /**
   * Connect one <code>java.io.InputStream</code> with a
   * <code>java.io.OutputStream</code>.
   *
   * Features:
   * <ul>
   *   <li> Buffered transfer or not (default unbuffered).</li>
   *   <li> Threaded transfer or not (default false).</li>
   *   <li> Set transfer rate limit (default no limit).</li>
   *   <li> Stop transfer at any time.</li>
   *   <li> Get current byte transferred.</li>
   *   <li> Transfer notification</li>
   * </ul>
   * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
   */
  public
  class StreamConnector implements Runnable {
  
      private InputStream mInStream;
      private OutputStream mOutStream;
  
      private boolean mbThreaded    = false;
      private boolean mbBuffered    = false;
      private boolean mbStopRequest = false;
  
      private int  miTransferLimit  = 0;
      private long mlTransferSize   = 0;
  
      private Exception mExp        = null;
      private Thread mConThread     = null; // stream conneector thread
  
      private StreamConnectorObserver mObserver = null;
  
  
      /**
       * Constructors
       * @param in pipe input
       * @param out pipe output
       */
      public StreamConnector(InputStream in, OutputStream out) {
          mInStream = in;
          mOutStream = out;
      }
  
      /**
       * Set stream connector observer.
       */
      public synchronized void setObserver(StreamConnectorObserver obsr) {
          mObserver = obsr;
      }
  
      /**
       * Set buffered transferred property.
       */
      public void setIsBuffered(boolean buf) {
          mbBuffered = buf;
      }
  
      /**
       * Get is buffered.
       */
      public boolean getIsBuffered() {
          return mbBuffered;
      }
  
      /**
       * Set threaded transfer property.
       */
      public void setIsThreaded(boolean thr) {
          mbThreaded = thr;
      }
  
      /**
       * Is the data transfer threaded?
       */
      public boolean getIsThreaded() {
          return mbThreaded;
      }
  
      /**
       * Get exception.
       */
      public Exception getException() {
          return mExp;
      }
  
      /**
       * Get transferred size in bytes.
       */
      public long getTransferredSize() {
          return mlTransferSize;
      }
  
      /**
       * Get transfer limit in bytes/second.
       */
      public int getMaxTransferRate() {
          return miTransferLimit;
      }
  
      /**
       * Set transfer limit - bytes/second.
       */
      public void setMaxTransferRate(int limit) {
          miTransferLimit = limit;
      }
  
      /**
       * Check exception status.
       */
      public boolean hasException() {
          return mExp != null;
      }
  
      /**
       * Stop data transfer.
       */
      public synchronized void stopTransfer() {
          mbStopRequest = true;
          if(mConThread != null) {
              mConThread.interrupt();
          }
          IoUtils.close(mInStream);
          IoUtils.close(mOutStream);
          mConThread = null;
          mInStream = null;
          mOutStream = null;
      }
  
      /**
       * Is stopped?
       */
      public boolean isStopped() {
          return mbStopRequest;
      }
  
      /**
       * Connect two streams.
       */
      public void connect() {
  
          // error test
          if(mbStopRequest) {
              throw new IllegalStateException("Data already transferred.");
          }
          if(mConThread != null) {
              throw new IllegalStateException("Streams already connected.");
          }
  
          // now connect
          if(mbThreaded) {
              new Thread(this).start();
          }
          else {
              run();
          }
      }
  
  
      /**
       * Transfer data from one stream to another.
       */
      public void run() {
          long startTime = System.currentTimeMillis();
          mConThread = Thread.currentThread();
          InputStream in = mInStream;
          OutputStream out = mOutStream;
          byte[] buff = new byte[4096];
  
          if(mbBuffered) {
              in = IoUtils.getBufferedInputStream(in);
              out = IoUtils.getBufferedOutputStream(out);
          }
  
          try {
             while(! (mbStopRequest || mConThread.isInterrupted()) ) {
  
                 // check transfer rate
                 if(miTransferLimit > 0) {
                     long interval = System.currentTimeMillis() - startTime;
  
                     // prevent "divide by zero" exception
                     if(interval == 0) {
                         interval = 1;
                     }
  
                     int rate = (int)((mlTransferSize*1000)/interval);
                     if(rate > miTransferLimit) {
                         try { Thread.sleep(100); } catch(InterruptedException ex) {break;}
                         continue;
                     }
                 }
  
                 // read data
                 int count = in.read(buff);
                 if(count == -1) {
                     break;
                 }
  
                 // write data
                 out.write(buff, 0, count);
                 mlTransferSize += count;
                 notifyObserver(count);
             }
             out.flush();
          }
          catch(Exception ex) {
              mExp = ex;
          }
          finally {
              synchronized (this) {
                  mbStopRequest = true;
                  IoUtils.close(in);
                  IoUtils.close(out);
                  notifyObserver(-1);
                  mConThread = null;
              }
          }
      }
  
      /**
       * Notify the observer.
       * @param sz bytes transferred
       */
      private void notifyObserver(int sz) {
          StreamConnectorObserver observer = mObserver;
          if(observer != null) {
              observer.dataTransferred(sz);
          }
      }
  
      /**
       * Last defense to stop thread.
       */
      protected void finalize() throws Throwable {
          stopTransfer();
          super.finalize();
      }
  
  }
  
  
  
  1.1                  incubator-ftpserver/src/java/org/apache/ftpserver/util/StreamConnectorObserver.java
  
  Index: StreamConnectorObserver.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *    "This product includes software developed by the
   *    Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software
   *    itself, if and wherever such third-party acknowledgments
   *    normally appear.
   *
   * 4. The names "Incubator", "FtpServer", and "Apache Software Foundation"
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation. For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: StreamConnectorObserver.java,v 1.1 2003/03/31 06:50:36 hammant Exp $
   */
  package org.apache.ftpserver.util;
  
  /**
   * This interface observes stream connector activity.
   *
   * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
   */
  public
  interface StreamConnectorObserver {
      /**
       * Data has been transferred.
       *
       * @size transferred byte size. If finished, it is -1.
       */
      void dataTransferred(int size);
  }
  
  
  
  1.1                  incubator-ftpserver/src/java/org/apache/ftpserver/util/StringUtils.java
  
  Index: StringUtils.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *    "This product includes software developed by the
   *    Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software
   *    itself, if and wherever such third-party acknowledgments
   *    normally appear.
   *
   * 4. The names "Incubator", "FtpServer", and "Apache Software Foundation"
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation. For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: StringUtils.java,v 1.1 2003/03/31 06:50:36 hammant Exp $
   */
  package org.apache.ftpserver.util;
  
  
  
  /**
   * String utility methods.
   *
   * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
   */
  
  public
  class StringUtils {
  
      private static final char SEPARATOR = '\n';
  
      /**
       * This is a string replacement method.
       */
      public static String replaceString(String source, String oldStr, String newStr) {
          StringBuffer sb = new StringBuffer(source.length());
          int sind = 0;
          int cind = 0;
          while ((cind=source.indexOf(oldStr, sind)) != -1) {
              sb.append(source.substring(sind, cind));
              sb.append(newStr);
              sind = cind + oldStr.length();
          }
          sb.append(source.substring(sind));
          return sb.toString();
      }
  
  
      /**
       * This method is used to insert HTML block dynamically
       *
       * @param source the HTML code to be processes
       * @param bReplaceNl if true '\n' will be replaced by <br>
       * @param bReplaceTag if true '<' will be replaced by &lt; and
       *                          '>' will be replaced by &gt;
       * @param bReplaceQuote if true '\"' will be replaced by &quot;
       */
      public static String formatHtml(String source,
                                      boolean bReplaceNl,
                                      boolean bReplaceTag,
                                      boolean bReplaceQuote) {
  
          StringBuffer sb = new StringBuffer();
          int len = source.length();
          for (int i=0; i<len; i++) {
              char c = source.charAt(i);
              switch (c) {
              case '\"':
                  if (bReplaceQuote)sb.append("&quot;");
                  else sb.append(c);
                  break;
  
              case '<':
                  if (bReplaceTag) sb.append("&lt;");
                  else sb.append(c);
                  break;
  
              case '>':
                  if (bReplaceTag) sb.append("&gt;");
                  else sb.append(c);
                  break;
  
              case '\n':
                  if (bReplaceNl) {
                      if (bReplaceTag) sb.append("&lt;br&gt;");
                      else sb.append("<br>");
                  } else {
                      sb.append(c);
                  }
                  break;
  
              case '\r':
                  break;
  
              case '&':
                  sb.append("&amp;");
                  break;
  
              default:
                  sb.append(c);
                  break;
              }
          }
          return sb.toString();
      }
  
      /**
       * Pad string object
       */
      public static String pad(String src,
                               char padChar,
                               boolean rightPad,
                               int totalLength) {
  
          int srcLength = src.length();
          if (srcLength >= totalLength) {
              return src;
          }
  
          int padLength = totalLength - srcLength;
          StringBuffer sb = new StringBuffer(padLength);
          for(int i=0; i<padLength; ++i) {
              sb.append(padChar);
          }
  
          if (rightPad) {
              return src + sb.toString();
          }
          else {
              return sb.toString() + src;
          }
      }
  
      /**
       * Get hex string from byte array
       */
      public static String toHexString(byte[] res) {
          StringBuffer sb = new StringBuffer(res.length << 1);
          for(int i=0; i<res.length; i++) {
              String digit = Integer.toHexString(0xFF & res[i]);
              if (digit.length() == 1) {
                  digit = '0' + digit;
              }
              sb.append(digit);
          }
          return sb.toString().toUpperCase();
      }
  
      /**
       * Get byte array from hex string
       */
      public static byte[] toByteArray(String hexString) {
          int arrLength = hexString.length() >> 1;
          byte buff[] = new byte[arrLength];
          for(int i=0; i<arrLength; i++) {
              int index = i << 1;
              String digit = hexString.substring(index, index+2);
              buff[i] = (byte)Integer.parseInt(digit, 16);
          }
          return buff;
      }
  
  }
  
  
  
  1.1                  incubator-ftpserver/src/java/org/apache/ftpserver/util/VirtualDirectory.java
  
  Index: VirtualDirectory.java
  ===================================================================
  /* ====================================================================
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *    "This product includes software developed by the
   *    Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software
   *    itself, if and wherever such third-party acknowledgments
   *    normally appear.
   *
   * 4. The names "Incubator", "FtpServer", and "Apache Software Foundation"
   *    must not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation. For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * $Id: VirtualDirectory.java,v 1.1 2003/03/31 06:50:36 hammant Exp $
   */
  package org.apache.ftpserver.util;
  
  import java.io.File;
  import java.io.Writer;
  import java.io.IOException;
  import java.io.Serializable;
  import java.util.Comparator;
  import java.util.Arrays;
  import java.util.Date;
  import java.util.StringTokenizer;
  
  /**
   * This class is responsible to handle all virtual directory activities.
   *
   * @author <a href="mailto:rana_b@yahoo.com">Rana Bhattacharyya</a>
   */
  public
  class VirtualDirectory implements Serializable {
  
      private static final String NEWLINE  = "\r\n";
      private static final String DELIM    = " ";
  
      private String mstRoot        = "/";
      private String mstCurrDir     = "/";
  
      private boolean mbWritePerm   = false;
  
  
      /**
       * Default constructor does nothing
       */
      public VirtualDirectory() {
      }
  
      /**
       * Set write permission.
       */
      public void setWritePermission(boolean perm) {
          mbWritePerm = perm;
      }
  
      /**
       * Set root directory. Root directory string will always
       * end with '/'.
       */
      public void setRootDirectory(File root) {
  
         if(root == null) {
             root = new File("/");
         }
         mstRoot = normalizeSeparateChar(root.getAbsolutePath());
  
         // if not ends with '/' - add one
         if(mstRoot.charAt(mstRoot.length()-1) != '/') {
             mstRoot = mstRoot + '/';
         }
         mstCurrDir = "/";
      }
  
      /**
       * Set root directory.
       */
      public void setRootDirectory(String root) throws IOException {
         mstRoot = normalizeSeparateChar(root);
  
         // if not ends with '/' - add one
         if(mstRoot.charAt(mstRoot.length()-1) != '/') {
             mstRoot = mstRoot + '/';
         }
         mstCurrDir = "/";
      }
  
      /**
       * Get write permission in this system
       */
      public boolean getWritePermission() {
          return mbWritePerm;
      }
  
      /**
       * Get current working directory.
       */
      public String getCurrentDirectory() {
          return mstCurrDir;
      }
  
  
      /**
       * Get root directory.
       */
      public String getRootDirectory() {
          return mstRoot;
      }
  
  
      /**
       * Get physical name (wrt the machine root).
       */
      public String getPhysicalName(String virtualName) {
          virtualName = normalizeSeparateChar(virtualName);
          return replaceDots(virtualName);
      }
  
  
      /**
       * Get virtual name (wrt the virtual root).
       * The return value will never end with '/' unless it is '/'.
       */
      public String getAbsoluteName(String virtualName) {
          virtualName = normalizeSeparateChar(virtualName);
          String physicalName = replaceDots(virtualName);
  
          String absoluteName = physicalName.substring(mstRoot.length()-1).trim();
          return removeLastSlash(absoluteName);
      }
  
  
      /**
       * Get virtual name (wrt the virtual root). The virtual
       * name will never end with '/' unless it is '/'.
       */
      public String getVirtualName(String physicalName) {
          physicalName = normalizeSeparateChar(physicalName);
          if (!physicalName.startsWith(mstRoot)) {
              return null;
          }
  
          String virtualName = physicalName.substring(mstRoot.length()-1).trim();
          return removeLastSlash(virtualName);
      }
  
  
      /**
       * Change directory. The current directory will never have '/'
       * at the end unless it is '/'.
       * @param dirName change the current working directory.
       * @return true if success
       */
      public boolean changeDirectory(String virtualDir) {
  
          String physcialDir = getPhysicalName(virtualDir);
          if (physcialDir.equals("")) {
              physcialDir = "/";
          }
  
          File dirFl = new File(physcialDir);
          if (dirFl.exists() && dirFl.isDirectory()) {
              mstCurrDir = physcialDir.substring(mstRoot.length() - 1).trim();
              mstCurrDir = removeLastSlash(mstCurrDir);
              return true;
          }
  
          return false;
      }
  
  
      /**
       * Check read permission.
       */
      public boolean hasReadPermission(String fileName, boolean bPhysical) {
          if(bPhysical) {
              fileName = normalizeSeparateChar(fileName);
          }
          else {
              fileName = getPhysicalName(fileName);
          }
  
          if(!fileName.startsWith(mstRoot)) {
              return false;
          }
  
          return new File(fileName).canRead();
      }
  
  
      /**
       * Chech file write/delete permission.
       */
      public boolean hasWritePermission(String fileName, boolean bPhysical) {
  
          // no write permission
          if(!mbWritePerm) {
              return false;
          }
  
          // if virtual name - get the physical name
          if(bPhysical) {
              fileName = normalizeSeparateChar(fileName);
          }
          else {
              fileName = getPhysicalName(fileName);
          }
  
          if(!fileName.startsWith(mstRoot)) {
              return false;
          }
  
          return new File(fileName).canWrite();
      }
  
  
      /**
       * Check file create permission.
       */
      public boolean hasCreatePermission(String fileName, boolean bPhysical) {
  
          // no write permission
          if(!mbWritePerm) {
              return false;
          }
  
          // if virtual name - get the physical name
          if(bPhysical) {
              fileName = normalizeSeparateChar(fileName);
          }
          else {
              fileName = getPhysicalName(fileName);
          }
  
          return fileName.startsWith(mstRoot);
      }
  
  
      /**
       * Print file list. Detail listing.
       * <pre>
       *   -a : display all (including hidden files)
       * </pre>
       * @return true if success
       */
      public boolean printList(String argument, Writer out) throws IOException {
  
          FileLister lister = new FileLister(argument);
          File[] flLst = lister.getFiles();
          if (flLst == null) {
              return false;
          }
          else {
              for(int i=0; i<flLst.length; i++) {
                  if ( (!lister.isAll()) && flLst[i].isHidden() ) {
                      continue;
                  }
                  printLine(flLst[i], out);
                  out.write(NEWLINE);
              }
              return true;
          }
      }
  
  
      /**
       * Print file list.
       * <pre>
       *   -l : detail listing
       *   -a : display all (including hidden files)
       * </pre>
       * @return true if success
       */
      public boolean printNList(String argument, Writer out) throws IOException {
  
          FileLister lister = new FileLister(argument);
          File[] flLst = lister.getFiles();
          if (flLst == null) {
              return false;
          }
          else {
              for(int i=0; i<flLst.length; i++) {
                  if ( (!lister.isAll()) && flLst[i].isHidden() ) {
                      continue;
                  }
                  if(lister.isDetail()) {
                      printLine(flLst[i], out);
                  }
                  else {
                      out.write(getName(flLst[i]));
                  }
                  out.write(NEWLINE);
              }
              return true;
          }
      }
  
      /**
       * Get file owner.
       */
      private String getOwner(File fl) {
          return "user";
      }
  
  
      /**
       * Get group name
       */
      private String getGroup(File fl) {
          return "group";
      }
  
  
      /**
       * Get link count
       */
      private String getLinkCount(File fl) {
          if(fl.isDirectory()) {
              return String.valueOf(3);
          }
          else {
              return String.valueOf(1);
          }
      }
  
  
      /**
       * Get size
       */
      private String getLength(File fl) {
          String initStr = "            ";
          long sz = 0;
          if(fl.isFile()) {
              sz = fl.length();
          }
          String szStr = String.valueOf(sz);
          if(szStr.length() > initStr.length()) {
              return szStr;
          }
          return initStr.substring(0, initStr.length() - szStr.length()) + szStr;
      }
  
  
      /**
       * Get last modified date string.
       */
      private String getLastModified(File fl) {
          long modTime = fl.lastModified();
          Date date = new Date(modTime);
          return DateUtils.getUnixDate(date);
      }
  
  
      /**
       * Get file name.
       */
      private String getName(File fl) {
          return fl.getName();
      }
  
  
      /**
       * Get permission string.
       */
      private String getPermission(File fl) {
  
          StringBuffer sb = new StringBuffer(13);
          if(fl.isDirectory()) {
              sb.append('d');
          }
          else {
              sb.append('-');
          }
  
          if (fl.canRead()) {
              sb.append('r');
          }
          else {
              sb.append('-');
          }
  
          if (mbWritePerm && fl.canWrite()) {
              sb.append('w');
          }
          else {
              sb.append('-');
          }
          sb.append("-------");
          return sb.toString();
      }
  
  
      /**
       * Normalize separate characher. Separate character should be '/' always.
       */
      private String normalizeSeparateChar(String pathName) {
         pathName = pathName.replace(File.separatorChar, '/');
         pathName = pathName.replace('\\', '/');
         return pathName;
      }
  
  
      /**
       * Replace dots. Returns physical name.
       * @param inArg the virtaul name
       */
      private String replaceDots(String inArg) {
  
          // get the starting directory
          String resArg;
          if(inArg.charAt(0) != '/') {
              resArg = mstRoot + mstCurrDir.substring(1);
          }
          else {
              resArg = mstRoot;
          }
  
          // strip last '/'
          if(resArg.charAt(resArg.length() -1) == '/') {
              resArg = resArg.substring(0, resArg.length()-1);
          }
  
          // replace ., ~ and ..
          StringTokenizer st = new StringTokenizer(inArg, "/");
          while(st.hasMoreTokens()) {
  
              String tok = st.nextToken().trim();
  
              // . => current directory
              if(tok.equals(".")) {
                  continue;
              }
  
              // .. => parent directory (if not root)
              if(tok.equals("..")) {
                  if(resArg.startsWith(mstRoot)) {
                    int slashIndex = resArg.lastIndexOf('/');
                    if(slashIndex != -1) {
                      resArg = resArg.substring(0, slashIndex);
                    }
                  }
                  continue;
              }
  
              // ~ => home directory (in this case /)
              if (tok.equals("~")) {
                  resArg = mstRoot.substring(0, mstRoot.length()-1).trim();
                  continue;
              }
  
              resArg = resArg + '/' + tok;
          }
  
          // add last slash if necessary
          if( !inArg.equals("") && (inArg.charAt(inArg.length()-1)=='/') ) {
              resArg = resArg + '/';
          }
  
          // final check
          if (resArg.length() < mstRoot.length()) {
              resArg = mstRoot;
          }
  
          return resArg;
      }
  
  
      /**
       * Get each directory line.
       */
      private void printLine(File fl, Writer out) throws IOException {
          out.write(getPermission(fl));
          out.write(DELIM);
          out.write(DELIM);
          out.write(DELIM);
          out.write(getLinkCount(fl));
          out.write(DELIM);
          out.write(getOwner(fl));
          out.write(DELIM);
          out.write(getGroup(fl));
          out.write(DELIM);
          out.write(getLength(fl));
          out.write(DELIM);
          out.write(getLastModified(fl));
          out.write(DELIM);
          out.write(getName(fl));
      }
  
      /**
       * If the string is not '/', remove last slash.
       */
      private String removeLastSlash(String str) {
          if ( (str.length()>1) && (str.charAt(str.length()-1)=='/') ) {
              str = str.substring(0, str.length()-1);
          }
          return str;
      }
  
  
  
      //////////////////////////////////////////////////////////////////////
      //////////////////////////////////////////////////////////////////////
      /**
       * Inner class to compare files
       */
      private class FileComparator implements Comparator {
          public int compare(Object o1, Object o2) {
              String s1 = ((File)o1).getName();
              String s2 = ((File)o2).getName();
              return s1.compareTo(s2);
          }
      }
  
  
      /////////////////////////////////////////////////////////////////////
      /////////////////////////////////////////////////////////////////////
      /**
       * File lister to list files properly
       */
      private class FileLister {
  
          private File[] files = null;
          private boolean bAll = false;
          private boolean bDetail = false;
  
          /**
           * Parse arguments - get options and get file list.
           */
          public FileLister(String argument) {
              String lsDirName = "./";
              String options = "";
              String pattern   = "*";
  
              // get options, directory name and pattern
              if(argument != null) {
                  argument = argument.trim();
                  StringBuffer optionsSb = new StringBuffer(4);
                  StringTokenizer st = new StringTokenizer(argument, " ");
                  while(st.hasMoreTokens()) {
                      String token = st.nextToken();
                      if(token.charAt(0) == '-') {
                          if (token.length() > 1) {
                              optionsSb.append(token.substring(1));
                          }
                      }
                      else {
                         lsDirName = token;
                      }
                  }
                  options = optionsSb.toString();
              }
  
              // check options
              bAll = options.indexOf('a') != -1;
              bDetail = options.indexOf('l') != -1;
  
              // check pattern
              lsDirName = getPhysicalName(lsDirName);
              File lstDirObj = new File(lsDirName);
              if ( !(lstDirObj.exists() && lstDirObj.isDirectory()) ) {
                  int slashIndex = lsDirName.lastIndexOf('/');
                  if( (slashIndex != -1) && (slashIndex != (lsDirName.length() -1)) ) {
                      pattern = lsDirName.substring(slashIndex+1);
                      lsDirName = lsDirName.substring(0, slashIndex+1);
                  }
              }
  
              // check directory
              lstDirObj = new File(lsDirName);
              if(!lstDirObj.exists()) {
                  return;
              }
              if(!lstDirObj.isDirectory()) {
                  return;
              }
  
              // get file list
              if ( (pattern == null) || pattern.equals("*") || pattern.equals("") ) {
                  files = lstDirObj.listFiles();
              }
              else {
                  files = lstDirObj.listFiles(new FileRegularFilter(pattern));
              }
              //Arrays.sort(files, new FileComparator());
          }
  
  
          /**
           * Get files
           */
          public File[] getFiles() {
              return files;
          }
  
          /**
           * Display all flag
           */
          public boolean isAll() {
              return bAll;
          }
  
          /**
           * Display detail flag
           */
          public boolean isDetail() {
              return bDetail;
          }
      }
  
  }
  
  
  
  1.1                  incubator-ftpserver/src/manifest/ftp-admin.mf
  
  Index: ftp-admin.mf
  ===================================================================
  Manifest-Version: 1.0
  Main-Class: org.apache.ftpserver.gui.FtpAdmin
  
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@incubator.apache.org
For additional commands, e-mail: cvs-help@incubator.apache.org


Mime
View raw message