package org.safermobile.utils; /* Copyright (c) 2009, Nathan Freitas, Orbot / The Guardian Project - http://openideals.com/guardian */ /* See LICENSE for licensing information */ import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.StringTokenizer; import android.content.Intent; import android.util.Log; public class ShellUtils { public final static String TAG = "ShellUtils"; //various console cmds public final static String SHELL_CMD_CHMOD = "chmod"; public final static String SHELL_CMD_KILL = "kill -9"; public final static String SHELL_CMD_RM = "rm"; public final static String SHELL_CMD_PS = "ps"; public final static String SHELL_CMD_PIDOF = "pidof"; public final static String CHMOD_EXE_VALUE = "777"; public final static int DEFAULT_WAIT_FOR = 3000; private boolean runAsRoot = false; Process proc = null; StreamThread it; StreamThread et; StreamThread.StreamUpdate logUpdate = null; OutputStream stdout; public ShellUtils (boolean mRunAsRoot, StreamThread.StreamUpdate mLogUpdate) throws IOException { runAsRoot = mRunAsRoot; if (mLogUpdate != null) logUpdate = mLogUpdate; else logUpdate = new LogUpdate(); initShell(); } private void initShell() throws IOException { if (proc != null) proc.destroy(); if (runAsRoot) proc = Runtime.getRuntime().exec("su - sh"); else proc = Runtime.getRuntime().exec("sh"); stdout = proc.getOutputStream(); it = new StreamThread(proc.getInputStream(), logUpdate); et = new StreamThread(proc.getErrorStream(), logUpdate); it.start(); et.start(); } /** * Check if we have root access * @return boolean true if we have root */ public boolean checkRootAccess() { try { // Run an empty script just to check root access String[] cmd = {"exit 0"}; doShellCommand(cmd); int exitCode = doExit(); if (exitCode == 0) { return true; } } catch (IOException e) { //this means that there is no root to be had (normally) so we won't log anything logException("Error checking for root access",e); } catch (Exception e) { logException("Error checking for root access",e); //this means that there is no root to be had (normally) } logMessage("Could not acquire root permissions"); return false; } public int findProcessId(String command) { int procId = -1; try { procId = findProcessIdWithPidOf(command); if (procId == -1) procId = findProcessIdWithPS(command); } catch (Exception e) { try { procId = findProcessIdWithPS(command); } catch (Exception e2) { logException("Unable to get proc id for: " + command,e2); } } return procId; } //use 'pidof' command public int findProcessIdWithPidOf(String command) throws Exception { int procId = -1; Runtime r = Runtime.getRuntime(); Process procPs = null; String baseName = new File(command).getName(); //fix contributed my mikos on 2010.12.10 procPs = r.exec(new String[] {SHELL_CMD_PIDOF, baseName}); //procPs = r.exec(SHELL_CMD_PIDOF); BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream())); String line = null; while ((line = reader.readLine())!=null) { try { //this line should just be the process id procId = Integer.parseInt(line.trim()); break; } catch (NumberFormatException e) { logException("unable to parse process pid: " + line,e); } } return procId; } //use 'ps' command public int findProcessIdWithPS(String command) throws Exception { int procId = -1; Runtime r = Runtime.getRuntime(); Process procPs = null; procPs = r.exec(SHELL_CMD_PS); BufferedReader reader = new BufferedReader(new InputStreamReader(procPs.getInputStream())); String line = null; while ((line = reader.readLine())!=null) { if (line.indexOf(' ' + command)!=-1) { StringTokenizer st = new StringTokenizer(line," "); st.nextToken(); //proc owner procId = Integer.parseInt(st.nextToken().trim()); break; } } return procId; } public int doExit () throws IOException, InterruptedException { logMessage("> exit"); stdout.write(("exit" + "\n").getBytes("ASCII")); logMessage("> exit"); stdout.write(("exit" + "\n").getBytes("ASCII")); return proc.waitFor(); } public void doShellCommand(String[] cmds) throws Exception { doShellCommand(cmds, DEFAULT_WAIT_FOR); } public void doShellCommand(String[] cmds, int waitTime) throws Exception { for (int i = 0; i < cmds.length; i++) { logMessage("> " + cmds[i]); stdout.write((cmds[i] + "\n").getBytes("ASCII")); } try { Thread.sleep (waitTime); } catch (Exception e){} } public class LogUpdate implements StreamThread.StreamUpdate { StringBuilder log = new StringBuilder(); @Override public void update(String val) { log.append(val); log.append('\n'); logMessage(val); } public String getLog () { return log.toString(); } } public static void logException (String exc, Exception e) { Log.e(TAG, exc, e); } public static void logMessage (String msg) { Log.i(TAG, msg); } }