Android Runtime.getRuntime().exec and rsync - android

I'm tryng to run rsync on my device. I have the binary in /system/xbin/rsync and I'm trying to launch it with Runtime.getRuntime().exec. I'm new to Android programming, so I don't get yet if I have to user Superuser Permissions.
My code is:
try {
Process process = Runtime.getRuntime().exec(
"/system/xbin/rsync -avzru /sdcard/Tinybox/ " +
"mattiazeni#192.168.1.6::88124bb378ac994088e704d553de6f19");
System.out.print("RSYNC LAUNCHED\n");
// Reads stdout.
// NOTE: You can write to stdin of the command using
// process.getOutputStream().
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
// Waits for the command to finish.
process.waitFor();
System.out.print(output);
System.out.print("RSYNC FINISHED\n");
// return output.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
And it doesn't work, it just prints "RSYNC STARTED" "RSYNC FINISHED".
But if I run:
Process process = Runtime.getRuntime().exec("/system/xbin/rsync --help");
it works fine, I can see the output from the LogCat window.
So I guess I have to use Superuser Permissions and so I modified my code as follows:
try {
System.out.print("RSYNC STARTED\n");
Process process = Runtime.getRuntime().exec("/system/xbin/su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
DataInputStream is = new DataInputStream(process.getInputStream());
os.writeBytes("/system/xbin/rsync --help");
String output = new String();
String temp = new String();
output = is.readLine();
System.out.print(output);
os.flush();
System.out.print("RSYNC FINISHED\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
}
But when I run the code the App freezes with no errors.

Ok, I'm using a slightly different version of the code:
try {
System.out.print("RSYNC STARTED\n");
process = Runtime.getRuntime().exec("/system/xbin/su -c sh");
OutputStream os = process.getOutputStream();
Log.d("RSYNC","/system/xbin/rsync" + " -avzru /sdcard/download/ mattiazeni#192.168.1.6::TinyBox &");
writeLine( os, "/system/xbin/rsync" + " -avzru /sdcard/download/ mattiazeni#192.168.1.6::TinyBox &");
os.flush();
System.out.print("RSYNC FINISHED\n");
}
catch ( IOException e ) {
e.printStackTrace();
}
I understood that the problem is on the su command. If I launch rsync using su it blocks with no error message as I previously said, if I remove the su command and launch just:
try {
System.out.print("RSYNC STARTED\n");
process = Runtime.getRuntime().exec("sh");
OutputStream os = process.getOutputStream();
Log.d("RSYNC","/system/xbin/rsync" + " -avzru /sdcard/download/ mattiazeni#192.168.1.6::TinyBox &");
writeLine( os, "/system/xbin/rsync" + " -avzru /sdcard/download/ mattiazeni#192.168.1.6::TinyBox &");
os.flush();
System.out.print("RSYNC FINISHED\n");
}
catch ( IOException e ) {
e.printStackTrace();
}
it works fine, but of course I got an error from rsync because I have no permissions and the synchronization won't work. How can I solve my problem??

Related

Trying to reboot programmatically rooted Android device

I'm trying to reboot programmatically my Galaxy S3.
Things that I've tried:
try {
Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", "reboot" });
proc.waitFor();
} catch (Exception ex) {
Log.i("RebootActivity", "Could not reboot", ex);
}
try {
Runtime.getRuntime().exec(new String[]{"su","-c","reboot now"});
} catch (IOException e) {
e.printStackTrace();
}
try
{
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("reboot now\n");
}
catch (Throwable t)
{
t.printStackTrace();
}
Do you guys have any idea how to accomplish this?
Thanks.
Try to do one normal string looking like 《su \n reboot; \n》 instead of an array.
Try to get the answer from the shell, that helps a lot for debugging.
What are the permissions of your su binary? If they would be wrong, you could try to 《chmod 7777 /system/xbin/su》 after 《mount -o remount,rw /system》
Here is some example code: (to run the string command, which is a \n and or ; separated list of linux shell commands)
StringBuffer commandOutput = new StringBuffer();
try {
Process process = Runtime.getRuntime().exec("su\n");
DataOutputStream out = new DataOutputStream(process.getOutputStream());
out.writeBytes("export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/vendor/lib:/system/lib\n");
out.writeBytes(command+"\n");
out.flush();
process.waitFor();
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
int numRead;
char[] buffer = new char[1000];
while ((numRead = in.read(buffer)) > 0) {
commandOutput.append(buffer, 0, numRead);
}
in.close();
process.waitFor();
} catch ...
return commandOutput.toString();
You could possibly use the PowerManager to make it reboot (this does not guarantee that it'll reboot - OS may cancel it):
http://developer.android.com/reference/android/os/PowerManager.html#reboot(java.lang.String
http://developer.android.com/reference/android/Manifest.permission.html#REBOOT

Embedding binary library into Android app

I'm coding apps that use busybox binary library stored in my project's assets folder. In runtime I copy this library to /data/data/com.myapp/ folder, I make this file executable and than try to execute some util cmds that should be available from this binary lib. But I have not get desired result. I use next function:
private void shellCmd()
{
try {
Process process = null;
/* I used this to make the file executable */
// process = Runtime.getRuntime().exec("/system/bin/chmod 777 "
// + this.getFilesDir().getPath() + "/busybox");
// process = Runtime.getRuntime().exec("/system/bin/ls -l "
// + this.getFilesDir().getPath() + "/busybox");
/* this exec function doesnt execute(there is no prompt into logcat)*/
process = Runtime.getRuntime().exec( this.getFilesDir().getPath() + "/busybox ping -4 46.173.103.134");
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
Log.w("groupAB",output.toString());
Log.i("groupAB", "finish");
process.waitFor();
return;
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
But when I'm trying to execute the same cmd using adb in way "adb shell /data/data/com.myapp/busybox ping -4 46.173.103.134" I get corect ping result. I'm confused why this doesn't work in a programming way. Where is my fault?

How to get error message of a failed shell command on android

On a rooted android device, I tried to run a cat command that read kernel log, as follow:
Process p = Runtime.getRuntime().exec("su");
p = Runtime.getRuntime().exec("/system/bin/cat /proc/kmsg");
The su command was successfully executed but not the cat.
I tried to read the output of the command using getInputStream() but nothing was there, as follow:
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((read = err.read(buffer)) > 0)
{ //read error to buffer
catOutput.append(buffer, 0, read);
}
in.close();
I used the same code with ls command instead of displaying the kernel log, it worked just fine and show me the result.
I wonder if what error I am getting and wantted to see the error message on the shell when executing the cat command. Tried the p.getErrorStream() but it doesn't give me any result.
Could any one help me with this ? Thanks.
Here's a comprehensive example on how to do this - note that I got the idea from this answer:
public void catKmsg() {
Runtime runtime = Runtime.getRuntime();
Process proc = null;
OutputStreamWriter osw = null;
StringBuilder sbstdOut = new StringBuilder();
StringBuilder sbstdErr = new StringBuilder();
String command="/system/bin/cat /proc/kmsg";
try { // Run Script
proc = runtime.exec("su");
osw = new OutputStreamWriter(proc.getOutputStream());
osw.write(command);
osw.flush();
osw.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (osw != null) {
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
if (proc != null) {
proc.waitFor();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
sbstdOut.append(ReadBufferedReader(new InputStreamReader
(proc.getInputStream())));
sbstdErr.append(ReadBufferedReader(new InputStreamReader
(proc.getErrorStream())));
if (proc.exitValue() != 0) {
}
}
I finally found the solution for the problem by using RootTools library.
Recently released (few months after my question was asked), RootTools provides a easy-to-use tool set that helps running commands that required root privilege. I created a wrapper to check if root access is available before executing shell command:
void testRootToolsCommand(String command){
if (RootTools.isRootAvailable())
toastMessage("Root is available !!!");
else {
toastMessage("NO ROOT !!! ");
return;
}
int timeOut = 1000;
try {
List<String> output = RootTools.sendShell(command,timeOut);
toastMessage("OUTPUT of the command \n" + output.toString());
} catch (RootToolsException re) {
toastMessage("Funny thing happened with RootTools!!! ");
} catch (TimeoutException te)
{
toastMessage("Timeout exception - Increase timeout !!! !!! ");
}
catch (Exception e) {
toastMessage(e.getMessage().toString());
}
}
An example of a function call is:
testRootToolsCommand("cat /proc/kmsg > /sdcard/jun11_4h51.txt");
Note: The Tool also support running multiple commands at once.

How can we execute a shell script file from my Android Application

Please Tell me it is possible to run a shell script file from My Android application.
and read the data from script file.
If it is possible than how to proceed , Please give me some guideline.
You can use this code snippet (from Aaron C)
void execCommandLine(String command)
{
Runtime runtime = Runtime.getRuntime();
Process proc = null;
OutputStreamWriter osw = null;
try
{
proc = runtime.exec("su");
osw = new OutputStreamWriter(proc.getOutputStream());
osw.write(command);
osw.flush();
osw.close();
}
catch (IOException ex)
{
Log.e("execCommandLine()", "Command resulted in an IO Exception: " + command);
return;
}
finally
{
if (osw != null)
{
try
{
osw.close();
}
catch (IOException e){}
}
}
try
{
proc.waitFor();
}
catch (InterruptedException e){}
if (proc.exitValue() != 0)
{
Log.e("execCommandLine()", "Command returned error: " + command + "\n Exit code: " + proc.exitValue());
}
}
But this requires root access I think.
You could also try to use GScript
I've been using this to run shell scripts in my android app. Only thing I've yet to figure out how to do is direct the output to where I want it. You don't need root for this, which is why I'm posting.
Process process = Runtime.getRuntime().exec("top -n 1");
//Get the output of top so that it can be read
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

RE :How can we execute a shell script file from my Android Application

I am trying to write an android application that runs a shell commands, or a shell script if that is preferable, and displays the output... can anyone give me in the right direction?
My code is as follows:
void execCommandLine()
{
Runtime runtime = Runtime.getRuntime();
Process proc = null;
OutputStreamWriter osw = null;
try
{
String[] str={"/system/bin/sh","/data/shTest.sh"};
System.out.println("EXEC STRING");
proc = runtime.exec(str);
osw = new OutputStreamWriter(proc.getOutputStream());
//osw.write(command);
osw.flush();
osw.close();
}
catch (IOException ex)
{
Log.e("erre","ioexception");
//Log.e("execCommandLine()", "Command resulted in an IO Exception: " + command);
return;
}
finally
{
if (osw != null)
{
try
{
osw.close();
}
catch (IOException e){}
}
}
try
{
proc.waitFor();
}
catch (InterruptedException e){}
if (proc.exitValue() != 0)
{
Log.e("erre","interruotexception");
//Log.e("execCommandLine()", "Command returned error: " + command + "\n Exit code: " + proc.exitValue());
}
}
// **************************************
Code is running successfully but I am not getting any output in adb shell logcat
would anyone tell me if this script is executed successfully how to get this output
in Adb shell.
Have you looked into GScript. It is quite flexible.

Categories

Resources