?? ftpcontrol.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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLException;
import org.h2.engine.Constants;
import org.h2.store.fs.FileSystem;
import org.h2.util.StringUtils;
/**
* The implementation of the control channel of the FTP server.
*/
public class FtpControl extends Thread {
private static final String SERVER_NAME = "Small FTP Server";
private FtpServer server;
private FileSystem fs;
private Socket control;
private FtpData data;
private PrintWriter output;
private String userName;
private boolean connected, readonly;
private String currentDir = "/";
private String serverIpAddress;
private boolean stop;
private String renameFrom;
private boolean replied;
private long restart;
public FtpControl(Socket control, FtpServer server, boolean stop) {
this.server = server;
this.fs = server.getFileSystem();
this.control = control;
this.stop = stop;
}
public void run() {
try {
output = new PrintWriter(new OutputStreamWriter(control.getOutputStream(), Constants.UTF8));
if (stop) {
reply(421, "Too many users");
} else {
reply(220, SERVER_NAME);
// TODO need option to configure the serverIpAddress
serverIpAddress = control.getLocalAddress().getHostAddress().replace('.', ',');
BufferedReader input = new BufferedReader(new InputStreamReader(control.getInputStream()));
while (!stop) {
String command = null;
try {
command = input.readLine();
} catch (IOException e) {
// ignore
}
if (command == null) {
break;
}
process(command);
}
if (data != null) {
data.close();
}
}
} catch (Throwable t) {
server.logError(t);
}
server.closeConnection();
}
private void process(String command) throws SQLException, IOException {
int idx = command.indexOf(' ');
String param = "";
if (idx >= 0) {
param = command.substring(idx).trim();
command = command.substring(0, idx);
}
command = StringUtils.toUpperEnglish(command);
if (command.length() == 0) {
reply(506, "No command");
return;
}
server.log(">" + command);
FtpEventListener listener = server.getEventListener();
FtpEvent event = null;
if (listener != null) {
event = new FtpEvent(this, command, param);
listener.beforeCommand(event);
}
replied = false;
if (connected) {
processConnected(command, param);
}
if (!replied) {
if ("USER".equals(command)) {
userName = param;
reply(331, "Need password");
} else if ("QUIT".equals(command)) {
reply(221, "Bye");
stop = true;
} else if ("PASS".equals(command)) {
if (userName == null) {
reply(332, "Need username");
} else if (server.checkUserPassword(userName, param)) {
reply(230, "Ok");
readonly = false;
connected = true;
} else if (server.checkUserPasswordReadOnly(userName, param)) {
reply(230, "Ok, readonly");
readonly = true;
connected = true;
} else {
reply(431, "Wrong user/password");
}
} else if ("REIN".equals(command)) {
userName = null;
connected = false;
currentDir = "/";
reply(200, "Ok");
} else if ("HELP".equals(command)) {
reply(214, SERVER_NAME);
}
}
if (!replied) {
listener.onUnsupportedCommand(event);
reply(506, "Invalid command");
}
if (listener != null) {
listener.afterCommand(event);
}
}
private void processConnected(String command, String param) throws SQLException, IOException {
switch (command.charAt(0)) {
case 'C':
if ("CWD".equals(command)) {
String path = getPath(param);
String fileName = getFileName(path);
if (fs.exists(fileName) && fs.isDirectory(fileName)) {
if (!path.endsWith("/")) {
path += "/";
}
currentDir = path;
reply(250, "Ok");
} else {
reply(550, "Failed");
}
} else if ("CDUP".equals(command)) {
if (currentDir.length() > 1) {
int idx = currentDir.lastIndexOf("/", currentDir.length() - 2);
currentDir = currentDir.substring(0, idx + 1);
reply(250, "Ok");
} else {
reply(550, "Failed");
}
}
break;
case 'D':
if ("DELE".equals(command)) {
String fileName = getFileName(param);
if (!readonly && fs.exists(fileName) && !fs.isDirectory(fileName) && fs.tryDelete(fileName)) {
if (server.getAllowTask() && fileName.endsWith(FtpServer.TASK_SUFFIX)) {
server.stopTask(fileName);
}
reply(250, "Ok");
} else {
reply(500, "Delete failed");
}
}
break;
case 'L':
if ("LIST".equals(command)) {
processList(param, true);
}
break;
case 'M':
if ("MKD".equals(command)) {
processMakeDir(param);
} else if ("MODE".equals(command)) {
if ("S".equals(StringUtils.toUpperEnglish(param))) {
reply(200, "Ok");
} else {
reply(504, "Invalid");
}
} else if ("MDTM".equals(command)) {
String fileName = getFileName(param);
if (fs.exists(fileName) && !fs.isDirectory(fileName)) {
reply(213, server.formatLastModified(fileName));
} else {
reply(550, "Failed");
}
}
break;
case 'N':
if ("NLST".equals(command)) {
processList(param, false);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -