Skip to content

Instantly share code, notes, and snippets.

@d4rken
Created Jan 14, 2014
Embed
What would you like to do?
/*
* Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
* 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;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Locale;
import org.sufficientlysecure.rootcommands.command.SimpleCommand;
import org.sufficientlysecure.rootcommands.util.Log;
//no modifier, this means it is package-private. Only our internal classes can use this.
class Remounter {
private Shell shell;
public Remounter(Shell shell) {
super();
this.shell = shell;
}
/**
* This will take a path, which can contain the file name as well, and attempt to remount the
* underlying partition.
* <p/>
* 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 <code>boolean</code> which indicates whether or not the partition has been
* remounted as specified.
*/
protected boolean remount(String path, String mountType) {
File possibleMountTarget = new File(path);
Mount actualMountTarget = findMountPointRecursive(possibleMountTarget);
if(actualMountTarget == null)
return false;
String target = actualMountTarget.getMountPoint().getAbsolutePath() + " " + actualMountTarget.getMountPoint().getAbsolutePath();
Log.i("DARKEN-Workaround", "Trying to remount " + actualMountTarget.getMountPoint().getAbsolutePath());
Process process = null;
try {
process = Runtime.getRuntime().exec("su");
OutputStreamWriter os = new OutputStreamWriter(process.getOutputStream());
if (mountType.toLowerCase(Locale.getDefault()).equals("rw")) {
os.write("mount -o rw,remount " + target + "\n");
Log.i("DARKEN-Workaround", "Mounted RW");
} else {
os.write("mount -o ro,remount " + target +"\n");
Log.i("DARKEN-Workaround", "Mounted RO");
}
os.write("exit\n");
os.flush();
os.close();
process.waitFor();
Log.i("DARKEN-Workaround", "System remount exitcode:"+process.exitValue());
if(process.exitValue() == 0)
return true;
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
process.destroy();
}
return false;
}
private Mount findMountPointRecursive(final File target) {
File currentTarget = target;
try {
ArrayList<Mount> mounts = getMounts();
while (currentTarget != null) {
for (Mount mount : mounts) {
if (mount.getMountPoint().getAbsolutePath().equals(currentTarget.getAbsolutePath())) {
return mount;
}
}
currentTarget = currentTarget.getParentFile();
}
} catch (Exception e) {
Log.e(RootCommands.TAG, "Exception", e);
}
return null;
}
/**
* This will return an ArrayList of the class Mount. The class mount contains the following
* property's: device mountPoint type flags
* <p/>
* These will provide you with any information you need to work with the mount points.
*
* @return <code>ArrayList<Mount></code> an ArrayList of the class Mount.
* @throws Exception
* if we cannot return the mount points.
*/
protected static ArrayList<Mount> getMounts() throws Exception {
final String tempFile = "/data/local/RootToolsMounts";
// copy /proc/mounts to tempfile. Directly reading it does not work on 4.3
Shell shell = Shell.startRootShell();
Toolbox tb = new Toolbox(shell);
tb.copyFile("/proc/mounts", tempFile, false, false);
tb.setFilePermissions(tempFile, "777");
shell.close();
LineNumberReader lnr = null;
lnr = new LineNumberReader(new FileReader(tempFile));
String line;
ArrayList<Mount> mounts = new ArrayList<Mount>();
while ((line = lnr.readLine()) != null) {
Log.d(RootCommands.TAG, line);
String[] fields = line.split(" ");
mounts.add(new Mount(new File(fields[0]), // device
new File(fields[1]), // mountPoint
fields[2], // fstype
fields[3] // flags
));
}
lnr.close();
return mounts;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment