最近开发Android app需要用到root权限去调用一些shell程序,接触过Linux的同学知道用su这个命令,su的意思是switch user,切换用户。然而在我调用su的时候,授权管理器总会弹出确认提示,更操蛋的是我手机安装的授权管理器即使设置了自动授权所有请求都不起作用!火了!干脆自己找su源码去改写个来用。
搜索了一下,发现superuser的su源码:
[cpp]
view plain
copy
/* ** 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. */ #include #include #include #include #include #include #include #include #include #include #include #define DBPATH "/data/data/com.koushikdutta.superuser/databases/superuser.sqlite" static int g_puid; static void printRow(int argc, char** argv, char** azColName) { int i; for (i = 0; i count = count; // remove whitelist entries that are expired if (count - 1 db, remove, NULL, NULL, NULL); return 0; } char update[1024]; sprintf(update, "update whitelist set count=%d where _id='%s';", count, argv[0]); sqlite3_exec(callInfo->db, update, NULL, NULL, NULL); return 0; } static int checkWhitelist() { sqlite3 *db; int rc = sqlite3_open_v2(DBPATH, &db, SQLITE_OPEN_READWRITE, NULL); if (!rc) { char *errorMessage; char query[1024]; sprintf(query, "select * from whitelist where _id=%d limit 1;", g_puid); struct whitelistCallInfo callInfo; callInfo.count = 0; callInfo.db = db; rc = sqlite3_exec(db, query, whitelistCallback, &callInfo, &errorMessage); if (rc != SQLITE_OK) { sqlite3_close(db); return 0; } sqlite3_close(db); return callInfo.count; } sqlite3_close(db); return 0; } static int executionFailure(char *context) { fprintf(stderr, "su: %s. Error:%s\n", context, strerror(errno)); return -errno; } static int permissionDenied() { // the superuser activity couldn't be started printf("su: permission denied\n"); return 1; } int main(int argc, char **argv) { struct stat stats; struct passwd *pw; int uid = 0; int gid = 0; int ppid = getppid(); char szppid[256]; sprintf(szppid, "/proc/%d", ppid); stat(szppid, &stats); g_puid = stats.st_uid; // lets make sure the caller is allowed to execute this if (!checkWhitelist()) { char sysCmd[1024]; sprintf(sysCmd, "am start -a android.intent.action.MAIN -n com.koushikdutta.superuser/com.koushikdutta.superuser.SuperuserRequestActivity --ei uid %d --ei pid %d > /dev/null", g_puid, ppid); if (system(sysCmd)) return executionFailure("am."); int found = 0; int i; for (i = 0; i 0 means yes/always // 0) { found = 1; break; } else if (checkResult |