- */
- symlinkRegex = "^.*?\\-\\>\\s+(.*)$";
- symlinkPattern = Pattern.compile(symlinkRegex);
- }
-
- /**
- * Converts permission string from ls command to numerical value. Example: -rwxrwxrwx gets
- * to 777
- *
- * @param permissions
- * @return
- */
- private String convertPermissions(String permissions) {
- int owner = getGroupPermission(permissions.substring(1, 4));
- int group = getGroupPermission(permissions.substring(4, 7));
- int world = getGroupPermission(permissions.substring(7, 10));
-
- return "" + owner + group + world;
- }
-
- /**
- * Calculates permission for one group
- *
- * @param permission
- * @return value of permission string
- */
- private int getGroupPermission(String permission) {
- int value = 0;
-
- if (permission.charAt(0) == 'r') {
- value += 4;
- }
- if (permission.charAt(1) == 'w') {
- value += 2;
- }
- if (permission.charAt(2) == 'x') {
- value += 1;
- }
-
- return value;
- }
-
- @Override
- public void output(int id, String line) {
- // general check if line contains file
- if (line.contains(fileName)) {
-
- // try to match line exactly
- try {
- Matcher permissionMatcher = permissionPattern.matcher(line);
- if (permissionMatcher.find()) {
- permissions = convertPermissions(permissionMatcher.group(1));
-
- Log.d(RootCommands.TAG, "Found permissions: " + permissions);
- } else {
- Log.d(RootCommands.TAG, "Permissions were not found in ls command!");
- }
-
- // try to parse for symlink
- Matcher symlinkMatcher = symlinkPattern.matcher(line);
- if (symlinkMatcher.find()) {
- /*
- * TODO: If symlink points to a file in the same directory the path is not
- * absolute!!!
- */
- symlink = symlinkMatcher.group(1);
- Log.d(RootCommands.TAG, "Symlink found: " + symlink);
- } else {
- Log.d(RootCommands.TAG, "No symlink found!");
- }
- } catch (Exception e) {
- Log.e(RootCommands.TAG, "Error with regex!", e);
- }
- }
- }
-
- @Override
- public void afterExecution(int id, int exitCode) {
- }
-
- }
-
- /**
- * @param file
- * String that represent the file, including the full path to the file and its name.
- * @param followSymlinks
- * @return File permissions as String, for example: 777, returns null on error
- * @throws IOException
- * @throws TimeoutException
- * @throws BrokenBusyboxException
- *
- */
- public String getFilePermissions(String file) throws BrokenBusyboxException, TimeoutException,
- IOException {
- Log.d(RootCommands.TAG, "Checking permissions for " + file);
-
- String permissions = null;
-
- if (fileExists(file)) {
- Log.d(RootCommands.TAG, file + " was found.");
-
- LsCommand lsCommand = new LsCommand(file);
- shell.add(lsCommand).waitForFinish();
-
- permissions = lsCommand.getPermissions();
- }
-
- return permissions;
- }
-
- /**
- * Sets permission of file
- *
- * @param file
- * absolute path to file
- * @param permissions
- * String like 777
- * @return true if command worked
- * @throws BrokenBusyboxException
- * @throws TimeoutException
- * @throws IOException
- */
- public boolean setFilePermissions(String file, String permissions)
- throws BrokenBusyboxException, TimeoutException, IOException {
- Log.d(RootCommands.TAG, "Set permissions of " + file + " to " + permissions);
-
- SimpleCommand chmodCommand = new SimpleCommand("chmod " + permissions + " " + file);
- shell.add(chmodCommand).waitForFinish();
-
- if (chmodCommand.getExitCode() == 0) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * This will return a String that represent the symlink for a specified file.
- *
- * @param file
- * The path to the file to get the Symlink for. (must have absolute path)
- *
- * @return A String that represent the symlink for a specified file or null if no symlink
- * exists.
- * @throws IOException
- * @throws TimeoutException
- * @throws BrokenBusyboxException
- */
- public String getSymlink(String file) throws BrokenBusyboxException, TimeoutException,
- IOException {
- Log.d(RootCommands.TAG, "Find symlink for " + file);
-
- String symlink = null;
-
- LsCommand lsCommand = new LsCommand(file);
- shell.add(lsCommand).waitForFinish();
-
- symlink = lsCommand.getSymlink();
-
- return symlink;
- }
-
- /**
- * Copys a file to a destination. Because cp is not available on all android devices, we use dd
- * or cat.
- *
- * @param source
- * example: /data/data/org.adaway/files/hosts
- * @param destination
- * example: /system/etc/hosts
- * @param remountAsRw
- * remounts the destination as read/write before writing to it
- * @param preserveFileAttributes
- * tries to copy file attributes from source to destination, if only cat is available
- * only permissions are preserved
- * @return true if it was successfully copied
- * @throws BrokenBusyboxException
- * @throws IOException
- * @throws TimeoutException
- */
- public boolean copyFile(String source, String destination, boolean remountAsRw,
- boolean preservePermissions) throws BrokenBusyboxException, IOException,
- TimeoutException {
-
- /*
- * dd can only copy files, but we can not check if the source is a file without invoking
- * shell commands, because from Java we probably have no read access, thus we only check if
- * they are ending with trailing slashes
- */
- if (source.endsWith("/") || destination.endsWith("/")) {
- throw new FileNotFoundException("dd can only copy files!");
- }
-
- // remount destination as read/write before copying to it
- if (remountAsRw) {
- if (!remount(destination, "RW")) {
- Log.d(RootCommands.TAG,
- "Remounting failed! There is probably no need to remount this partition!");
- }
- }
-
- // get permissions of source before overwriting
- String permissions = null;
- if (preservePermissions) {
- permissions = getFilePermissions(source);
- }
-
- boolean commandSuccess = false;
-
- SimpleCommand ddCommand = new SimpleCommand("dd if=" + source + " of="
- + destination);
- shell.add(ddCommand).waitForFinish();
-
- if (ddCommand.getExitCode() == 0) {
- commandSuccess = true;
- } else {
- // try cat if dd fails
- SimpleCommand catCommand = new SimpleCommand("cat " + source + " > "
- + destination);
- shell.add(catCommand).waitForFinish();
-
- if (catCommand.getExitCode() == 0) {
- commandSuccess = true;
- }
- }
-
- // set back permissions from source to destination
- if (preservePermissions) {
- setFilePermissions(destination, permissions);
- }
-
- // remount destination back to read only
- if (remountAsRw) {
- if (!remount(destination, "RO")) {
- Log.d(RootCommands.TAG,
- "Remounting failed! There is probably no need to remount this partition!");
- }
- }
-
- return commandSuccess;
- }
-
- public static final int REBOOT_HOTREBOOT = 1;
- public static final int REBOOT_REBOOT = 2;
- public static final int REBOOT_SHUTDOWN = 3;
- public static final int REBOOT_RECOVERY = 4;
-
- /**
- * Shutdown or reboot device. Possible actions are REBOOT_HOTREBOOT, REBOOT_REBOOT,
- * REBOOT_SHUTDOWN, REBOOT_RECOVERY
- *
- * @param action
- * @throws IOException
- * @throws TimeoutException
- * @throws BrokenBusyboxException
- */
- public void reboot(int action) throws BrokenBusyboxException, TimeoutException, IOException {
- if (action == REBOOT_HOTREBOOT) {
- killAll("system_server");
- // or: killAll("zygote");
- } else {
- String command;
- switch (action) {
- case REBOOT_REBOOT:
- command = "reboot";
- break;
- case REBOOT_SHUTDOWN:
- command = "reboot -p";
- break;
- case REBOOT_RECOVERY:
- command = "reboot recovery";
- break;
- default:
- command = "reboot";
- break;
- }
-
- SimpleCommand rebootCommand = new SimpleCommand(command);
- shell.add(rebootCommand).waitForFinish();
-
- if (rebootCommand.getExitCode() == -1) {
- Log.e(RootCommands.TAG, "Reboot failed!");
- }
- }
- }
-
- /**
- * This command checks if a file exists
- */
- private class FileExistsCommand extends Command {
- private String file;
- private boolean fileExists = false;
-
- public FileExistsCommand(String file) {
- super("ls " + file);
- this.file = file;
- }
-
- public boolean isFileExists() {
- return fileExists;
- }
-
- @Override
- public void output(int id, String line) {
- if (line.trim().equals(file)) {
- fileExists = true;
- }
- }
-
- @Override
- public void afterExecution(int id, int exitCode) {
- }
-
- }
-
- /**
- * Use this to check whether or not a file exists on the filesystem.
- *
- * @param file
- * String that represent the file, including the full path to the file and its name.
- *
- * @return a boolean that will indicate whether or not the file exists.
- * @throws IOException
- * @throws TimeoutException
- * @throws BrokenBusyboxException
- *
- */
- public boolean fileExists(String file) throws BrokenBusyboxException, TimeoutException,
- IOException {
- FileExistsCommand fileExistsCommand = new FileExistsCommand(file);
- shell.add(fileExistsCommand).waitForFinish();
-
- if (fileExistsCommand.isFileExists()) {
- return true;
- } else {
- return false;
- }
- }
-
- public abstract class WithPermissions {
- abstract void whileHavingPermissions();
- }
-
- /**
- * Execute user defined Java code while having temporary permissions on a file
- *
- * @param file
- * @param withPermissions
- * @throws BrokenBusyboxException
- * @throws TimeoutException
- * @throws IOException
- */
- public void withPermission(String file, String permission, WithPermissions withPermissions)
- throws BrokenBusyboxException, TimeoutException, IOException {
- String oldPermissions = getFilePermissions(file);
-
- // set permissions (If set to 666, then Dalvik VM can also write to that file!)
- setFilePermissions(file, permission);
-
- // execute user defined code
- withPermissions.whileHavingPermissions();
-
- // set back to old permissions
- setFilePermissions(file, oldPermissions);
- }
-
- /**
- * Execute user defined Java code while having temporary write permissions on a file using chmod
- * 666
- *
- * @param file
- * @param withWritePermissions
- * @throws BrokenBusyboxException
- * @throws TimeoutException
- * @throws IOException
- */
- public void withWritePermissions(String file, WithPermissions withWritePermissions)
- throws BrokenBusyboxException, TimeoutException, IOException {
- withPermission(file, "666", withWritePermissions);
- }
-
- /**
- * Sets system clock using /dev/alarm
- *
- * @param millis
- * @throws BrokenBusyboxException
- * @throws TimeoutException
- * @throws IOException
- */
- public void setSystemClock(final long millis) throws BrokenBusyboxException, TimeoutException,
- IOException {
- withWritePermissions("/dev/alarm", new WithPermissions() {
-
- @Override
- void whileHavingPermissions() {
- SystemClock.setCurrentTimeMillis(millis);
- }
- });
- }
-
- /**
- * Adjust system clock by offset using /dev/alarm
- *
- * @param offset
- * @throws BrokenBusyboxException
- * @throws TimeoutException
- * @throws IOException
- */
- public void adjustSystemClock(final long offset) throws BrokenBusyboxException,
- TimeoutException, IOException {
- withWritePermissions("/dev/alarm", new WithPermissions() {
-
- @Override
- void whileHavingPermissions() {
- SystemClock.setCurrentTimeMillis(System.currentTimeMillis() + offset);
- }
- });
- }
-
- /**
- * This will take a path, which can contain the file name as well, and attempt to remount the
- * underlying partition.
- *
- * For example, passing in the following string:
- * "/system/bin/some/directory/that/really/would/never/exist" will result in /system ultimately
- * being remounted. However, keep in mind that the longer the path you supply, the more work
- * this has to do, and the slower it will run.
- *
- * @param file
- * file path
- * @param mountType
- * mount type: pass in RO (Read only) or RW (Read Write)
- * @return a boolean which indicates whether or not the partition has been
- * remounted as specified.
- */
- public boolean remount(String file, String mountType) {
- // Recieved a request, get an instance of Remounter
- Remounter remounter = new Remounter(shell);
- // send the request
- return (remounter.remount(file, mountType));
- }
-
- /**
- * This will tell you how the specified mount is mounted. rw, ro, etc...
- *
- * @param The
- * mount you want to check
- *
- * @return String What the mount is mounted as.
- * @throws Exception
- * if we cannot determine how the mount is mounted.
- */
- public String getMountedAs(String path) throws Exception {
- ArrayList mounts = Remounter.getMounts();
- if (mounts != null) {
- for (Mount mount : mounts) {
- if (path.contains(mount.getMountPoint().getAbsolutePath())) {
- Log.d(RootCommands.TAG, (String) mount.getFlags().toArray()[0]);
- return (String) mount.getFlags().toArray()[0];
- }
- }
-
- throw new Exception();
- } else {
- throw new Exception();
- }
- }
-
- /**
- * Check if there is enough space on partition where target is located
- *
- * @param size
- * size of file to put on partition
- * @param target
- * path where to put the file
- *
- * @return true if it will fit on partition of target, false if it will not fit.
- */
- public boolean hasEnoughSpaceOnPartition(String target, long size) {
- try {
- // new File(target).getFreeSpace() (API 9) is not working on data partition
-
- // get directory without file
- String directory = new File(target).getParent().toString();
-
- StatFs stat = new StatFs(directory);
- long blockSize = stat.getBlockSize();
- long availableBlocks = stat.getAvailableBlocks();
- long availableSpace = availableBlocks * blockSize;
-
- Log.i(RootCommands.TAG, "Checking for enough space: Target: " + target
- + ", directory: " + directory + " size: " + size + ", availableSpace: "
- + availableSpace);
-
- if (size < availableSpace) {
- return true;
- } else {
- Log.e(RootCommands.TAG, "Not enough space on partition!");
- return false;
- }
- } catch (Exception e) {
- // if new StatFs(directory) fails catch IllegalArgumentException and just return true as
- // workaround
- Log.e(RootCommands.TAG, "Problem while getting available space on partition!", e);
- return true;
- }
- }
-
- /**
- * TODO: Not tested!
- *
- * @param toggle
- * @throws IOException
- * @throws TimeoutException
- * @throws BrokenBusyboxException
- */
- public void toggleAdbDaemon(boolean toggle) throws BrokenBusyboxException, TimeoutException,
- IOException {
- SimpleCommand disableAdb = new SimpleCommand("setprop persist.service.adb.enable 0",
- "stop adbd");
- SimpleCommand enableAdb = new SimpleCommand("setprop persist.service.adb.enable 1",
- "stop adbd", "sleep 1", "start adbd");
-
- if (toggle) {
- shell.add(enableAdb).waitForFinish();
- } else {
- shell.add(disableAdb).waitForFinish();
- }
- }
-
-}
diff --git a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/Command.java b/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/Command.java
deleted file mode 100644
index 33e0f19..0000000
--- a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/Command.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann
- * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Adam Shanks, Jeremy Lakeman (RootTools)
- *
- * 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 org.sufficientlysecure.rootcommands.command;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.concurrent.TimeoutException;
-
-import org.sufficientlysecure.rootcommands.RootCommands;
-import org.sufficientlysecure.rootcommands.Shell;
-import org.sufficientlysecure.rootcommands.util.BrokenBusyboxException;
-import org.sufficientlysecure.rootcommands.util.Log;
-
-public abstract class Command {
- final String command[];
- boolean finished = false;
- boolean brokenBusyboxDetected = false;
- int exitCode;
- int id;
- int timeout = RootCommands.DEFAULT_TIMEOUT;
- Shell shell = null;
-
- public Command(String... command) {
- this.command = command;
- }
-
- public Command(int timeout, String... command) {
- this.command = command;
- this.timeout = timeout;
- }
-
- /**
- * This is called from Shell after adding it
- *
- * @param shell
- * @param id
- */
- public void addedToShell(Shell shell, int id) {
- this.shell = shell;
- this.id = id;
- }
-
- /**
- * Gets command string executed on the shell
- *
- * @return
- */
- public String getCommand() {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < command.length; i++) {
- // redirect stderr to stdout
- sb.append(command[i] + " 2>&1");
- sb.append('\n');
- }
- Log.d(RootCommands.TAG, "Sending command(s): " + sb.toString());
- return sb.toString();
- }
-
- public void writeCommand(OutputStream out) throws IOException {
- out.write(getCommand().getBytes());
- }
-
- public void processOutput(String line) {
- Log.d(RootCommands.TAG, "ID: " + id + ", Output: " + line);
-
- /*
- * Try to detect broken toolbox/busybox binaries (see
- * https://code.google.com/p/busybox-android/issues/detail?id=1)
- *
- * It is giving "Value too large for defined data type" on certain file operations (e.g. ls
- * and chown) in certain directories (e.g. /data/data)
- */
- if (line.contains("Value too large for defined data type")) {
- Log.e(RootCommands.TAG, "Busybox is broken with high probability due to line: " + line);
- brokenBusyboxDetected = true;
- }
-
- // now execute specific output parsing
- output(id, line);
- }
-
- public abstract void output(int id, String line);
-
- public void processAfterExecution(int exitCode) {
- Log.d(RootCommands.TAG, "ID: " + id + ", ExitCode: " + exitCode);
-
- afterExecution(id, exitCode);
- }
-
- public abstract void afterExecution(int id, int exitCode);
-
- public void commandFinished(int id) {
- Log.d(RootCommands.TAG, "Command " + id + " finished.");
- }
-
- public void setExitCode(int code) {
- synchronized (this) {
- exitCode = code;
- finished = true;
- commandFinished(id);
- this.notifyAll();
- }
- }
-
- /**
- * Close the shell
- *
- * @param reason
- */
- public void terminate(String reason) {
- try {
- shell.close();
- Log.d(RootCommands.TAG, "Terminating the shell.");
- terminated(reason);
- } catch (IOException e) {
- }
- }
-
- public void terminated(String reason) {
- setExitCode(-1);
- Log.d(RootCommands.TAG, "Command " + id + " did not finish, because of " + reason);
- }
-
- /**
- * Waits for this command to finish and forwards exitCode into afterExecution method
- *
- * @param timeout
- * @throws TimeoutException
- * @throws BrokenBusyboxException
- */
- public void waitForFinish() throws TimeoutException, BrokenBusyboxException {
- synchronized (this) {
- while (!finished) {
- try {
- this.wait(timeout);
- } catch (InterruptedException e) {
- Log.e(RootCommands.TAG, "InterruptedException in waitForFinish()", e);
- }
-
- if (!finished) {
- finished = true;
- terminate("Timeout");
- throw new TimeoutException("Timeout has occurred.");
- }
- }
-
- if (brokenBusyboxDetected) {
- throw new BrokenBusyboxException();
- }
-
- processAfterExecution(exitCode);
- }
- }
-
-}
\ No newline at end of file
diff --git a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/ExecutableCommand.java b/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/ExecutableCommand.java
deleted file mode 100644
index d6c8e61..0000000
--- a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/ExecutableCommand.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann
- *
- * 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 org.sufficientlysecure.rootcommands.command;
-
-import java.io.File;
-
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.os.Build;
-
-public abstract class ExecutableCommand extends Command {
- public static final String EXECUTABLE_PREFIX = "lib";
- public static final String EXECUTABLE_SUFFIX = "_exec.so";
-
- /**
- * This class provides a way to use your own binaries!
- *
- * Include your own executables, renamed from * to lib*_exec.so, in your libs folder under the
- * architecture directories. Now they will be deployed by Android the same way libraries are
- * deployed!
- *
- * See README for more information how to use your own executables!
- *
- * @param context
- * @param executableName
- * @param parameters
- */
- public ExecutableCommand(Context context, String executableName, String parameters) {
- super(getLibDirectory(context) + File.separator + EXECUTABLE_PREFIX + executableName
- + EXECUTABLE_SUFFIX + " " + parameters);
- }
-
- /**
- * Get full path to lib directory of app
- *
- * @return dir as String
- */
- @SuppressLint("NewApi")
- private static String getLibDirectory(Context context) {
- if (Build.VERSION.SDK_INT >= 9) {
- return context.getApplicationInfo().nativeLibraryDir;
- } else {
- return context.getApplicationInfo().dataDir + File.separator + "lib";
- }
- }
-
- public abstract void output(int id, String line);
-
- public abstract void afterExecution(int id, int exitCode);
-
-}
\ No newline at end of file
diff --git a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/SimpleCommand.java b/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/SimpleCommand.java
deleted file mode 100644
index 9049040..0000000
--- a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/SimpleCommand.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann
- *
- * 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 org.sufficientlysecure.rootcommands.command;
-
-public class SimpleCommand extends Command {
- private StringBuilder sb = new StringBuilder();
-
- public SimpleCommand(String... command) {
- super(command);
- }
-
- @Override
- public void output(int id, String line) {
- sb.append(line).append('\n');
- }
-
- @Override
- public void afterExecution(int id, int exitCode) {
- }
-
- public String getOutput() {
- return sb.toString();
- }
-
- public int getExitCode() {
- return exitCode;
- }
-
-}
\ No newline at end of file
diff --git a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/SimpleExecutableCommand.java b/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/SimpleExecutableCommand.java
deleted file mode 100644
index 95d2fae..0000000
--- a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/command/SimpleExecutableCommand.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann
- *
- * 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 org.sufficientlysecure.rootcommands.command;
-
-import android.content.Context;
-
-public class SimpleExecutableCommand extends ExecutableCommand {
- private StringBuilder sb = new StringBuilder();
-
- public SimpleExecutableCommand(Context context, String executableName, String parameters) {
- super(context, executableName, parameters);
- }
-
- @Override
- public void output(int id, String line) {
- sb.append(line).append('\n');
- }
-
- @Override
- public void afterExecution(int id, int exitCode) {
- }
-
- public String getOutput() {
- return sb.toString();
- }
-
- public int getExitCode() {
- return exitCode;
- }
-
-}
\ No newline at end of file
diff --git a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/BrokenBusyboxException.java b/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/BrokenBusyboxException.java
deleted file mode 100644
index e982b24..0000000
--- a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/BrokenBusyboxException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann
- *
- * 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 org.sufficientlysecure.rootcommands.util;
-
-import java.io.IOException;
-
-public class BrokenBusyboxException extends IOException {
- private static final long serialVersionUID = 8337358201589488409L;
-
- public BrokenBusyboxException() {
- super();
- }
-
- public BrokenBusyboxException(String detailMessage) {
- super(detailMessage);
- }
-
-}
diff --git a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/Log.java b/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/Log.java
deleted file mode 100644
index a25fbf4..0000000
--- a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/Log.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann
- *
- * 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 org.sufficientlysecure.rootcommands.util;
-
-import org.sufficientlysecure.rootcommands.RootCommands;
-
-/**
- * Wraps Android Logging to enable or disable debug output using Constants
- *
- */
-public final class Log {
-
- public static void v(String tag, String msg) {
- if (RootCommands.DEBUG) {
- android.util.Log.v(tag, msg);
- }
- }
-
- public static void v(String tag, String msg, Throwable tr) {
- if (RootCommands.DEBUG) {
- android.util.Log.v(tag, msg, tr);
- }
- }
-
- public static void d(String tag, String msg) {
- if (RootCommands.DEBUG) {
- android.util.Log.d(tag, msg);
- }
- }
-
- public static void d(String tag, String msg, Throwable tr) {
- if (RootCommands.DEBUG) {
- android.util.Log.d(tag, msg, tr);
- }
- }
-
- public static void i(String tag, String msg) {
- if (RootCommands.DEBUG) {
- android.util.Log.i(tag, msg);
- }
- }
-
- public static void i(String tag, String msg, Throwable tr) {
- if (RootCommands.DEBUG) {
- android.util.Log.i(tag, msg, tr);
- }
- }
-
- public static void w(String tag, String msg) {
- android.util.Log.w(tag, msg);
- }
-
- public static void w(String tag, String msg, Throwable tr) {
- android.util.Log.w(tag, msg, tr);
- }
-
- public static void w(String tag, Throwable tr) {
- android.util.Log.w(tag, tr);
- }
-
- public static void e(String tag, String msg) {
- android.util.Log.e(tag, msg);
- }
-
- public static void e(String tag, String msg, Throwable tr) {
- android.util.Log.e(tag, msg, tr);
- }
-
-}
diff --git a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/RootAccessDeniedException.java b/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/RootAccessDeniedException.java
deleted file mode 100644
index 35f353d..0000000
--- a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/RootAccessDeniedException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann
- *
- * 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 org.sufficientlysecure.rootcommands.util;
-
-import java.io.IOException;
-
-public class RootAccessDeniedException extends IOException {
- private static final long serialVersionUID = 9088998884166225540L;
-
- public RootAccessDeniedException() {
- super();
- }
-
- public RootAccessDeniedException(String detailMessage) {
- super(detailMessage);
- }
-
-}
diff --git a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/UnsupportedArchitectureException.java b/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/UnsupportedArchitectureException.java
deleted file mode 100644
index 96ad030..0000000
--- a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/UnsupportedArchitectureException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann
- *
- * 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 org.sufficientlysecure.rootcommands.util;
-
-public class UnsupportedArchitectureException extends Exception {
- private static final long serialVersionUID = 7826528799780001655L;
-
- public UnsupportedArchitectureException() {
- super();
- }
-
- public UnsupportedArchitectureException(String detailMessage) {
- super(detailMessage);
- }
-
-}
diff --git a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/Utils.java b/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/Utils.java
deleted file mode 100644
index 87f32bb..0000000
--- a/libraries/RootCommands/src/main/java/org/sufficientlysecure/rootcommands/util/Utils.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2012 Dominik Schürmann
- * Copyright (c) 2012 Michael Elsdörfer (Android Autostarts)
- * Copyright (c) 2012 Stephen Erickson, Chris Ravenscroft, Adam Shanks (RootTools)
- *
- * 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 org.sufficientlysecure.rootcommands.util;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Map;
-
-import org.sufficientlysecure.rootcommands.RootCommands;
-
-public class Utils {
- /*
- * The emulator and ADP1 device both have a su binary in /system/xbin/su, but it doesn't allow
- * apps to use it (su app_29 $ su su: uid 10029 not allowed to su).
- *
- * Cyanogen used to have su in /system/bin/su, in newer versions it's a symlink to
- * /system/xbin/su.
- *
- * The Archos tablet has it in /data/bin/su, since they don't have write access to /system yet.
- */
- static final String[] BinaryPlaces = { "/data/bin/", "/system/bin/", "/system/xbin/", "/sbin/",
- "/data/local/xbin/", "/data/local/bin/", "/system/sd/xbin/", "/system/bin/failsafe/",
- "/data/local/" };
-
- /**
- * Determine the path of the su executable.
- *
- * Code from https://github.com/miracle2k/android-autostarts, use under Apache License was
- * agreed by Michael Elsdörfer
- */
- public static String getSuPath() {
- for (String p : BinaryPlaces) {
- File su = new File(p + "su");
- if (su.exists()) {
- Log.d(RootCommands.TAG, "su found at: " + p);
- return su.getAbsolutePath();
- } else {
- Log.v(RootCommands.TAG, "No su in: " + p);
- }
- }
- Log.d(RootCommands.TAG, "No su found in a well-known location, " + "will just use \"su\".");
- return "su";
- }
-
- /**
- * This code is adapted from java.lang.ProcessBuilder.start().
- *
- * The problem is that Android doesn't allow us to modify the map returned by
- * ProcessBuilder.environment(), even though the docstring indicates that it should. This is
- * because it simply returns the SystemEnvironment object that System.getenv() gives us. The
- * relevant portion in the source code is marked as "// android changed", so presumably it's not
- * the case in the original version of the Apache Harmony project.
- *
- * Note that simply passing the environment variables we want to Process.exec won't be good
- * enough, since that would override the environment we inherited completely.
- *
- * We needed to be able to set a CLASSPATH environment variable for our new process in order to
- * use the "app_process" command directly. Note: "app_process" takes arguments passed on to the
- * Dalvik VM as well; this might be an alternative way to set the class path.
- *
- * Code from https://github.com/miracle2k/android-autostarts, use under Apache License was
- * agreed by Michael Elsdörfer
- */
- public static Process runWithEnv(String command, ArrayList customAddedEnv,
- String baseDirectory) throws IOException {
-
- Map environment = System.getenv();
- String[] envArray = new String[environment.size()
- + (customAddedEnv != null ? customAddedEnv.size() : 0)];
- int i = 0;
- for (Map.Entry entry : environment.entrySet()) {
- envArray[i++] = entry.getKey() + "=" + entry.getValue();
- }
- if (customAddedEnv != null) {
- for (String entry : customAddedEnv) {
- envArray[i++] = entry;
- }
- }
-
- Process process;
- if (baseDirectory == null) {
- process = Runtime.getRuntime().exec(command, envArray, null);
- } else {
- process = Runtime.getRuntime().exec(command, envArray, new File(baseDirectory));
- }
- return process;
- }
-}
diff --git a/libraries/libsuperuser b/libraries/libsuperuser
new file mode 160000
index 0000000..abf0553
--- /dev/null
+++ b/libraries/libsuperuser
@@ -0,0 +1 @@
+Subproject commit abf0553fc1b4d45c9fc646453fa5cce4636f310a
diff --git a/settings.gradle b/settings.gradle
index b841800..72f34c6 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1,2 @@
-include ':app', ':libraries:RootCommands'
+include ':app', ':libsuperuser'
+project(':libsuperuser').projectDir = new File('libraries/libsuperuser/libsuperuser')
\ No newline at end of file
diff --git a/zertman.iml b/zertman.iml
index edb62a6..0bb6048 100644
--- a/zertman.iml
+++ b/zertman.iml
@@ -1,5 +1,12 @@
+
+
+
+
+
+
+