diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/.classpath b/rse/plugins/org.eclipse.rse.subsystems.files.scp/.classpath
new file mode 100644
index 00000000000..64c5e31b7a2
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/.project b/rse/plugins/org.eclipse.rse.subsystems.files.scp/.project
new file mode 100644
index 00000000000..dc11c14fec7
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/.project
@@ -0,0 +1,28 @@
+
+
+ org.eclipse.rse.subsystems.files.scp
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/.settings/org.eclipse.jdt.core.prefs b/rse/plugins/org.eclipse.rse.subsystems.files.scp/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..1fbfa75195a
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/.settings/org.eclipse.jdt.core.prefs
@@ -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
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/META-INF/MANIFEST.MF b/rse/plugins/org.eclipse.rse.subsystems.files.scp/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..021e8535740
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/META-INF/MANIFEST.MF
@@ -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
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/about.html b/rse/plugins/org.eclipse.rse.subsystems.files.scp/about.html
new file mode 100644
index 00000000000..d4cc693f9f0
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/about.html
@@ -0,0 +1,28 @@
+
+
+
+
+About
+
+
+About This Content
+
+June 5, 2007
+License
+
+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 http://www.eclipse.org/legal/epl-v10.html.
+For purposes of the EPL, "Program" will mean the Content.
+
+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 http://www.eclipse.org.
+
+
+
\ No newline at end of file
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/build.properties b/rse/plugins/org.eclipse.rse.subsystems.files.scp/build.properties
new file mode 100644
index 00000000000..0a50975014f
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/build.properties
@@ -0,0 +1,6 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ icons/,\
+ plugin.properties,\
+ plugin.xml
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/icons/full/obj16/systemfiles_obj.gif b/rse/plugins/org.eclipse.rse.subsystems.files.scp/icons/full/obj16/systemfiles_obj.gif
new file mode 100644
index 00000000000..874c9926215
Binary files /dev/null and b/rse/plugins/org.eclipse.rse.subsystems.files.scp/icons/full/obj16/systemfiles_obj.gif differ
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/icons/full/obj16/systemfileslive_obj.gif b/rse/plugins/org.eclipse.rse.subsystems.files.scp/icons/full/obj16/systemfileslive_obj.gif
new file mode 100644
index 00000000000..885b8a69e39
Binary files /dev/null and b/rse/plugins/org.eclipse.rse.subsystems.files.scp/icons/full/obj16/systemfileslive_obj.gif differ
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/plugin.properties b/rse/plugins/org.eclipse.rse.subsystems.files.scp/plugin.properties
new file mode 100644
index 00000000000..e34f7d92dc9
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/plugin.properties
@@ -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.
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/plugin.xml b/rse/plugins/org.eclipse.rse.subsystems.files.scp/plugin.xml
new file mode 100644
index 00000000000..b42eca23b99
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/plugin.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/Activator.java b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/Activator.java
new file mode 100644
index 00000000000..600762a7099
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/Activator.java
@@ -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));
+ }
+
+}
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileAdapter.java b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileAdapter.java
new file mode 100644
index 00000000000..7ea96133bdc
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileAdapter.java
@@ -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 results = new ArrayList();
+ 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()]);
+ }
+
+}
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileAttr.java b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileAttr.java
new file mode 100644
index 00000000000..ab9bf1ac99c
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileAttr.java
@@ -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 fields = new Stack();
+ 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);
+ }
+
+}
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileService.java b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileService.java
new file mode 100644
index 00000000000..9d6972d0c23
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileService.java
@@ -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 results = new ArrayList();
+ 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";
+ }
+
+}
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileUtils.java b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileUtils.java
new file mode 100644
index 00000000000..816dacaa970
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpFileUtils.java
@@ -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;
+ }
+
+}
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpRemoteFile.java b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpRemoteFile.java
new file mode 100644
index 00000000000..666f864d6fa
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/internal/subsystems/files/scp/ScpRemoteFile.java
@@ -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();
+ }
+}
diff --git a/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/subsystems/files/scp/ScpFileSubSystemConfiguration.java b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/subsystems/files/scp/ScpFileSubSystemConfiguration.java
new file mode 100644
index 00000000000..0e0aae2cf8e
--- /dev/null
+++ b/rse/plugins/org.eclipse.rse.subsystems.files.scp/src/org/eclipse/rse/subsystems/files/scp/ScpFileSubSystemConfiguration.java
@@ -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;
+ }
+
+}