Android Runtime.getRuntime().exec and rsync

phcaze picture phcaze · Jan 14, 2013 · Viewed 9.4k times · Source

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/ " +
            "[email protected]::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.

Answer

phcaze picture phcaze · Jan 15, 2013

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/ [email protected]::TinyBox &");
    writeLine( os, "/system/xbin/rsync" + " -avzru /sdcard/download/ [email protected]::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/ [email protected]::TinyBox &");
    writeLine( os, "/system/xbin/rsync" + " -avzru /sdcard/download/ [email protected]::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??