?? ftpserver.java
字號:
/*
* Copyright 2004-2008 H2 Group. Licensed under the H2 License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.server.ftp;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Properties;
import org.h2.engine.Constants;
import org.h2.server.Service;
import org.h2.store.fs.FileSystem;
import org.h2.util.FileUtils;
import org.h2.util.IOUtils;
import org.h2.util.MathUtils;
import org.h2.util.NetUtils;
/**
* Small FTP Server. Intended for ad-hoc networks in a secure environment.
* Remote connections are possible.
* See also http://cr.yp.to/ftp.html http://www.ftpguide.com/
*/
public class FtpServer implements Service {
public static final String DEFAULT_ROOT = "ftp";
public static final String DEFAULT_READ = "guest";
public static final String DEFAULT_WRITE = "sa";
public static final String DEFAULT_WRITE_PASSWORD = "sa";
private ServerSocket serverSocket;
private int port = Constants.DEFAULT_FTP_PORT;
private int openConnectionCount;
private int maxConnectionCount = 100;
private SimpleDateFormat dateFormatNew = new SimpleDateFormat("MMM dd HH:mm", Locale.ENGLISH);
private SimpleDateFormat dateFormatOld = new SimpleDateFormat("MMM dd yyyy", Locale.ENGLISH);
private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
private String root = DEFAULT_ROOT;
private String writeUserName = DEFAULT_WRITE, writePassword = DEFAULT_WRITE_PASSWORD;
private String readUserName = DEFAULT_READ;
private HashMap tasks = new HashMap();
private FileSystem fs;
private boolean log;
private boolean allowTask;
static final String TASK_SUFFIX = ".task";
private FtpEventListener eventListener;
public void listen() {
try {
while (serverSocket != null) {
Socket s = serverSocket.accept();
boolean stop;
synchronized (this) {
openConnectionCount++;
stop = openConnectionCount > maxConnectionCount;
}
FtpControl c = new FtpControl(s, this, stop);
c.start();
}
} catch (Exception e) {
logError(e);
}
}
void closeConnection() {
synchronized (this) {
openConnectionCount--;
}
}
public ServerSocket createDataSocket() throws SQLException {
ServerSocket dataSocket = NetUtils.createServerSocket(0, false);
return dataSocket;
}
void appendFile(StringBuffer buff, String fileName) throws SQLException {
buff.append(fs.isDirectory(fileName) ? 'd' : '-');
buff.append('r');
buff.append(fs.canWrite(fileName) ? 'w' : '-');
buff.append("------- 1 owner group ");
String size = String.valueOf(fs.length(fileName));
for (int i = size.length(); i < 15; i++) {
buff.append(' ');
}
buff.append(size);
buff.append(' ');
Date now = new Date(), mod = new Date(fs.getLastModified(fileName));
String date;
if (mod.after(now) || Math.abs((now.getTime() - mod.getTime()) / 1000 / 60 / 60 / 24) > 180) {
synchronized (dateFormatOld) {
date = dateFormatOld.format(mod);
}
} else {
synchronized (dateFormatNew) {
date = dateFormatNew.format(mod);
}
}
buff.append(date);
buff.append(' ');
buff.append(FileUtils.getFileName(fileName));
buff.append("\r\n");
}
String formatLastModified(String fileName) {
synchronized (dateFormat) {
return dateFormat.format(new Date(fs.getLastModified(fileName)));
}
}
String getFileName(String path) {
return root + getPath(path);
}
String getPath(String path) {
if (path.indexOf("..") > 0) {
path = "/";
}
while (path.startsWith("/") && root.endsWith("/")) {
path = path.substring(1);
}
while (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
log("path: " + path);
return path;
}
String getDirectoryListing(String directory, boolean listDirectories) throws SQLException {
String[] list = fs.listFiles(directory);
StringBuffer buff = new StringBuffer();
for (int i = 0; list != null && i < list.length; i++) {
String fileName = list[i];
if (!fs.isDirectory(fileName) || (fs.isDirectory(fileName) && listDirectories)) {
appendFile(buff, fileName);
}
}
return buff.toString();
}
public boolean checkUserPassword(String userName, String password) {
return userName.equals(this.writeUserName) && password.equals(this.writePassword);
}
public boolean checkUserPasswordReadOnly(String userName, String param) {
return userName.equals(this.readUserName);
}
public void init(String[] args) throws Exception {
for (int i = 0; args != null && i < args.length; i++) {
String a = args[i];
if ("-ftpPort".equals(a)) {
port = MathUtils.decodeInt(args[++i]);
} else if ("-ftpDir".equals(a)) {
root = FileUtils.normalize(args[++i]);
} else if ("-ftpRead".equals(a)) {
readUserName = args[++i];
} else if ("-ftpWrite".equals(a)) {
writeUserName = args[++i];
} else if ("-ftpWritePassword".equals(a)) {
writePassword = args[++i];
} else if ("-log".equals(a)) {
log = Boolean.valueOf(args[++i]).booleanValue();
} else if ("-ftpTask".equals(a)) {
allowTask = Boolean.valueOf(args[++i]).booleanValue();
}
}
fs = FileSystem.getInstance(root);
root = fs.normalize(root);
}
public String getURL() {
return "ftp://" + NetUtils.getLocalAddress() + ":" + port;
}
public void start() throws SQLException {
fs.mkdirs(root);
serverSocket = NetUtils.createServerSocket(port, false);
}
public void stop() {
try {
serverSocket.close();
} catch (IOException e) {
logError(e);
}
serverSocket = null;
}
public boolean isRunning() {
if (serverSocket == null) {
return false;
}
try {
Socket s = NetUtils.createLoopbackSocket(port, false);
s.close();
return true;
} catch (Exception e) {
return false;
}
}
public boolean getAllowOthers() {
return true;
}
public String getType() {
return "FTP";
}
public String getName() {
return "H2 FTP Server";
}
void log(String s) {
if (log) {
System.out.println(s);
}
}
void logError(Throwable e) {
if (log) {
e.printStackTrace();
}
}
public boolean getAllowTask() {
return allowTask;
}
void startTask(String path) throws IOException {
stopTask(path);
if (path.endsWith(".zip.task")) {
log("expand: " + path);
Process p = Runtime.getRuntime().exec("jar -xf " + path, null, new File(root));
new StreamRedirect(path, p.getInputStream(), null).start();
return;
}
Properties prop = FileUtils.loadProperties(path);
String command = prop.getProperty("command");
String outFile = path.substring(0, path.length() - TASK_SUFFIX.length());
String errorFile = root + "/" + prop.getProperty("error", outFile + ".err.txt");
String outputFile = root + "/" + prop.getProperty("output", outFile + ".out.txt");
log("start process: " + path + " / " + command);
Process p = Runtime.getRuntime().exec(command, null, new File(root));
new StreamRedirect(path, p.getErrorStream(), errorFile).start();
new StreamRedirect(path, p.getInputStream(), outputFile).start();
tasks.put(path, p);
}
private static class StreamRedirect extends Thread {
private InputStream in;
private OutputStream out;
private String outFile;
private String processFile;
StreamRedirect(String processFile, InputStream in, String outFile) {
this.processFile = processFile;
this.in = in;
this.outFile = outFile;
}
private void openOutput() {
if (outFile != null) {
try {
this.out = FileUtils.openFileOutputStream(outFile, false);
} catch (Exception e) {
// ignore
}
outFile = null;
}
}
public void run() {
while (true) {
try {
int x = in.read();
if (x < 0) {
break;
}
openOutput();
if (out != null) {
out.write(x);
}
} catch (IOException e) {
// ignore
}
}
IOUtils.closeSilently(out);
IOUtils.closeSilently(in);
new File(processFile).delete();
}
}
void stopTask(String processName) {
log("kill process: " + processName);
Process p = (Process) tasks.remove(processName);
if (p == null) {
return;
}
p.destroy();
}
/**
* Get the file system used by this FTP server.
*
* @return the file system
*/
public FileSystem getFileSystem() {
return fs;
}
/**
* Set the event listener. Only one listener can be registered.
*
* @param eventListener the new listener, or null to de-register
*/
public void setEventListener(FtpEventListener eventListener) {
this.eventListener = eventListener;
}
/**
* Get the registered event listener.
*
* @return the event listener, or null if non is registered
*/
public FtpEventListener getEventListener() {
return eventListener;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -