import java.io.*;
import java.util.*;
import javax.swing.*;
//jcifs.samba.org
import jcifs.smb.*;
import javaforce.*;
/**
*
* @author pquiring
*/
public class SiteSMB extends Site {
private String url;
private NtlmPasswordAuthentication auth;
@Override
public boolean connect(SiteDetails sd) {
try {
setStatus("Connecting...");
url = "smb://" + sd.host;
if (!sd.remoteDir.startsWith("/"))
remoteDir.setText("/" + sd.remoteDir);
else
remoteDir.setText(sd.remoteDir);
auth = new NtlmPasswordAuthentication("domain", sd.username, sd.password);
SmbFile file = new SmbFile(url + remoteDir.getText(), auth);
if (!file.exists()) throw new Exception("Resource not found");
if (!remote_ls()) throw new Exception("Connection failed");
setStatus(null);
} catch (Exception e) {
JF.showMessage("Error", "Error:" + e);
JFLog.log(e);
closeSite();
return false;
}
return true;
}
@Override
public void disconnect() {
}
public String remote_pwd() {
return remoteDir.getText();
}
public String getListing() {
//attr node owner group filesize mth dy time filename //time=year if older than 1 year
StringBuffer str = new StringBuffer();
try {
setStatus("Listing");
SmbFile folder = new SmbFile(url + remoteDir.getText() + "/", auth);
SmbFile lst[] = folder.listFiles();
for(int a=0;a<lst.length;a++) {
String name = lst[a].getName();
if (lst[a].isDirectory()) {
str.append("drwx------ 1 smb smb 0 1 1 12:00 " + name.substring(0, name.length() - 1) + "\n");
} else {
str.append("-rwx------ 1 smb smb " + lst[a].length() + " 1 1 12:00 " + name + "\n");
}
}
setStatus(null);
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("Error:" + e);
return null;
}
return str.toString();
}
public boolean remote_ls() {
try {
String ls = getListing();
if (ls == null) return false;
parseRemote(remote_pwd(), ls);
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("Error:" + e);
}
return true;
}
@Override
public void remote_chdir(String path) {
String wd = remoteDir.getText();
path = path.replaceAll("\\\\", "/");
if (path.equals(".")) {
//do nothing
} else if (path.equals("..")) {
//remove last path element
int idx = wd.lastIndexOf('/');
if (idx == -1) {
wd = "/";
} else {
wd = wd.substring(0, idx);
}
} else {
if (path.indexOf("/") != -1) {
//absolute path
wd = path;
} else {
//add path element
if (!wd.endsWith("/")) wd += "/";
wd += path;
}
}
remoteDir.setText(wd);
parseRemote(wd, getListing());
}
@Override
public void download() {
aborted = false;
localFolderStack = new ArrayList<String>();
remoteFolderStack = new ArrayList<String>();
new Thread() {
@Override
public void run() {
setStatus("Downloading");
download_files();
setStatus(null);
}
public void download_files() {
try {
int rows[] = remoteFiles.getSelectedRows();
if (rows.length == 0) return;
SiteFile sf[] = new SiteFile[rows.length];
for(int idx=0;idx<rows.length;idx++) {
sf[idx] = (SiteFile)remoteFilesTableModel.getValueAt(rows[idx], 0);
}
for(int idx=0;idx<sf.length;idx++) {
if (sf[idx].getText().equals(".")) continue;
if (sf[idx].getText().equals("..")) continue;
totalFileSize = sf[idx].filesize;
if (sf[idx].isDir) {
remoteFolderStack.add(remoteDir.getText());
remote_chdir(sf[idx].getText());
}
if (sf[idx].isLink && !sf[idx].isDir) {
//test if dir
String d1 = remoteDir.getText();
remote_chdir(sf[idx].getText());
String d2 = remoteDir.getText();
if (!d1.equals(d2)) {
remoteFolderStack.add(d1);
sf[idx].isDir = true;
}
}
if (sf[idx].isDir) {
//already remote_chdir()
localFolderStack.add(localDir.getText());
local_mkdir(localDir.getText() + "/" + sf[idx].getText());
local_chdir(sf[idx].getText());
remoteFiles.selectAll();
download_files();
remote_chdir(remoteFolderStack.remove(remoteFolderStack.size() - 1));
local_chdir(localFolderStack.remove(localFolderStack.size() - 1));
continue;
}
File remoteFile = new File(remoteDir.getText() + "/" + sf[idx].getText());
File localFile = new File(localDir.getText() + "/" + sf[idx].getText());
JFLog.log("download:" + remoteFile + "->" + localFile);
addLog("download:" + remoteFile + "->" + localFile);
setStatus("download:" + remoteFile + "->" + localFile);
setTotalFileSize(sf[idx].filesize);
download_file(remoteFile, localFile);
if (aborted) break;
}
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("" + e);
}
local_chdir("."); //refresh
}
}.start();
}
public void download_file(File remote, File local) {
SmbFile file;
try {
file = new SmbFile(url + remoteDir.getText() + "/" + remote.getName(), auth);
InputStream fis = file.getInputStream();
int len = (int)file.length();
byte buf[] = new byte[64 * 1024];
OutputStream fos = new FileOutputStream(local);
int copied = 0;
while ((len > 0) && (!aborted)) {
int read = fis.read(buf);
if (read == -1) throw new Exception("file i/o error");
if (read > 0) {
fos.write(buf, 0, read);
len -= read;
copied += read;
setProgress(copied);
}
}
fos.close();
fis.close();
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("" + e);
}
}
@Override
public void upload() {
aborted = false;
localFolderStack = new ArrayList<String>();
remoteFolderStack = new ArrayList<String>();
new Thread() {
@Override
public void run() {
setStatus("Uploading");
upload_files();
setStatus(null);
}
public void upload_files() {
try {
int rows[] = localFiles.getSelectedRows();
if (rows.length == 0) return;
SiteFile sf[] = new SiteFile[rows.length];
for(int idx=0;idx<rows.length;idx++) {
sf[idx] = (SiteFile)localFilesTableModel.getValueAt(rows[idx], 0);
}
for(int idx=0;idx<sf.length;idx++) {
if (sf[idx].getText().equals(".")) continue;
if (sf[idx].getText().equals("..")) continue;
totalFileSize = sf[idx].filesize;
if (sf[idx].isDir) {
localFolderStack.add(localDir.getText());
local_chdir(sf[idx].getText());
}
if (sf[idx].isLink && !sf[idx].isDir) {
//test if dir
String d1 = localDir.getText();
local_chdir(sf[idx].getText());
String d2 = localDir.getText();
if (!d1.equals(d2)) {
localFolderStack.add(d1);
sf[idx].isDir = true;
}
}
if (sf[idx].isDir) {
//already local_chdir()
remoteFolderStack.add(remoteDir.getText());
remote_mkdir(sf[idx].getText());
remote_chdir(sf[idx].getText());
localFiles.selectAll();
upload_files();
remote_chdir(remoteFolderStack.remove(remoteFolderStack.size() - 1));
local_chdir(localFolderStack.remove(localFolderStack.size() - 1));
continue;
}
File remoteFile = new File(remoteDir.getText() + "/" + sf[idx].getText());
File localFile = new File(localDir.getText() + "/" + sf[idx].getText());
JFLog.log("upload:" + localFile + "->" + remoteFile);
addLog("upload:" + localFile + "->" + remoteFile);
setStatus("upload:" + localFile + "->" + remoteFile);
setTotalFileSize((int)localFile.length());
upload_file(localFile, remoteFile);
if (aborted) break;
}
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("" + e);
}
remote_chdir("."); //refresh
}
}.start();
}
public void upload_file(File local, File remote) {
SmbFile file;
try {
file = new SmbFile(url + remoteDir.getText() + "/" + remote.getName(), auth);
if (file.exists()) {
file.delete();
}
file.createNewFile();
OutputStream fos = file.getOutputStream();
byte buf[] = new byte[64 * 1024];
InputStream fis = new FileInputStream(local);
int len = fis.available();
int copied = 0;
while ((len > 0) && (!aborted)) {
int read = fis.read(buf);
if (read == -1) throw new Exception("file i/o error");
if (read > 0) {
fos.write(buf, 0, read);
len -= read;
copied += read;
setProgress(copied);
}
}
fos.close();
fis.close();
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("" + e);
}
}
public void abort() {
aborted = true;
}
@Override
public void remote_mkdir() {
String fn = JF.getString("Enter new folder name", "");
if ((fn == null) || (fn.length() == 0)) return;
if (fn.indexOf(":") != -1) return;
if (fn.indexOf("/") != -1) return;
if (fn.indexOf("?") != -1) return;
if (fn.indexOf("*") != -1) return;
String wd = remoteDir.getText();
if (!wd.endsWith("/")) wd += "/";
String file = wd + fn;
remote_mkdir(file);
remote_chdir("."); //refresh
}
public void remote_mkdir(String file) {
try {
if (!file.startsWith("/")) file = remoteDir.getText() + "/" + file;
setStatus("mkdir");
SmbFile smbfile = new SmbFile(url + file, auth);
smbfile.mkdir();
setStatus(null);
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("Error:" + e);
}
}
@Override
public void remote_delete() {
remoteFolderStack = new ArrayList<String>();
if (!JF.showConfirm("Delete", "Are you sure you want to delete file(s)?")) return;
aborted = false;
setStatus("Deleting");
new Thread() {
@Override
public void run() {
remote_delete_files();
remote_chdir("."); //refresh
setStatus(null);
}
}.start();
}
private void remote_delete_files() {
int rows[] = remoteFiles.getSelectedRows();
if (rows.length == 0) return;
SiteFile sf[] = new SiteFile[rows.length];
for(int idx=0;idx<rows.length;idx++) {
sf[idx] = (SiteFile)remoteFilesTableModel.getValueAt(rows[idx], 0);
}
for(int idx=0;idx<sf.length;idx++) {
if (sf[idx].getText().equals(".")) continue;
if (sf[idx].getText().equals("..")) continue;
totalFileSize = sf[idx].filesize;
if (sf[idx].isDir) {
remoteFolderStack.add(remoteDir.getText());
remote_chdir(sf[idx].getText());
}
if (sf[idx].isLink && !sf[idx].isDir) {
//test if dir
String d1 = remoteDir.getText();
remote_chdir(sf[idx].getText());
String d2 = remoteDir.getText();
if (!d1.equals(d2)) {
remoteFolderStack.add(d1);
sf[idx].isDir = true;
}
}
if (sf[idx].isDir) {
//already remote_chdir();
remoteFiles.selectAll();
remote_delete_files();
remote_chdir(remoteFolderStack.remove(remoteFolderStack.size() - 1));
}
String remoteFile = remoteDir.getText() + "/" + sf[idx].getText();
if (sf[idx].isDir) {
remote_delete_folder(remoteFile);
} else {
remote_delete_file(remoteFile);
}
if (aborted) break;
}
}
public void remote_delete_file(String file) {
try {
if (!file.startsWith("/")) file = remoteDir.getText() + "/" + file;
SmbFile smbfile = new SmbFile(url + file, auth);
smbfile.delete();
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("Error:" + e);
}
}
public void remote_delete_folder(String file) {
try {
if (!file.endsWith("/"))
remote_delete_file(file + "/");
else
remote_delete_file(file);
//update remoteTree
int idx = file.lastIndexOf("/");
if (idx != -1) file = file.substring(idx+1);
for(int a=0;a<remoteTag.getChildCount();a++) {
XML.XMLTag child = remoteTag.getChildAt(a);
if (child.getName().equals(file)) {
remoteFolders.deleteTag(child);
break;
}
}
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("Error:" + e);
}
}
@Override
public void remote_rename() {
int rows[] = remoteFiles.getSelectedRows();
if ((rows == null) || (rows.length != 1)) return;
SiteFile sf = (SiteFile)remoteFilesTableModel.getValueAt(rows[0], 0);
String remoteFile = remoteDir.getText() + "/" + sf.getText();
String newName = JF.getString("Rename File", sf.getText());
if ((newName == null) || (newName.length() == 0)) return;
File newFile = new File(remoteDir.getText() + "/" + newName);
remote_rename(remoteFile, newName);
//update remoteTree
for(int a=0;a<remoteTag.getChildCount();a++) {
XML.XMLTag child = remoteTag.getChildAt(a);
if (child.getName().equals(sf.getText())) {
child.setName(newName);
break;
}
}
remote_chdir("."); //refresh
}
public void remote_rename(String from, String to) {
try {
SmbFile smbfrom, smbto;
if (from.startsWith("/"))
smbfrom = new SmbFile(url + from, auth);
else
smbfrom = new SmbFile(url + remoteDir.getText() + "/" + from, auth);
if (to.startsWith("/"))
smbto = new SmbFile(url + to, auth);
else
smbto = new SmbFile(url + remoteDir.getText() + "/" + to, auth);
smbfrom.renameTo(smbto);
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("Error:" + e);
}
}
@Override
public void remote_props() {
int rows[] = remoteFiles.getSelectedRows();
if ((rows == null) || (rows.length != 1)) return;
SiteFile sf = (SiteFile)remoteFilesTableModel.getValueAt(rows[0], 0);
String remoteFile = remoteDir.getText() + "/" + sf.getText();
String perms = (String)remoteFilesTableModel.getValueAt(rows[0], 3);
//drwxrwxrwx
int octal = 0;
if (perms.charAt(1) == 'r') octal += 0x100;
if (perms.charAt(2) == 'w') octal += 0x80;
if (perms.charAt(3) == 'x') octal += 0x40;
if (perms.charAt(4) == 'r') octal += 0x20;
if (perms.charAt(5) == 'w') octal += 0x10;
if (perms.charAt(6) == 'x') octal += 0x08;
if (perms.charAt(7) == 'r') octal += 0x04;
if (perms.charAt(8) == 'w') octal += 0x02;
if (perms.charAt(9) == 'x') octal += 0x01;
Permissions dialog = new Permissions(null, true, remoteFile, octal);
dialog.setVisible(true);
if (dialog.value == -1) return;
try {
setPerms(dialog.value, remoteFile);
remote_chdir("."); //refresh
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("Error:" + e);
}
}
public void setPerms(int value, String remoteFile) {
try {
//TODO
remote_chdir("."); //refresh
} catch (Exception e) {
setStatus("Error:" + e);
JFLog.log(e);
addLog("Error:" + e);
}
}
public void closeSite() {
JPanel panel = (JPanel)this.getClientProperty("panel");
JTabbedPane tabs = (JTabbedPane)this.getClientProperty("tabs");
tabs.remove(panel);
}
}