mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-02 22:55:26 +02:00
[213438] Checked in initial scp filesubsystem contribution by Nikita Shulga (Mentor Graphics).
This commit is contained in:
parent
b2ff1be03f
commit
1a03a16e19
17 changed files with 1339 additions and 0 deletions
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
28
rse/plugins/org.eclipse.rse.subsystems.files.scp/.project
Normal file
28
rse/plugins/org.eclipse.rse.subsystems.files.scp/.project
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.eclipse.rse.subsystems.files.scp</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.pde.PluginNature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -0,0 +1,7 @@
|
|||
#Fri Feb 06 22:40:19 JST 2009
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
|
||||
org.eclipse.jdt.core.compiler.compliance=1.5
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.5
|
|
@ -0,0 +1,19 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.rse.subsystems.files.scp;singleton:=true
|
||||
Bundle-Version: 0.1.0.qualifier
|
||||
Bundle-Vendor: %providerName
|
||||
Bundle-Localization: plugin
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Require-Bundle: org.eclipse.rse.subsystems.files.core;bundle-version="[3.0.0,4.0.0)",
|
||||
org.eclipse.rse.services.ssh;bundle-version="[3.0.0,3.1.0)",
|
||||
org.eclipse.rse.connectorservice.ssh;bundle-version="[2.0.0,2.2.0)",
|
||||
org.eclipse.rse.services;bundle-version="[3.0.0,4.0.0)",
|
||||
org.eclipse.rse.core;bundle-version="[3.0.0,4.0.0)",
|
||||
org.eclipse.rse.ui;bundle-version="[3.0.0,4.0.0)",
|
||||
com.jcraft.jsch;bundle-version="[0.1.31,1.0.0)",
|
||||
org.eclipse.core.runtime;bundle-version="[3.4.0,3.7.0)"
|
||||
Bundle-Activator: org.eclipse.rse.internal.subsystems.files.scp.Activator
|
||||
Export-Package: org.eclipse.rse.internal.subsystems.files.scp;x-internal:=true,
|
||||
org.eclipse.rse.subsystems.files.scp
|
28
rse/plugins/org.eclipse.rse.subsystems.files.scp/about.html
Normal file
28
rse/plugins/org.eclipse.rse.subsystems.files.scp/about.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
|
||||
<title>About</title>
|
||||
</head>
|
||||
<body lang="EN-US">
|
||||
<h2>About This Content</h2>
|
||||
|
||||
<p>June 5, 2007</p>
|
||||
<h3>License</h3>
|
||||
|
||||
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise
|
||||
indicated below, the Content is provided to you under the terms and conditions of the
|
||||
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available
|
||||
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
|
||||
For purposes of the EPL, "Program" will mean the Content.</p>
|
||||
|
||||
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
|
||||
being redistributed by another party ("Redistributor") and different terms and conditions may
|
||||
apply to your use of any object code in the Content. Check the Redistributor's license that was
|
||||
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
|
||||
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
|
||||
and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
source.. = src/
|
||||
output.. = bin/
|
||||
bin.includes = META-INF/,\
|
||||
icons/,\
|
||||
plugin.properties,\
|
||||
plugin.xml
|
Binary file not shown.
After Width: | Height: | Size: 157 B |
Binary file not shown.
After Width: | Height: | Size: 224 B |
|
@ -0,0 +1,16 @@
|
|||
################################################################################
|
||||
# Copyright (c) 2010 Mentor Graphics Corporation and others.
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# which accompanies this distribution, and is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Contributors:
|
||||
# Nikita Shulga - initial API and implementation
|
||||
################################################################################
|
||||
|
||||
pluginName = RSE SCP Files (Incubation)
|
||||
providerName = Eclipse.org - DSDP
|
||||
|
||||
ScpFileSubsystemName=Scp Files
|
||||
ScpFileSubsystemDescription=Work with files on remote systems using the Secure Shell (ssh) protocol.
|
32
rse/plugins/org.eclipse.rse.subsystems.files.scp/plugin.xml
Normal file
32
rse/plugins/org.eclipse.rse.subsystems.files.scp/plugin.xml
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2009, 2010 Mentor Graphics Corporation and others.
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
which accompanies this distribution, and is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
|
||||
Contributors:
|
||||
Nikita Shulga - initial API and implementation
|
||||
-->
|
||||
|
||||
<?eclipse version="3.1"?>
|
||||
|
||||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.rse.core.subsystemConfigurations">
|
||||
<configuration
|
||||
category="files"
|
||||
class="org.eclipse.rse.subsystems.files.scp.ScpFileSubSystemConfiguration"
|
||||
description="%ScpFileSubsystemName"
|
||||
icon="icons/full/obj16/systemfiles_obj.gif"
|
||||
iconlive="icons/full/obj16/systemfileslive_obj.gif"
|
||||
id="scp.files"
|
||||
name="%ScpFileSubsystemName"
|
||||
priority="80"
|
||||
serviceType="_scp-ssh._tcp"
|
||||
systemTypeIds="org.eclipse.rse.systemtype.linux;org.eclipse.rse.systemtype.unix;org.eclipse.rse.systemtype.aix;org.eclipse.rse.systemtype.ssh"
|
||||
vendor="%providerName">
|
||||
</configuration>
|
||||
</extension>
|
||||
</plugin>
|
|
@ -0,0 +1,71 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2010 Mentor Graphics Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Nikita Shulga (Mentor Graphics) - initial implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.subsystems.files.scp;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
public class Activator extends Plugin {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = Activator.class.getCanonicalName();
|
||||
|
||||
private static Activator plugin = null;
|
||||
private static Bundle bundle = null;
|
||||
|
||||
public Activator() {
|
||||
}
|
||||
|
||||
public static Plugin getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public static Bundle getDefaultBundle() {
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(BundleContext context) throws Exception {
|
||||
super.start(context);
|
||||
plugin = this;
|
||||
bundle = context.getBundle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
plugin = null;
|
||||
bundle = null;
|
||||
super.stop(context);
|
||||
}
|
||||
|
||||
public static void log(String msg) {
|
||||
log(msg, null);
|
||||
}
|
||||
|
||||
public static void log(String msg, Exception e) {
|
||||
log(IStatus.INFO, msg, e);
|
||||
}
|
||||
|
||||
public static void warn(String msg, Exception e) {
|
||||
log(IStatus.WARNING, msg, e);
|
||||
}
|
||||
|
||||
public static void log(int sev, String msg, Exception e) {
|
||||
Platform.getLog(getDefaultBundle()).log(
|
||||
new Status(sev, PLUGIN_ID, msg, e));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Initial Contributors:
|
||||
* The following IBM employees contributed to the Remote System Explorer
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - Adapted from FTPFileAdapter.
|
||||
* Martin Oberhuber (Wind River) - [235363][api][breaking] IHostFileToRemoteFileAdapter methods should return AbstractRemoteFile
|
||||
* Nikita Shulga (Mentor Graphics) - Adapted from SftpFileAdapter.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.subsystems.files.scp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.rse.services.files.IHostFile;
|
||||
import org.eclipse.rse.subsystems.files.core.servicesubsystem.AbstractRemoteFile;
|
||||
import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem;
|
||||
import org.eclipse.rse.subsystems.files.core.subsystems.IHostFileToRemoteFileAdapter;
|
||||
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
|
||||
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileContext;
|
||||
|
||||
public class ScpFileAdapter implements IHostFileToRemoteFileAdapter {
|
||||
|
||||
public AbstractRemoteFile convertToRemoteFile(FileServiceSubSystem ss,
|
||||
IRemoteFileContext context, IRemoteFile parent, IHostFile node) {
|
||||
|
||||
ScpRemoteFile file = new ScpRemoteFile(ss, context, parent, node);
|
||||
ss.cacheRemoteFile(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
public AbstractRemoteFile[] convertToRemoteFiles(FileServiceSubSystem ss,
|
||||
IRemoteFileContext context, IRemoteFile parent, IHostFile[] nodes) {
|
||||
|
||||
if (nodes == null)
|
||||
return new AbstractRemoteFile[0];
|
||||
|
||||
List<ScpRemoteFile> results = new ArrayList<ScpRemoteFile>();
|
||||
for (IHostFile node : nodes) {
|
||||
ScpRemoteFile file = new ScpRemoteFile(ss, context, parent, node);
|
||||
ss.cacheRemoteFile(file);
|
||||
results.add(file);
|
||||
}
|
||||
|
||||
return (ScpRemoteFile[]) results.toArray(new ScpRemoteFile[results
|
||||
.size()]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,248 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2010 Mentor Graphics Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Nikita Shulga - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.subsystems.files.scp;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Stack;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.files.HostFilePermissions;
|
||||
import org.eclipse.rse.services.files.IHostFilePermissions;
|
||||
|
||||
import com.jcraft.jsch.Session;
|
||||
|
||||
public class ScpFileAttr {
|
||||
private String lsString;
|
||||
private String attrString = null;
|
||||
private int linkNo = 0;
|
||||
private long mTime = 0;
|
||||
private String user = null;
|
||||
private String group = null;
|
||||
private long size = -1;
|
||||
private String name = null;
|
||||
private String linkName = null;
|
||||
|
||||
public IHostFilePermissions getFilePermissions() {
|
||||
return new HostFilePermissions(getAttrs(), getUser(), getGroup());
|
||||
}
|
||||
|
||||
public long getMTime() {
|
||||
if (!initialized)
|
||||
doSplit();
|
||||
return mTime;
|
||||
}
|
||||
|
||||
public long getSize() {
|
||||
if (!initialized)
|
||||
doSplit();
|
||||
return size;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
if (!initialized)
|
||||
doSplit();
|
||||
return user;
|
||||
}
|
||||
|
||||
public String getGroup() {
|
||||
if (!initialized)
|
||||
doSplit();
|
||||
return group;
|
||||
}
|
||||
|
||||
public int getLinkNo() {
|
||||
if (!initialized)
|
||||
doSplit();
|
||||
return linkNo;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
if (!initialized)
|
||||
doSplit();
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getLinkName() {
|
||||
if (!initialized)
|
||||
doSplit();
|
||||
return linkName;
|
||||
}
|
||||
|
||||
public String getAttrs() {
|
||||
if (!initialized)
|
||||
doSplit();
|
||||
|
||||
if (attrString == null || attrString.length() < 9)
|
||||
return "---------"; //$NON-NLS-1$
|
||||
|
||||
return attrString;
|
||||
}
|
||||
|
||||
private char getFileType() {
|
||||
String attrs = getAttrs();
|
||||
if (attrs == null || attrs.length() == 0)
|
||||
return 0;
|
||||
return attrs.charAt(0);
|
||||
}
|
||||
|
||||
public boolean isBlockDevice() {
|
||||
return getFileType() == 'b';
|
||||
}
|
||||
|
||||
public boolean isCharDevice() {
|
||||
return getFileType() == 'c';
|
||||
}
|
||||
|
||||
public boolean isLink() {
|
||||
return getFileType() == 'l';
|
||||
}
|
||||
|
||||
public boolean isDirectory() {
|
||||
return getFileType() == 'd';
|
||||
}
|
||||
|
||||
ScpFileAttr(String str) {
|
||||
lsString = str;
|
||||
if (lsString.endsWith("\n")) //$NON-NLS-1$
|
||||
lsString = lsString.substring(0, lsString.length() - 1);
|
||||
}
|
||||
|
||||
private boolean initialized = false;
|
||||
|
||||
private void doSplit() {
|
||||
if (initialized)
|
||||
return;
|
||||
initialized = true;
|
||||
try {
|
||||
SplitAux();
|
||||
} catch (Exception e) {
|
||||
Activator.warn(
|
||||
"ScpFileAttr:Exception occured while splitting string "
|
||||
+ lsString, e);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ls command uses two short date formats: - for files modified more than 6
|
||||
* month ago - for files modified less than 6 month ago
|
||||
*/
|
||||
final static DateFormat lessThanSixMonthOldFormat = new SimpleDateFormat(
|
||||
"MMM dd HH:mm"); //$NON-NLS-1$
|
||||
final static DateFormat moreThanSixMonthOldFormat = new SimpleDateFormat(
|
||||
"MMM dd yyyy"); //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
* Parses date time string returned by ls command
|
||||
*
|
||||
* @param date
|
||||
* - file modification date as string
|
||||
* @return time in seconds since start of epoch until mTime
|
||||
*/
|
||||
static long parseDateTime(String date) {
|
||||
// TODO: Add support for ls -le date format
|
||||
try {
|
||||
Date d = lessThanSixMonthOldFormat.parse(date);
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(d);
|
||||
c.set(Calendar.YEAR, Calendar.getInstance().get(Calendar.YEAR));
|
||||
return c.getTimeInMillis() / 1000;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
try {
|
||||
Date d = moreThanSixMonthOldFormat.parse(date);
|
||||
return d.getTime() / 1000;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static Pattern lsPattern = Pattern.compile("\\s+"); //$NON-NLS-1$
|
||||
|
||||
public void SplitAux() throws Exception {
|
||||
Stack<String> fields = new Stack<String>();
|
||||
for (String s : lsPattern.split(lsString))
|
||||
fields.insertElementAt(s, 0);
|
||||
|
||||
/* store file attributes */
|
||||
if (fields.empty())
|
||||
return;
|
||||
attrString = fields.pop();
|
||||
|
||||
/* store link number */
|
||||
if (fields.empty())
|
||||
return;
|
||||
linkNo = Integer.parseInt(fields.pop());
|
||||
|
||||
/* store uid and gid */
|
||||
if (fields.empty())
|
||||
return;
|
||||
user = fields.pop();
|
||||
if (fields.empty())
|
||||
return;
|
||||
group = fields.pop();
|
||||
|
||||
/* store file size */
|
||||
if (fields.empty())
|
||||
return;
|
||||
if (!isCharDevice() && !isBlockDevice())
|
||||
size = Long.parseLong(fields.pop());
|
||||
else {
|
||||
/* Size is undefined for character and block devices */
|
||||
size = 0;
|
||||
/* And we don't know what to do with devs major/minor */
|
||||
fields.pop();
|
||||
if (fields.empty())
|
||||
return;
|
||||
fields.pop();
|
||||
}
|
||||
|
||||
/* Date always takes three fields */
|
||||
if (fields.empty())
|
||||
return;
|
||||
String dateField = fields.pop();
|
||||
if (fields.empty())
|
||||
return;
|
||||
dateField = dateField + " " + fields.pop(); //$NON-NLS-1$
|
||||
if (fields.empty())
|
||||
return;
|
||||
dateField = dateField + " " + fields.pop(); //$NON-NLS-1$
|
||||
|
||||
mTime = parseDateTime(dateField);
|
||||
/* The rest of the entry is name ( and may be symlink ) */
|
||||
String[] namesplit = Pattern.compile(
|
||||
dateField.replace(" ", "\\s+") + "\\s").split(lsString); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
|
||||
if (namesplit.length != 2)
|
||||
return;
|
||||
name = namesplit[1];
|
||||
if (isLink()) {
|
||||
namesplit = name.split(" -> "); //$NON-NLS-1$
|
||||
if (namesplit.length != 2)
|
||||
return;
|
||||
name = namesplit[0];
|
||||
linkName = namesplit[1];
|
||||
}
|
||||
}
|
||||
|
||||
public static ScpFileAttr getAttr(Session sess, String path)
|
||||
throws SystemMessageException {
|
||||
String attr = ScpFileUtils.execCommandSafe(sess, "ls -land " //$NON-NLS-1$
|
||||
+ ScpFileUtils.escapePath(path));
|
||||
if (attr == null || attr.length() < 9)
|
||||
return null;
|
||||
return new ScpFileAttr(attr);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,522 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2010 Mentor Graphics Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Nikita Shulga - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.rse.internal.subsystems.files.scp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.rse.internal.services.ssh.ISshSessionProvider;
|
||||
import org.eclipse.rse.internal.services.ssh.files.SftpHostFile;
|
||||
import org.eclipse.rse.services.clientserver.FileTypeMatcher;
|
||||
import org.eclipse.rse.services.clientserver.IMatcher;
|
||||
import org.eclipse.rse.services.clientserver.NamePatternMatcher;
|
||||
import org.eclipse.rse.services.clientserver.messages.SimpleSystemMessage;
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
import org.eclipse.rse.services.files.AbstractFileService;
|
||||
import org.eclipse.rse.services.files.HostFilePermissions;
|
||||
import org.eclipse.rse.services.files.IFilePermissionsService;
|
||||
import org.eclipse.rse.services.files.IHostFile;
|
||||
import org.eclipse.rse.services.files.IHostFilePermissions;
|
||||
import org.eclipse.rse.services.files.IHostFilePermissionsContainer;
|
||||
|
||||
import com.jcraft.jsch.ChannelExec;
|
||||
import com.jcraft.jsch.Session;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class ScpFileService extends AbstractFileService implements
|
||||
IFilePermissionsService {
|
||||
|
||||
private final ISshSessionProvider fSessionProvider;
|
||||
private String fUserHome = null;
|
||||
|
||||
public ISshSessionProvider getSessionProvider() {
|
||||
return fSessionProvider;
|
||||
}
|
||||
|
||||
public Session getSession() {
|
||||
return getSessionProvider().getSession();
|
||||
}
|
||||
|
||||
public ScpFileService(ISshSessionProvider provider) {
|
||||
fSessionProvider = provider;
|
||||
}
|
||||
|
||||
protected static void throwSystemException(String msg)
|
||||
throws SystemMessageException {
|
||||
throw new SystemMessageException(new SimpleSystemMessage(
|
||||
Activator.PLUGIN_ID, IStatus.ERROR, msg));
|
||||
}
|
||||
|
||||
protected static void throwSystemException(Exception e)
|
||||
throws SystemMessageException {
|
||||
Activator.warn("ScpFileServie.throwSystemExcpeption", e);
|
||||
|
||||
if (e instanceof SystemMessageException)
|
||||
throw (SystemMessageException) e;
|
||||
throw new SystemMessageException(new SimpleSystemMessage(
|
||||
Activator.PLUGIN_ID, IStatus.ERROR, e.getMessage(), e));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IHostFile[] internalFetch(String parentPath, String fileFilter,
|
||||
int fileType, IProgressMonitor monitor)
|
||||
throws SystemMessageException {
|
||||
|
||||
if (fileFilter == null)
|
||||
fileFilter = "*";
|
||||
IMatcher filematcher = null;
|
||||
if (fileFilter.endsWith(",")) { //$NON-NLS-1$
|
||||
String[] types = fileFilter.split(","); //$NON-NLS-1$
|
||||
filematcher = new FileTypeMatcher(types, true);
|
||||
} else {
|
||||
filematcher = new NamePatternMatcher(fileFilter, true, true);
|
||||
}
|
||||
|
||||
List<IHostFile> results = new ArrayList<IHostFile>();
|
||||
Session sess = getSession();
|
||||
String cmd = "ls -lAn " + ScpFileUtils.escapePath(parentPath); //$NON-NLS-1$
|
||||
|
||||
String rc = ScpFileUtils.execCommandSafe(sess, cmd);
|
||||
|
||||
for (String lsString : rc.split(ScpFileUtils.EOL_STRING)) {
|
||||
if (lsString.length() == 0 || lsString.startsWith("total")) //$NON-NLS-1$
|
||||
continue;
|
||||
ScpFileAttr attr = new ScpFileAttr(lsString);
|
||||
if (attr == null || attr.getName() == null) {
|
||||
Activator.warn("internalFetch(parentPath='" + parentPath
|
||||
+ "'): Can't get name of " + lsString, null);
|
||||
continue;
|
||||
}
|
||||
if (!filematcher.matches(attr.getName()))
|
||||
continue;
|
||||
IHostFile f = makeHostFile(parentPath, null, attr);
|
||||
if (isRightType(fileType, f))
|
||||
results.add(f);
|
||||
}
|
||||
return (IHostFile[]) results.toArray(new IHostFile[results.size()]);
|
||||
}
|
||||
|
||||
public int getCapabilities(IHostFile host) {
|
||||
return IFilePermissionsService.FS_CAN_GET_ALL
|
||||
| IFilePermissionsService.FS_CAN_SET_ALL;
|
||||
}
|
||||
|
||||
public IHostFilePermissions getFilePermissions(IHostFile file,
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
if (file instanceof IHostFilePermissionsContainer) {
|
||||
return ((IHostFilePermissionsContainer) file).getPermissions();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setFilePermissions(IHostFile file,
|
||||
IHostFilePermissions permissions, IProgressMonitor monitor)
|
||||
throws SystemMessageException {
|
||||
Session session = getSession();
|
||||
String path = ScpFileUtils.escapePath(file.getAbsolutePath());
|
||||
int permBits = permissions.getPermissionBits();
|
||||
String ownStr = permissions.getUserOwner() + ':'
|
||||
+ permissions.getGroupOwner();
|
||||
String cmd = "chmod " + Integer.toOctalString(permBits) + " " + path; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
ScpFileUtils.execCommandSafe(session, cmd);
|
||||
ScpFileUtils.execCommandSafe(session, "chown " + ownStr + " " + path); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
public void copy(String arg0, String arg1, String arg2, String arg3,
|
||||
IProgressMonitor arg4) throws SystemMessageException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public void copyBatch(String[] arg0, String[] arg1, String arg2,
|
||||
IProgressMonitor arg3) throws SystemMessageException {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
public IHostFile createFile(String remotePath, String fileName,
|
||||
IProgressMonitor arg2) throws SystemMessageException {
|
||||
Session session = getSession();
|
||||
String fullPath = ScpFileUtils.concat(remotePath, fileName);
|
||||
|
||||
ScpFileUtils.execCommandSafe(session,
|
||||
"touch " + ScpFileUtils.escapePath(fullPath)); //$NON-NLS-1$
|
||||
ScpFileAttr attr = ScpFileAttr.getAttr(session, fullPath);
|
||||
|
||||
return makeHostFile(remotePath, fileName, attr);
|
||||
}
|
||||
|
||||
public IHostFile createFolder(String remotePath, String fileName,
|
||||
IProgressMonitor arg2) throws SystemMessageException {
|
||||
Session session = getSession();
|
||||
String fullPath = ScpFileUtils.concat(remotePath, fileName);
|
||||
|
||||
ScpFileUtils.execCommandSafe(session,
|
||||
"mkdir " + ScpFileUtils.escapePath(fullPath)); //$NON-NLS-1$
|
||||
ScpFileAttr attr = ScpFileAttr.getAttr(session, fullPath);
|
||||
|
||||
return makeHostFile(remotePath, fileName, attr);
|
||||
}
|
||||
|
||||
public void delete(String remotePath, String fileName, IProgressMonitor arg2)
|
||||
throws SystemMessageException {
|
||||
Session session = getSession();
|
||||
String fullPathEsc = ScpFileUtils.concatEscape(remotePath, fileName);
|
||||
|
||||
ScpFileUtils.execCommandSafe(session, "rm -rf " + fullPathEsc); //$NON-NLS-1$
|
||||
|
||||
}
|
||||
|
||||
private static String lastErrorMessage = null;
|
||||
|
||||
private static void setErrorMessage(String s) {
|
||||
lastErrorMessage = s;
|
||||
}
|
||||
|
||||
public static String getLastError() {
|
||||
return lastErrorMessage;
|
||||
}
|
||||
|
||||
private static int readAck(InputStream is) throws IOException {
|
||||
int rc = is.read();
|
||||
if (rc <= 0)
|
||||
return rc;
|
||||
|
||||
/* In case of non fatal error had to read an error string */
|
||||
StringBuffer sb = new StringBuffer();
|
||||
int ch;
|
||||
do {
|
||||
ch = is.read();
|
||||
sb.append((char) ch);
|
||||
} while (ch != ScpFileUtils.EOL_CHAR);
|
||||
setErrorMessage(sb.toString());
|
||||
return rc;
|
||||
}
|
||||
|
||||
public void download(String remoteParent, String fileName, File localFile,
|
||||
boolean isBinary, String hostEncoding, IProgressMonitor monitor)
|
||||
throws SystemMessageException {
|
||||
|
||||
try {
|
||||
if (!localFile.exists()) {
|
||||
File localParentFile = localFile.getParentFile();
|
||||
if (!localParentFile.exists()) {
|
||||
localParentFile.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
internalDownload(remoteParent, fileName, localFile, monitor);
|
||||
|
||||
} catch (Exception e) {
|
||||
throwSystemException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public IHostFile getFile(String remotePath, String fileName,
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
Session session = getSession();
|
||||
String fullPath = ScpFileUtils.concat(remotePath, fileName);
|
||||
ScpFileAttr attr = ScpFileAttr.getAttr(session, fullPath);
|
||||
|
||||
return makeHostFile(remotePath, fileName, attr);
|
||||
}
|
||||
|
||||
public IHostFile[] getRoots(IProgressMonitor monitor)
|
||||
throws SystemMessageException {
|
||||
IHostFile root = null;
|
||||
try {
|
||||
root = getFile(null, ScpFileUtils.TARGET_SEPARATOR, monitor);
|
||||
} catch (SystemMessageException e) {
|
||||
Activator.warn("Failed to get root file", e);
|
||||
}
|
||||
if (root == null)
|
||||
root = new SftpHostFile(null, ScpFileUtils.TARGET_SEPARATOR, true,
|
||||
true, false, 0, 0);
|
||||
|
||||
return new IHostFile[] { root };
|
||||
|
||||
}
|
||||
|
||||
public IHostFile getUserHome() {
|
||||
if (fUserHome == null) {
|
||||
try {
|
||||
Session sess = getSession();
|
||||
fUserHome = ScpFileUtils.execCommand(sess, "pwd").split( //$NON-NLS-1$
|
||||
ScpFileUtils.EOL_STRING)[0];
|
||||
} catch (Exception e) {
|
||||
Activator.warn("Failed to execute pwd", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (fUserHome == null)
|
||||
return null;
|
||||
int lastSlash = fUserHome
|
||||
.lastIndexOf(ScpFileUtils.TARGET_SEPARATOR_CHAR);
|
||||
String name = fUserHome.substring(lastSlash + 1);
|
||||
String parent = fUserHome.substring(0, lastSlash);
|
||||
IHostFile rc = null;
|
||||
try {
|
||||
rc = getFile(parent, name, null);
|
||||
} catch (SystemMessageException e) {
|
||||
Activator.warn("Failed to get user home file ", e);
|
||||
}
|
||||
if (rc == null)
|
||||
rc = new SftpHostFile(null, fUserHome, true, true, false, 0, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
public boolean isCaseSensitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void move(String oldPath, String oldName, String newPath,
|
||||
String newName, IProgressMonitor arg4)
|
||||
throws SystemMessageException {
|
||||
Session session = getSession();
|
||||
String oldFullPathEsc = ScpFileUtils.concatEscape(newPath, oldName);
|
||||
String newFullPathEsc = ScpFileUtils.concatEscape(newPath, newName);
|
||||
|
||||
ScpFileUtils.execCommandSafe(session, "mv " + oldFullPathEsc + " " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ newFullPathEsc);
|
||||
}
|
||||
|
||||
public void rename(String remotePath, String oldName, String newName,
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
Session session = getSession();
|
||||
String oldFullPathEsc = ScpFileUtils.concatEscape(remotePath, oldName);
|
||||
String newFullPathEsc = ScpFileUtils.concatEscape(remotePath, newName);
|
||||
|
||||
ScpFileUtils.execCommandSafe(session, "mv " + oldFullPathEsc + " " //$NON-NLS-1$ //$NON-NLS-2$
|
||||
+ newFullPathEsc);
|
||||
|
||||
}
|
||||
|
||||
public void rename(String remotePath, String oldName, String newName,
|
||||
IHostFile hostFile, IProgressMonitor monitor)
|
||||
throws SystemMessageException {
|
||||
// hostFile remains unused
|
||||
rename(remotePath, oldName, newName, monitor);
|
||||
}
|
||||
|
||||
public void setLastModified(String arg0, String arg1, long arg2,
|
||||
IProgressMonitor arg3) throws SystemMessageException {
|
||||
throwSystemException("setLastModified() not supported");
|
||||
}
|
||||
|
||||
public void setReadOnly(String remotePath, String fileName,
|
||||
boolean disableWrite, IProgressMonitor monitor)
|
||||
throws SystemMessageException {
|
||||
Session session = getSession();
|
||||
String fullPath = ScpFileUtils.concat(remotePath, fileName);
|
||||
ScpFileAttr attr = ScpFileAttr.getAttr(session, fullPath);
|
||||
if (attr == null)
|
||||
throwSystemException("Can't get attribute of file " + fullPath);
|
||||
int perm = new HostFilePermissions(attr.getAttrs(), "", "") //$NON-NLS-1$ //$NON-NLS-2$
|
||||
.getPermissionBits();
|
||||
if (disableWrite)
|
||||
perm &= ~0222;
|
||||
else
|
||||
perm |= 0200;
|
||||
ScpFileUtils.execCommandSafe(
|
||||
session,
|
||||
"chmod " + Integer.toOctalString(perm) + " " //$NON-NLS-1$//$NON-NLS-2$
|
||||
+ ScpFileUtils.escapePath(fullPath));
|
||||
}
|
||||
|
||||
public void upload(InputStream stream, String remotePath,
|
||||
String remoteFile, boolean isBinary, String hostEncoding,
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
|
||||
}
|
||||
|
||||
private void internalDownload(String remoteParent, String fileName,
|
||||
File localFile, IProgressMonitor monitor) throws Exception {
|
||||
String remotePath = ScpFileUtils.concat(remoteParent, fileName);
|
||||
String cmd = "scp -f " + ScpFileUtils.escapePath(remotePath); //$NON-NLS-1$
|
||||
|
||||
ChannelExec ch = ScpFileUtils.openExecChannel(getSession(), cmd);
|
||||
InputStream is = ch.getInputStream();
|
||||
OutputStream os = ch.getOutputStream();
|
||||
ch.connect();
|
||||
|
||||
byte buf[] = new byte[1024];
|
||||
// send '0'
|
||||
buf[0] = 0;
|
||||
os.write(buf, 0, 1);
|
||||
os.flush();
|
||||
|
||||
int c = is.read();
|
||||
if (c == 1) {
|
||||
String errmsg = ScpFileUtils.readString(is);
|
||||
throw new Exception("Error while downloading " + remotePath + " :"
|
||||
+ errmsg);
|
||||
}
|
||||
if (c != 'C')
|
||||
throw new Exception("Error while downloading " + remotePath
|
||||
+ ": Can't download file of type" + c);
|
||||
|
||||
// read '0644'
|
||||
is.read(buf, 0, 5);
|
||||
|
||||
// get file size
|
||||
long filesize = 0;
|
||||
while (true) {
|
||||
if (is.read(buf, 0, 1) < 0)
|
||||
break;
|
||||
if (buf[0] == ' ')
|
||||
break;
|
||||
filesize = filesize * 10 + (buf[0] - '0');
|
||||
}
|
||||
String fname = ScpFileUtils.readString(is);
|
||||
|
||||
Activator.log("filesize=" + filesize + " fname=" + fname);
|
||||
|
||||
// Confirm that file description is read by sending '0'
|
||||
buf[0] = 0;
|
||||
os.write(buf, 0, 1);
|
||||
os.flush();
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(localFile);
|
||||
monitor.beginTask("Downloading file", (int) filesize);
|
||||
long bytesDownloaded = 0;
|
||||
while (true) {
|
||||
int len = buf.length;
|
||||
if (filesize - bytesDownloaded < len)
|
||||
len = (int) (filesize - bytesDownloaded);
|
||||
int rc = is.read(buf, 0, len);
|
||||
if (rc < 0)
|
||||
break;
|
||||
monitor.worked(rc);
|
||||
fos.write(buf, 0, rc);
|
||||
bytesDownloaded += rc;
|
||||
if (bytesDownloaded >= filesize)
|
||||
break;
|
||||
}
|
||||
fos.close();
|
||||
fos = null;
|
||||
monitor.done();
|
||||
|
||||
c = is.read();
|
||||
if (c == 0) {
|
||||
// Confirm that file was received by sending '0'
|
||||
buf[0] = 0;
|
||||
os.write(buf, 0, 1);
|
||||
os.flush();
|
||||
}
|
||||
|
||||
os.close();
|
||||
is.close();
|
||||
|
||||
ch.disconnect();
|
||||
}
|
||||
|
||||
private void internalUpload(File localFile, String remotePath,
|
||||
String remoteFile, IProgressMonitor monitor) throws Exception {
|
||||
|
||||
monitor.beginTask("Uploading file", (int) localFile.length() + 10);
|
||||
|
||||
Session session = getSession();
|
||||
String cmd = "scp -p -t " + ScpFileUtils.escapePath(remotePath); //$NON-NLS-1$
|
||||
ChannelExec ch = ScpFileUtils.openExecChannel(session, cmd);
|
||||
InputStream is = ch.getInputStream();
|
||||
OutputStream os = ch.getOutputStream();
|
||||
ch.connect();
|
||||
monitor.internalWorked(5);
|
||||
|
||||
String fileHeader = "C0644" + " " + localFile.length() + " " //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
|
||||
+ remoteFile + "\n"; //$NON-NLS-1$
|
||||
if (readAck(is) != 0)
|
||||
throw new Exception("upload: wrong Ack! Last error:"
|
||||
+ getLastError());
|
||||
|
||||
os.write(fileHeader.getBytes());
|
||||
os.flush();
|
||||
|
||||
monitor.internalWorked(4);
|
||||
|
||||
FileInputStream fis = new FileInputStream(localFile);
|
||||
|
||||
byte[] buf = new byte[1024];
|
||||
while (true) {
|
||||
int len = fis.read(buf, 0, buf.length);
|
||||
if (len <= 0)
|
||||
break;
|
||||
os.write(buf, 0, len);
|
||||
monitor.internalWorked(len);
|
||||
}
|
||||
fis.close();
|
||||
|
||||
buf[0] = 0;
|
||||
os.write(buf, 0, 1);
|
||||
os.flush();
|
||||
if (readAck(is) != 0)
|
||||
throw new Exception("Error happened while uploading "
|
||||
+ localFile.getAbsolutePath() + ":" + getLastError());
|
||||
monitor.internalWorked(1);
|
||||
|
||||
os.close();
|
||||
is.close();
|
||||
monitor.done();
|
||||
ch.disconnect();
|
||||
}
|
||||
|
||||
public void upload(File localFile, String remotePath, String remoteFile,
|
||||
boolean isBinary, String srcEncoding, String hostEncoding,
|
||||
IProgressMonitor monitor) throws SystemMessageException {
|
||||
|
||||
try {
|
||||
internalUpload(localFile, remotePath, remoteFile, monitor);
|
||||
} catch (Exception e) {
|
||||
throwSystemException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private IHostFile makeHostFile(String remotePath, String fileName,
|
||||
ScpFileAttr attr) {
|
||||
boolean isRoot = (remotePath == null || remotePath.length() == 0);
|
||||
if (attr == null)
|
||||
return new SftpHostFile(isRoot ? null : remotePath, fileName,
|
||||
false, isRoot, false, 0, 0);
|
||||
|
||||
boolean isLink = attr.isLink();
|
||||
boolean isDir = attr.isDirectory();
|
||||
if (fileName == null)
|
||||
fileName = attr.getName();
|
||||
SftpHostFile node = new SftpHostFile(isRoot ? null : remotePath,
|
||||
fileName, isDir, isRoot, isLink, 1000L * attr.getMTime(),
|
||||
attr.getSize());
|
||||
if (isLink && attr.getLinkName() != null)
|
||||
node.setLinkTarget(attr.getLinkName());
|
||||
node.setPermissions(attr.getFilePermissions());
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return "SSH/SCP File Service can be used to connect to embedded sshd implementations, which often lacks sftp service";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SCP File Service";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2010 Mentor Graphics Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Nikita Shulga - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.subsystems.files.scp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
|
||||
|
||||
import com.jcraft.jsch.ChannelExec;
|
||||
import com.jcraft.jsch.Session;
|
||||
|
||||
public class ScpFileUtils {
|
||||
public static final String EOL_STRING = "\n"; //$NON-NLS-1$
|
||||
public static final String TARGET_SEPARATOR = "/"; //$NON-NLS-1$
|
||||
public static final String EXEC_CHANNEL = "exec"; //$NON-NLS-1$
|
||||
public static final String QUOTATION_MARK = "\""; //$NON-NLS-1$
|
||||
|
||||
public static char EOL_CHAR = EOL_STRING.charAt(0);
|
||||
public static char TARGET_SEPARATOR_CHAR = TARGET_SEPARATOR.charAt(0);
|
||||
|
||||
/**
|
||||
* Concatenate a parent directory with a file name to form a new proper path
|
||||
* name.
|
||||
*
|
||||
* This method was cloned from
|
||||
* {@link org.eclipse.rse.internal.services.ssh.files.SftpFileService#concat}
|
||||
*/
|
||||
protected static String concat(String parentDir, String fileName) {
|
||||
// See also {@link SftpHostFile#getAbsolutePath()}
|
||||
if (parentDir == null || parentDir.length() == 0) {
|
||||
// Looking at a Root
|
||||
return fileName;
|
||||
}
|
||||
|
||||
StringBuffer path = new StringBuffer(parentDir);
|
||||
if (!parentDir.endsWith(TARGET_SEPARATOR))
|
||||
path.append(TARGET_SEPARATOR_CHAR);
|
||||
|
||||
path.append(fileName);
|
||||
return path.toString();
|
||||
}
|
||||
|
||||
public static ChannelExec openExecChannel(Session sess) throws Exception {
|
||||
return (ChannelExec) sess.openChannel(EXEC_CHANNEL);
|
||||
}
|
||||
|
||||
public static ChannelExec openExecChannel(Session sess, String cmd)
|
||||
throws Exception {
|
||||
ChannelExec ch = openExecChannel(sess);
|
||||
if (ch != null)
|
||||
ch.setCommand(cmd);
|
||||
return ch;
|
||||
}
|
||||
|
||||
public static String execCommand(Session sess, String command)
|
||||
throws Exception {
|
||||
ChannelExec ch = openExecChannel(sess, command);
|
||||
ch.setInputStream(null);
|
||||
ch.setErrStream(System.err, true);
|
||||
InputStream is = ch.getInputStream();
|
||||
ch.connect();
|
||||
|
||||
String str = readStream(ch);
|
||||
is.close();
|
||||
ch.disconnect();
|
||||
return str;
|
||||
}
|
||||
|
||||
public static String execCommandSafe(Session session, String command)
|
||||
throws SystemMessageException {
|
||||
String rc = null;
|
||||
try {
|
||||
rc = execCommand(session, command);
|
||||
} catch (Exception e) {
|
||||
ScpFileService.throwSystemException(e);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
public static String escapePath(String path) {
|
||||
if (path.indexOf(' ') < 0)
|
||||
return path;
|
||||
return QUOTATION_MARK + path + QUOTATION_MARK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates parent directory with file name and escape the result if
|
||||
* necessary
|
||||
*
|
||||
* @param parentDir
|
||||
* parent directory
|
||||
* @param fileName
|
||||
* file name
|
||||
* @return escaped concatenated path to the file
|
||||
*/
|
||||
protected static String concatEscape(String parentDir, String fileName) {
|
||||
return escapePath(concat(parentDir, fileName));
|
||||
}
|
||||
|
||||
public static String readString(InputStream is) throws IOException {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
int rc = 0;
|
||||
while (true) {
|
||||
rc = is.read();
|
||||
if (rc == EOL_CHAR)
|
||||
break;
|
||||
buf.append((char) rc);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String readStream(ChannelExec ch) throws IOException {
|
||||
InputStream is = ch.getInputStream();
|
||||
byte[] buf = new byte[1024];
|
||||
String rc = ""; //$NON-NLS-1$
|
||||
while (!ch.isClosed() || is.available() > 0) {
|
||||
int cnt = is.read(buf, 0, buf.length);
|
||||
if (cnt < 0)
|
||||
break;
|
||||
rc += new String(buf, 0, cnt);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2010 IBM Corporation and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Initial Contributors:
|
||||
* The following IBM employees contributed to the Remote System Explorer
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - Adapted from FTPRemoteFile.
|
||||
* Martin Oberhuber (Wind River) - [216343] immediate link targets and canonical paths for Sftp
|
||||
* Nikita Shulga (Mentor Graphics) - Adapted from SftpRemoteFile.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.internal.subsystems.files.scp;
|
||||
|
||||
import org.eclipse.rse.internal.services.ssh.files.SftpHostFile;
|
||||
import org.eclipse.rse.services.files.IHostFile;
|
||||
import org.eclipse.rse.subsystems.files.core.servicesubsystem.AbstractRemoteFile;
|
||||
import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem;
|
||||
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
|
||||
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileContext;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class ScpRemoteFile extends AbstractRemoteFile {
|
||||
|
||||
public ScpRemoteFile(FileServiceSubSystem ss, IRemoteFileContext context,
|
||||
IRemoteFile parent, IHostFile hostFile) {
|
||||
super(ss, context, parent, hostFile);
|
||||
}
|
||||
|
||||
public SftpHostFile getSftpHostFile() {
|
||||
return (SftpHostFile) getHostFile();
|
||||
}
|
||||
|
||||
public String getCanonicalPath() {
|
||||
String canonicalPath = getSftpHostFile().getCanonicalPath();
|
||||
if (canonicalPath.equals(getAbsolutePath()) && _parentFile != null) {
|
||||
String parentCanonicalPath = _parentFile.getCanonicalPath();
|
||||
StringBuffer path = new StringBuffer(parentCanonicalPath);
|
||||
if (!parentCanonicalPath.endsWith(ScpFileUtils.TARGET_SEPARATOR))
|
||||
path.append(ScpFileUtils.TARGET_SEPARATOR);
|
||||
|
||||
path.append(getName());
|
||||
canonicalPath = path.toString();
|
||||
}
|
||||
return canonicalPath;
|
||||
}
|
||||
|
||||
public String getClassification() {
|
||||
return getSftpHostFile().getClassification();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2010 Wind River Systems, Inc. and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - initial API and implementation
|
||||
* Nikita Shulga (Mentor Graphics) - adapted from SftpFileSubSystemConfiguration.
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.rse.subsystems.files.scp;
|
||||
|
||||
import org.eclipse.rse.core.model.IHost;
|
||||
import org.eclipse.rse.core.subsystems.IConnectorService;
|
||||
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||
import org.eclipse.rse.internal.connectorservice.ssh.SshConnectorService;
|
||||
import org.eclipse.rse.internal.connectorservice.ssh.SshConnectorServiceManager;
|
||||
import org.eclipse.rse.internal.services.ssh.ISshService;
|
||||
import org.eclipse.rse.internal.subsystems.files.scp.ScpFileAdapter;
|
||||
import org.eclipse.rse.internal.subsystems.files.scp.ScpFileService;
|
||||
|
||||
import org.eclipse.rse.services.clientserver.SystemSearchString;
|
||||
import org.eclipse.rse.services.files.IFileService;
|
||||
import org.eclipse.rse.services.search.IHostSearchResultConfiguration;
|
||||
import org.eclipse.rse.services.search.IHostSearchResultSet;
|
||||
import org.eclipse.rse.services.search.ISearchService;
|
||||
import org.eclipse.rse.subsystems.files.core.ILanguageUtilityFactory;
|
||||
import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystem;
|
||||
import org.eclipse.rse.subsystems.files.core.servicesubsystem.FileServiceSubSystemConfiguration;
|
||||
import org.eclipse.rse.subsystems.files.core.subsystems.IHostFileToRemoteFileAdapter;
|
||||
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
|
||||
|
||||
@SuppressWarnings("restriction")
|
||||
public class ScpFileSubSystemConfiguration extends
|
||||
FileServiceSubSystemConfiguration {
|
||||
|
||||
protected IHostFileToRemoteFileAdapter _hostFileAdapter;
|
||||
|
||||
public ScpFileSubSystemConfiguration() {
|
||||
super();
|
||||
setIsUnixStyle(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ISubSystem createSubSystemInternal(IHost host) {
|
||||
IConnectorService connectorService = getConnectorService(host);
|
||||
IFileService fileService = getFileService(host);
|
||||
ISubSystem subsys = new FileServiceSubSystem(host, connectorService,
|
||||
fileService, getHostFileAdapter(), getSearchService(host));
|
||||
return subsys;
|
||||
}
|
||||
|
||||
public IFileService createFileService(IHost host) {
|
||||
SshConnectorService connectorService = (SshConnectorService) getConnectorService(host);
|
||||
return new ScpFileService(connectorService);
|
||||
}
|
||||
|
||||
public IHostFileToRemoteFileAdapter getHostFileAdapter() {
|
||||
if (_hostFileAdapter == null) {
|
||||
_hostFileAdapter = new ScpFileAdapter();
|
||||
}
|
||||
return _hostFileAdapter;
|
||||
}
|
||||
|
||||
public ILanguageUtilityFactory getLanguageUtilityFactory(
|
||||
IRemoteFileSubSystem arg0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public IConnectorService getConnectorService(IHost host) {
|
||||
return SshConnectorServiceManager.getInstance().getConnectorService(
|
||||
host, getServiceImplType());
|
||||
}
|
||||
|
||||
public Class<?> getServiceImplType() {
|
||||
return ISshService.class;
|
||||
}
|
||||
|
||||
public boolean supportsArchiveManagement() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsFileTypes() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsSearch() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public ISearchService createSearchService(IHost arg0) {
|
||||
// no search service supported for ssh/scp at moment
|
||||
return null;
|
||||
}
|
||||
|
||||
public IHostSearchResultConfiguration createSearchConfiguration(IHost arg0,
|
||||
IHostSearchResultSet arg1, Object arg2, SystemSearchString arg3) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Reference in a new issue