19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2008, The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "installd.h" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define BUFFER_MAX 1024 /* input buffer for commands */ 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define TOKEN_MAX 8 /* max number of arguments in buffer */ 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define REPLY_MAX 256 /* largest reply allowed */ 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_ping(char **arg, char reply[REPLY_MAX]) 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_install(char **arg, char reply[REPLY_MAX]) 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3135ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root return install(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */ 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_dexopt(char **arg, char reply[REPLY_MAX]) 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* apk_path, uid, is_public */ 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dexopt(arg[0], atoi(arg[1]), atoi(arg[2])); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_move_dex(char **arg, char reply[REPLY_MAX]) 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return move_dex(arg[0], arg[1]); /* src, dst */ 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_rm_dex(char **arg, char reply[REPLY_MAX]) 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return rm_dex(arg[0]); /* pkgname */ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_remove(char **arg, char reply[REPLY_MAX]) 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 520b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return uninstall(arg[0], atoi(arg[1])); /* pkgname, userid */ 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackbornstatic int do_rename(char **arg, char reply[REPLY_MAX]) 56b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn{ 5735ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root return renamepkg(arg[0], arg[1]); /* oldpkgname, newpkgname */ 58b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn} 59b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_free_cache(char **arg, char reply[REPLY_MAX]) /* TODO int:free_size */ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 623e319a9962434e1fae86b2180ad210170f02c152Kenny Root return free_cache((int64_t)atoll(arg[0])); /* free_size */ 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_rm_cache(char **arg, char reply[REPLY_MAX]) 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6735ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root return delete_cache(arg[0]); /* pkgname */ 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_protect(char **arg, char reply[REPLY_MAX]) 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return protect(arg[0], atoi(arg[1])); /* pkgname, gid */ 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_get_size(char **arg, char reply[REPLY_MAX]) 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 773e319a9962434e1fae86b2180ad210170f02c152Kenny Root int64_t codesize = 0; 783e319a9962434e1fae86b2180ad210170f02c152Kenny Root int64_t datasize = 0; 793e319a9962434e1fae86b2180ad210170f02c152Kenny Root int64_t cachesize = 0; 80292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn int64_t asecsize = 0; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res = 0; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* pkgdir, apkpath */ 84292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn res = get_size(arg[0], arg[1], arg[2], arg[3], &codesize, &datasize, &cachesize, &asecsize); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 863e319a9962434e1fae86b2180ad210170f02c152Kenny Root /* 873e319a9962434e1fae86b2180ad210170f02c152Kenny Root * Each int64_t can take up 22 characters printed out. Make sure it 883e319a9962434e1fae86b2180ad210170f02c152Kenny Root * doesn't go over REPLY_MAX in the future. 893e319a9962434e1fae86b2180ad210170f02c152Kenny Root */ 90292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64, 91292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn codesize, datasize, cachesize, asecsize); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_rm_user_data(char **arg, char reply[REPLY_MAX]) 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 970b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return delete_user_data(arg[0], atoi(arg[1])); /* pkgname, userid */ 980b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani} 990b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 1000b285499db739ba50f2f839d633e763c70e67f96Amith Yamasanistatic int do_mk_user_data(char **arg, char reply[REPLY_MAX]) 1010b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani{ 1020b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return make_user_data(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, userid */ 1030b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani} 1040b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 1050b285499db739ba50f2f839d633e763c70e67f96Amith Yamasanistatic int do_rm_user(char **arg, char reply[REPLY_MAX]) 1060b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani{ 1070b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return delete_persona(atoi(arg[0])); /* userid */ 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 110b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackbornstatic int do_movefiles(char **arg, char reply[REPLY_MAX]) 111b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn{ 112b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn return movefiles(); 113b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn} 114b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn 1156a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Rootstatic int do_linklib(char **arg, char reply[REPLY_MAX]) 1166a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root{ 1176a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root return linklib(arg[0], arg[1]); 1186a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root} 1196a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root 1206a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Rootstatic int do_unlinklib(char **arg, char reply[REPLY_MAX]) 1216a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root{ 1226a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root return unlinklib(arg[0]); 1236a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root} 1246a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct cmdinfo { 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char *name; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned numargs; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int (*func)(char **arg, char reply[REPLY_MAX]); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct cmdinfo cmds[] = { 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "ping", 0, do_ping }, 13335ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root { "install", 3, do_install }, 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "dexopt", 3, do_dexopt }, 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "movedex", 2, do_move_dex }, 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "rmdex", 1, do_rm_dex }, 1370b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani { "remove", 2, do_remove }, 13835ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root { "rename", 2, do_rename }, 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "freecache", 1, do_free_cache }, 14035ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root { "rmcache", 1, do_rm_cache }, 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "protect", 2, do_protect }, 142292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn { "getsize", 4, do_get_size }, 1430b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani { "rmuserdata", 2, do_rm_user_data }, 144b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn { "movefiles", 0, do_movefiles }, 1456a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root { "linklib", 2, do_linklib }, 1466a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root { "unlinklib", 1, do_unlinklib }, 1470b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani { "mkuserdata", 3, do_mk_user_data }, 1480b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani { "rmuser", 1, do_rm_user }, 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int readx(int s, void *_buf, int count) 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char *buf = _buf; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = 0, r; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count < 0) return -1; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (n < count) { 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = read(s, buf + n, count - n); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r < 0) { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (errno == EINTR) continue; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("read error: %s\n", strerror(errno)); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r == 0) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("eof\n"); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; /* EOF */ 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += r; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int writex(int s, const void *_buf, int count) 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char *buf = _buf; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = 0, r; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count < 0) return -1; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (n < count) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = write(s, buf + n, count - n); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r < 0) { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (errno == EINTR) continue; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("write error: %s\n", strerror(errno)); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += r; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* Tokenize the command buffer, locate a matching command, 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ensure that the required number of arguments are provided, 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * call the function(), return the result. 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int execute(int s, char cmd[BUFFER_MAX]) 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char reply[REPLY_MAX]; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char *arg[TOKEN_MAX+1]; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned i; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned n = 0; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned short count; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret = -1; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// LOGI("execute('%s')\n", cmd); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* default reply is "" */ 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reply[0] = 0; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* n is number of args (not counting arg[0]) */ 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project arg[0] = cmd; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*cmd) { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isspace(*cmd)) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *cmd++ = 0; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n++; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project arg[n] = cmd; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n == TOKEN_MAX) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("too many arguments\n"); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmd++; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!strcmp(cmds[i].name,arg[0])) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != cmds[i].numargs) { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("%s requires %d arguments (%d given)\n", 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmds[i].name, cmds[i].numargs, n); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = cmds[i].func(arg + 1, reply); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("unsupported command '%s'\n", arg[0]); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone: 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (reply[0]) { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply); 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = snprintf(cmd, BUFFER_MAX, "%d", ret); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n > BUFFER_MAX) n = BUFFER_MAX; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count = n; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// LOGI("reply: '%s'\n", cmd); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (writex(s, &count, sizeof(count))) return -1; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (writex(s, cmd, count)) return -1; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root/** 25286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root * Initialize all the global variables that are used elsewhere. Returns 0 upon 25386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root * success and -1 on error. 25486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root */ 25586c9584559439504fc57ece2ccd9b6cbd568430cKenny Rootvoid free_globals() { 25686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root size_t i; 25786c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 25886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root for (i = 0; i < android_system_dirs.count; i++) { 25986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (android_system_dirs.dirs[i].path != NULL) { 26086c9584559439504fc57ece2ccd9b6cbd568430cKenny Root free(android_system_dirs.dirs[i].path); 26186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 26286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 26386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 26486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root free(android_system_dirs.dirs); 26586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root} 26686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 26786c9584559439504fc57ece2ccd9b6cbd568430cKenny Rootint initialize_globals() { 26886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // Get the android data directory. 26986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (get_path_from_env(&android_data_dir, "ANDROID_DATA") < 0) { 27086c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 27186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 27286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 27386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // Get the android app directory. 27486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (copy_and_append(&android_app_dir, &android_data_dir, APP_SUBDIR) < 0) { 27586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 27686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 27786c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 27886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // Get the android protected app directory. 27986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (copy_and_append(&android_app_private_dir, &android_data_dir, PRIVATE_APP_SUBDIR) < 0) { 28086c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 28186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 28286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 28386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // Get the sd-card ASEC mount point. 28486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (get_path_from_env(&android_asec_dir, "ASEC_MOUNTPOINT") < 0) { 28586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 28686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 28786c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 28886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // Take note of the system and vendor directories. 28986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root android_system_dirs.count = 2; 29086c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 29186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root android_system_dirs.dirs = calloc(android_system_dirs.count, sizeof(dir_rec_t)); 29286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (android_system_dirs.dirs == NULL) { 29386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root LOGE("Couldn't allocate array for dirs; aborting\n"); 29486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 29586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 29686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 29786c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // system 29886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (get_path_from_env(&android_system_dirs.dirs[0], "ANDROID_ROOT") < 0) { 29986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root free_globals(); 30086c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 30186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 30286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 3030b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani // append "app/" to dirs[0] 3040b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani char *system_app_path = build_string2(android_system_dirs.dirs[0].path, APP_SUBDIR); 3050b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani android_system_dirs.dirs[0].path = system_app_path; 3060b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani android_system_dirs.dirs[0].len = strlen(system_app_path); 3070b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 30886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // vendor 30986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // TODO replace this with an environment variable (doesn't exist yet) 3100b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani android_system_dirs.dirs[1].path = "/vendor/app/"; 31186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root android_system_dirs.dirs[1].len = strlen(android_system_dirs.dirs[1].path); 31286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 31386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return 0; 31486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root} 31586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 3160b285499db739ba50f2f839d633e763c70e67f96Amith Yamasaniint initialize_directories() { 3170b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani // /data/user 3180b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani char *user_data_dir = build_string2(android_data_dir.path, SECONDARY_USER_PREFIX); 3190b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani // /data/data 3200b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani char *legacy_data_dir = build_string2(android_data_dir.path, PRIMARY_USER_PREFIX); 3210b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani // /data/user/0 3220b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani char *primary_data_dir = build_string3(android_data_dir.path, SECONDARY_USER_PREFIX, 3230b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani "0"); 3240b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani int ret = -1; 3250b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani if (user_data_dir != NULL && primary_data_dir != NULL && legacy_data_dir != NULL) { 3260b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani ret = 0; 3270b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani // Make the /data/user directory if necessary 3280b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani if (access(user_data_dir, R_OK) < 0) { 3290b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani if (mkdir(user_data_dir, 0755) < 0) { 3300b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return -1; 3310b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 3320b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani if (chown(user_data_dir, AID_SYSTEM, AID_SYSTEM) < 0) { 3330b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return -1; 3340b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 3350b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 3360b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani // Make the /data/user/0 symlink to /data/data if necessary 3370b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani if (access(primary_data_dir, R_OK) < 0) { 3380b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani ret = symlink(legacy_data_dir, primary_data_dir); 3390b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 3400b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani free(user_data_dir); 3410b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani free(legacy_data_dir); 3420b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani free(primary_data_dir); 3430b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 3440b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return ret; 3450b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani} 3460b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 34786c9584559439504fc57ece2ccd9b6cbd568430cKenny Rootint main(const int argc, const char *argv[]) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[BUFFER_MAX]; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct sockaddr addr; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socklen_t alen; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int lsocket, s, count; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 35386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (initialize_globals() < 0) { 35486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root LOGE("Could not initialize globals; exiting.\n"); 35586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root exit(1); 35686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 35786c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 3580b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani if (initialize_directories() < 0) { 3590b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani LOGE("Could not create directories; exiting.\n"); 3600b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani exit(1); 3610b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 3620b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lsocket = android_get_control_socket(SOCKET_PATH); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lsocket < 0) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Failed to get socket from environment: %s\n", strerror(errno)); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project exit(1); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listen(lsocket, 5)) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Listen on socket failed: %s\n", strerror(errno)); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project exit(1); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fcntl(lsocket, F_SETFD, FD_CLOEXEC); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (;;) { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alen = sizeof(addr); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = accept(lsocket, &addr, &alen); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s < 0) { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Accept failed: %s\n", strerror(errno)); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fcntl(s, F_SETFD, FD_CLOEXEC); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGI("new connection\n"); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (;;) { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned short count; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (readx(s, &count, sizeof(count))) { 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("failed to read size\n"); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((count < 1) || (count >= BUFFER_MAX)) { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("invalid size %d\n", count); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (readx(s, buf, count)) { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("failed to read command\n"); 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[count] = 0; 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (execute(s, buf)) break; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGI("closing connection\n"); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(s); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 407