TEST_F(UtilsTest, CreateMovePath_Primary) { char path[PKG_PATH_MAX]; EXPECT_EQ(0, create_move_path(path, "com.android.test", "shared_prefs", 0)) << "Should be able to create move path for primary user"; EXPECT_STREQ("/data/data/com.android.test/shared_prefs", path) << "Primary user package directory should be created correctly"; }
int movefiles() { DIR *d; int dfd, subfd; struct dirent *de; struct stat s; char buf[PKG_PATH_MAX+1]; int bufp, bufe, bufi, readlen; char srcpkg[PKG_NAME_MAX]; char dstpkg[PKG_NAME_MAX]; char srcpath[PKG_PATH_MAX]; char dstpath[PKG_PATH_MAX]; int dstuid=-1, dstgid=-1; int hasspace; d = opendir(UPDATE_COMMANDS_DIR_PREFIX); if (d == NULL) { goto done; } dfd = dirfd(d); /* Iterate through all files in the directory, executing the * file movements requested there-in. */ while ((de = readdir(d))) { const char *name = de->d_name; if (de->d_type == DT_DIR) { continue; } else { subfd = openat(dfd, name, O_RDONLY); if (subfd < 0) { ALOGW("Unable to open update commands at %s%s\n", UPDATE_COMMANDS_DIR_PREFIX, name); continue; } bufp = 0; bufe = 0; buf[PKG_PATH_MAX] = 0; srcpkg[0] = dstpkg[0] = 0; while (1) { bufi = bufp; while (bufi < bufe && buf[bufi] != '\n') { bufi++; } if (bufi < bufe) { buf[bufi] = 0; ALOGV("Processing line: %s\n", buf+bufp); hasspace = 0; while (bufp < bufi && isspace(buf[bufp])) { hasspace = 1; bufp++; } if (buf[bufp] == '#' || bufp == bufi) { // skip comments and empty lines. } else if (hasspace) { if (dstpkg[0] == 0) { ALOGW("Path before package line in %s%s: %s\n", UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp); } else if (srcpkg[0] == 0) { // Skip -- source package no longer exists. } else { ALOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg); if (!create_move_path(srcpath, srcpkg, buf+bufp, 0) && !create_move_path(dstpath, dstpkg, buf+bufp, 0)) { movefileordir(srcpath, dstpath, strlen(dstpath)-strlen(buf+bufp), dstuid, dstgid, &s); } } } else { char* div = strchr(buf+bufp, ':'); if (div == NULL) { ALOGW("Bad package spec in %s%s; no ':' sep: %s\n", UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp); } else { *div = 0; div++; if (strlen(buf+bufp) < PKG_NAME_MAX) { strcpy(dstpkg, buf+bufp); } else { srcpkg[0] = dstpkg[0] = 0; ALOGW("Package name too long in %s%s: %s\n", UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp); } if (strlen(div) < PKG_NAME_MAX) { strcpy(srcpkg, div); } else { srcpkg[0] = dstpkg[0] = 0; ALOGW("Package name too long in %s%s: %s\n", UPDATE_COMMANDS_DIR_PREFIX, name, div); } if (srcpkg[0] != 0) { if (!create_pkg_path(srcpath, srcpkg, PKG_DIR_POSTFIX, 0)) { if (lstat(srcpath, &s) < 0) { // Package no longer exists -- skip. srcpkg[0] = 0; } } else { srcpkg[0] = 0; ALOGW("Can't create path %s in %s%s\n", div, UPDATE_COMMANDS_DIR_PREFIX, name); } if (srcpkg[0] != 0) { if (!create_pkg_path(dstpath, dstpkg, PKG_DIR_POSTFIX, 0)) { if (lstat(dstpath, &s) == 0) { dstuid = s.st_uid; dstgid = s.st_gid; } else { // Destination package doesn't // exist... due to original-package, // this is normal, so don't be // noisy about it. srcpkg[0] = 0; } } else { srcpkg[0] = 0; ALOGW("Can't create path %s in %s%s\n", div, UPDATE_COMMANDS_DIR_PREFIX, name); } } ALOGV("Transfering from %s to %s: uid=%d\n", srcpkg, dstpkg, dstuid); } } } bufp = bufi+1; } else { if (bufp == 0) { if (bufp < bufe) { ALOGW("Line too long in %s%s, skipping: %s\n", UPDATE_COMMANDS_DIR_PREFIX, name, buf); } } else if (bufp < bufe) { memcpy(buf, buf+bufp, bufe-bufp); bufe -= bufp; bufp = 0; } readlen = read(subfd, buf+bufe, PKG_PATH_MAX-bufe); if (readlen < 0) { ALOGW("Failure reading update commands in %s%s: %s\n", UPDATE_COMMANDS_DIR_PREFIX, name, strerror(errno)); break; } else if (readlen == 0) { break; } bufe += readlen; buf[bufe] = 0; ALOGV("Read buf: %s\n", buf); } } close(subfd); } } closedir(d); done: return 0; }
TEST_F(UtilsTest, CreateMovePath_Fail_LeafTooLong) { char path[PKG_PATH_MAX]; EXPECT_EQ(-1, create_move_path(path, "com.android.test", REALLY_LONG_LEAF_NAME, 0)) << "Should fail to create move path for primary user"; }
TEST_F(UtilsTest, CreateMovePath_Fail_AppTooLong) { char path[PKG_PATH_MAX]; EXPECT_EQ(-1, create_move_path(path, REALLY_LONG_APP_NAME, "shared_prefs", 0)) << "Should fail to create move path for primary user"; }