view src/com/five_ten_sg/connectbot/transport/Local.java @ 163:284152c31335
Added tag stable-1.8.1 for changeset 9904642c319e
author |
Carl Byington <carl@five-ten-sg.com> |
date |
Tue, 24 Jun 2014 12:33:39 -0700 (2014-06-24) |
parents |
77ac18bc1b2f |
children |
|
line source
/*
* ConnectBot: simple, powerful, open-source SSH client for Android
* Copyright 2007 Kenny Root, Jeffrey Sharkey
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.five_ten_sg.connectbot.transport;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Map;
import com.five_ten_sg.connectbot.R;
import com.five_ten_sg.connectbot.bean.HostBean;
import com.five_ten_sg.connectbot.service.TerminalBridge;
import com.five_ten_sg.connectbot.service.TerminalManager;
import com.five_ten_sg.connectbot.util.HostDatabase;
import android.content.Context;
import android.net.Uri;
import android.util.Log;
import com.google.ase.Exec;
/**
* @author Kenny Root
*
*/
public class Local extends AbsTransport {
private static final String TAG = "ConnectBot.Local";
private static final String PROTOCOL = "local";
private static final String DEFAULT_URI = "local:#Local";
private FileDescriptor shellFd;
private FileInputStream is;
private FileOutputStream os;
/**
*
*/
public Local() {
}
public static String getProtocolName() {
return PROTOCOL;
}
public Uri getUri(String input) {
Uri uri = Uri.parse(DEFAULT_URI);
if (input != null && input.length() > 0) {
uri = uri.buildUpon().fragment(input).build();
}
return uri;
}
@Override
public void connect() {
int[] pids = new int[1];
try {
shellFd = Exec.createSubprocess("/system/bin/sh", "-", null, pids);
}
catch (Exception e) {
bridge.outputLine(manager.res.getString(R.string.local_shell_unavailable));
Log.e(TAG, "Cannot start local shell", e);
return;
}
final int shellPid = pids[0];
Runnable exitWatcher = new Runnable() {
public void run() {
Exec.waitFor(shellPid);
bridge.dispatchDisconnect(false);
}
};
Thread exitWatcherThread = new Thread(exitWatcher);
exitWatcherThread.setName("LocalExitWatcher");
exitWatcherThread.setDaemon(true);
exitWatcherThread.start();
is = new FileInputStream(shellFd);
os = new FileOutputStream(shellFd);
bridge.onConnected();
}
@Override
public boolean willBlock() {
if (is == null) return true;
try {
return is.available() == 0;
}
catch (Exception e) {
return true;
}
}
@Override
public int read(byte[] buffer, int start, int len) throws IOException {
if (is == null) {
bridge.dispatchDisconnect(false);
throw new IOException("session closed");
}
return is.read(buffer, start, len);
}
@Override
public void write(byte[] buffer) throws IOException {
if (os != null)
os.write(buffer);
}
@Override
public void write(int c) throws IOException {
if (os != null)
os.write(c);
}
@Override
public void flush() throws IOException {
os.flush();
}
@Override
public void close() {
try {
if (os != null) {
os.close();
os = null;
}
if (is != null) {
is.close();
is = null;
}
}
catch (IOException e) {
Log.e(TAG, "Couldn't close shell", e);
}
}
@Override
public void setDimensions(int columns, int rows, int width, int height) {
try {
Exec.setPtyWindowSize(shellFd, rows, columns, width, height);
}
catch (Exception e) {
Log.e(TAG, "Couldn't resize pty", e);
}
}
@Override
public int getDefaultPort() {
return 0;
}
@Override
public boolean isConnected() {
return is != null && os != null;
}
@Override
public boolean isSessionOpen() {
return isConnected();
}
@Override
public boolean isAuthenticated() {
return isConnected();
}
@Override
public String getDefaultNickname(String username, String hostname, int port) {
return DEFAULT_URI;
}
@Override
public void getSelectionArgs(Uri uri, Map<String, String> selection) {
selection.put(HostDatabase.FIELD_HOST_PROTOCOL, PROTOCOL);
selection.put(HostDatabase.FIELD_HOST_NICKNAME, uri.getFragment());
}
@Override
public HostBean createHost(Uri uri) {
HostBean host = new HostBean();
host.setProtocol(PROTOCOL);
String nickname = uri.getFragment();
if (nickname == null || nickname.length() == 0) {
host.setNickname(getDefaultNickname(host.getUsername(),
host.getHostname(), host.getPort()));
}
else {
host.setNickname(uri.getFragment());
}
return host;
}
public String getFormatHint(Context context) {
return context.getString(R.string.hostpref_nickname_title);
}
@Override
public boolean usesNetwork() {
return false;
}
}