1 /* 2 ** Copyright 2008, The Android Open Source Project 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 #include "installd.h" 18 19 int install(const char *pkgname, uid_t uid, gid_t gid) 20 { 21 char pkgdir[PKG_PATH_MAX]; 22 char libdir[PKG_PATH_MAX]; 23 24 if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) { 25 LOGE("invalid uid/gid: %d %d\n", uid, gid); 26 return -1; 27 28 } 29 30 if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) 31 return -1; 32 if (create_pkg_path(libdir, PKG_LIB_PREFIX, pkgname, PKG_LIB_POSTFIX)) 33 return -1; 34 35 36 if (mkdir(pkgdir, 0751) < 0) { 37 LOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno)); 38 return -errno; 39 } 40 if (chown(pkgdir, uid, gid) < 0) { 41 LOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno)); 42 unlink(pkgdir); 43 return -errno; 44 } 45 if (mkdir(libdir, 0755) < 0) { 46 LOGE("cannot create dir '%s': %s\n", libdir, strerror(errno)); 47 unlink(pkgdir); 48 return -errno; 49 } 50 if (chown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) { 51 LOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno)); 52 unlink(libdir); 53 unlink(pkgdir); 54 return -errno; 55 } 56 return 0; 57 } 58 59 int uninstall(const char *pkgname) 60 { 61 char pkgdir[PKG_PATH_MAX]; 62 63 if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) 64 return -1; 65 66 /* delete contents AND directory, no exceptions */ 67 return delete_dir_contents(pkgdir, 1, 0); 68 } 69 70 int renamepkg(const char *oldpkgname, const char *newpkgname) 71 { 72 char oldpkgdir[PKG_PATH_MAX]; 73 char newpkgdir[PKG_PATH_MAX]; 74 75 if (create_pkg_path(oldpkgdir, PKG_DIR_PREFIX, oldpkgname, PKG_DIR_POSTFIX)) 76 return -1; 77 if (create_pkg_path(newpkgdir, PKG_DIR_PREFIX, newpkgname, PKG_DIR_POSTFIX)) 78 return -1; 79 80 81 if (rename(oldpkgdir, newpkgdir) < 0) { 82 LOGE("cannot rename dir '%s' to '%s': %s\n", oldpkgdir, newpkgdir, strerror(errno)); 83 return -errno; 84 } 85 return 0; 86 } 87 88 int delete_user_data(const char *pkgname) 89 { 90 char pkgdir[PKG_PATH_MAX]; 91 92 if (create_pkg_path(pkgdir, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) 93 return -1; 94 95 /* delete contents, excluding "lib", but not the directory itself */ 96 return delete_dir_contents(pkgdir, 0, "lib"); 97 } 98 99 int delete_cache(const char *pkgname) 100 { 101 char cachedir[PKG_PATH_MAX]; 102 103 if (create_pkg_path(cachedir, CACHE_DIR_PREFIX, pkgname, CACHE_DIR_POSTFIX)) 104 return -1; 105 106 107 /* delete contents, not the directory, no exceptions */ 108 return delete_dir_contents(cachedir, 0, 0); 109 } 110 111 static int disk_free() 112 { 113 struct statfs sfs; 114 if (statfs(PKG_DIR_PREFIX, &sfs) == 0) { 115 return sfs.f_bavail * sfs.f_bsize; 116 } else { 117 return -1; 118 } 119 } 120 121 /* Try to ensure free_size bytes of storage are available. 122 * Returns 0 on success. 123 * This is rather simple-minded because doing a full LRU would 124 * be potentially memory-intensive, and without atime it would 125 * also require that apps constantly modify file metadata even 126 * when just reading from the cache, which is pretty awful. 127 */ 128 int free_cache(int free_size) 129 { 130 const char *name; 131 int dfd, subfd; 132 DIR *d; 133 struct dirent *de; 134 int avail; 135 136 avail = disk_free(); 137 if (avail < 0) return -1; 138 139 LOGI("free_cache(%d) avail %d\n", free_size, avail); 140 if (avail >= free_size) return 0; 141 142 d = opendir(PKG_DIR_PREFIX); 143 if (d == NULL) { 144 LOGE("cannot open %s\n", PKG_DIR_PREFIX); 145 return -1; 146 } 147 dfd = dirfd(d); 148 149 while ((de = readdir(d))) { 150 if (de->d_type != DT_DIR) continue; 151 name = de->d_name; 152 153 /* always skip "." and ".." */ 154 if (name[0] == '.') { 155 if (name[1] == 0) continue; 156 if ((name[1] == '.') && (name[2] == 0)) continue; 157 } 158 159 subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); 160 if (subfd < 0) continue; 161 162 delete_dir_contents_fd(subfd, "cache"); 163 close(subfd); 164 165 avail = disk_free(); 166 if (avail >= free_size) { 167 closedir(d); 168 return 0; 169 } 170 } 171 closedir(d); 172 173 /* Fail case - not possible to free space */ 174 return -1; 175 } 176 177 /* used by move_dex, rm_dex, etc to ensure that the provided paths 178 * don't point anywhere other than at the APK_DIR_PREFIX 179 */ 180 static int is_valid_apk_path(const char *path) 181 { 182 int len = strlen(APK_DIR_PREFIX); 183 int nosubdircheck = 0; 184 if (strncmp(path, APK_DIR_PREFIX, len)) { 185 len = strlen(PROTECTED_DIR_PREFIX); 186 if (strncmp(path, PROTECTED_DIR_PREFIX, len)) { 187 len = strlen(SDCARD_DIR_PREFIX); 188 if (strncmp(path, SDCARD_DIR_PREFIX, len)) { 189 LOGE("invalid apk path '%s' (bad prefix)\n", path); 190 return 0; 191 } else { 192 nosubdircheck = 1; 193 } 194 } 195 } 196 if ((nosubdircheck != 1) && strchr(path + len, '/')) { 197 LOGE("invalid apk path '%s' (subdir?)\n", path); 198 return 0; 199 } 200 if (path[len] == '.') { 201 LOGE("invalid apk path '%s' (trickery)\n", path); 202 return 0; 203 } 204 return 1; 205 } 206 207 int move_dex(const char *src, const char *dst) 208 { 209 char src_dex[PKG_PATH_MAX]; 210 char dst_dex[PKG_PATH_MAX]; 211 212 if (!is_valid_apk_path(src)) return -1; 213 if (!is_valid_apk_path(dst)) return -1; 214 215 if (create_cache_path(src_dex, src)) return -1; 216 if (create_cache_path(dst_dex, dst)) return -1; 217 218 LOGI("move %s -> %s\n", src_dex, dst_dex); 219 if (rename(src_dex, dst_dex) < 0) { 220 return -1; 221 } else { 222 return 0; 223 } 224 } 225 226 int rm_dex(const char *path) 227 { 228 char dex_path[PKG_PATH_MAX]; 229 230 if (!is_valid_apk_path(path)) return -1; 231 if (create_cache_path(dex_path, path)) return -1; 232 233 LOGI("unlink %s\n", dex_path); 234 if (unlink(dex_path) < 0) { 235 return -1; 236 } else { 237 return 0; 238 } 239 } 240 241 int protect(char *pkgname, gid_t gid) 242 { 243 struct stat s; 244 char pkgpath[PKG_PATH_MAX]; 245 246 if (gid < AID_SYSTEM) return -1; 247 248 if (create_pkg_path(pkgpath, PROTECTED_DIR_PREFIX, pkgname, ".apk")) 249 return -1; 250 251 if (stat(pkgpath, &s) < 0) return -1; 252 253 if (chown(pkgpath, s.st_uid, gid) < 0) { 254 LOGE("failed to chgrp '%s': %s\n", pkgpath, strerror(errno)); 255 return -1; 256 } 257 258 if (chmod(pkgpath, S_IRUSR|S_IWUSR|S_IRGRP) < 0) { 259 LOGE("failed to chmod '%s': %s\n", pkgpath, strerror(errno)); 260 return -1; 261 } 262 263 return 0; 264 } 265 266 static int stat_size(struct stat *s) 267 { 268 int blksize = s->st_blksize; 269 int size = s->st_size; 270 271 if (blksize) { 272 /* round up to filesystem block size */ 273 size = (size + blksize - 1) & (~(blksize - 1)); 274 } 275 276 return size; 277 } 278 279 static int calculate_dir_size(int dfd) 280 { 281 int size = 0; 282 struct stat s; 283 DIR *d; 284 struct dirent *de; 285 286 d = fdopendir(dfd); 287 if (d == NULL) { 288 close(dfd); 289 return 0; 290 } 291 292 while ((de = readdir(d))) { 293 const char *name = de->d_name; 294 if (de->d_type == DT_DIR) { 295 int subfd; 296 /* always skip "." and ".." */ 297 if (name[0] == '.') { 298 if (name[1] == 0) continue; 299 if ((name[1] == '.') && (name[2] == 0)) continue; 300 } 301 subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); 302 if (subfd >= 0) { 303 size += calculate_dir_size(subfd); 304 } 305 } else { 306 if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { 307 size += stat_size(&s); 308 } 309 } 310 } 311 closedir(d); 312 return size; 313 } 314 315 int get_size(const char *pkgname, const char *apkpath, 316 const char *fwdlock_apkpath, 317 int *_codesize, int *_datasize, int *_cachesize) 318 { 319 DIR *d; 320 int dfd; 321 struct dirent *de; 322 struct stat s; 323 char path[PKG_PATH_MAX]; 324 325 int codesize = 0; 326 int datasize = 0; 327 int cachesize = 0; 328 329 /* count the source apk as code -- but only if it's not 330 * on the /system partition and its not on the sdcard. 331 */ 332 if (strncmp(apkpath, "/system", 7) != 0 && 333 strncmp(apkpath, SDCARD_DIR_PREFIX, 7) != 0) { 334 if (stat(apkpath, &s) == 0) { 335 codesize += stat_size(&s); 336 } 337 } 338 /* count the forward locked apk as code if it is given 339 */ 340 if (fwdlock_apkpath != NULL && fwdlock_apkpath[0] != '!') { 341 if (stat(fwdlock_apkpath, &s) == 0) { 342 codesize += stat_size(&s); 343 } 344 } 345 /* count the cached dexfile as code */ 346 if (!create_cache_path(path, apkpath)) { 347 if (stat(path, &s) == 0) { 348 codesize += stat_size(&s); 349 } 350 } 351 352 if (create_pkg_path(path, PKG_DIR_PREFIX, pkgname, PKG_DIR_POSTFIX)) { 353 goto done; 354 } 355 356 d = opendir(path); 357 if (d == NULL) { 358 goto done; 359 } 360 dfd = dirfd(d); 361 362 /* most stuff in the pkgdir is data, except for the "cache" 363 * directory and below, which is cache, and the "lib" directory 364 * and below, which is code... 365 */ 366 while ((de = readdir(d))) { 367 const char *name = de->d_name; 368 369 if (de->d_type == DT_DIR) { 370 int subfd; 371 /* always skip "." and ".." */ 372 if (name[0] == '.') { 373 if (name[1] == 0) continue; 374 if ((name[1] == '.') && (name[2] == 0)) continue; 375 } 376 subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY); 377 if (subfd >= 0) { 378 int size = calculate_dir_size(subfd); 379 if (!strcmp(name,"lib")) { 380 codesize += size; 381 } else if(!strcmp(name,"cache")) { 382 cachesize += size; 383 } else { 384 datasize += size; 385 } 386 } 387 } else { 388 if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { 389 datasize += stat_size(&s); 390 } 391 } 392 } 393 closedir(d); 394 done: 395 *_codesize = codesize; 396 *_datasize = datasize; 397 *_cachesize = cachesize; 398 return 0; 399 } 400 401 402 /* a simpler version of dexOptGenerateCacheFileName() */ 403 int create_cache_path(char path[PKG_PATH_MAX], const char *src) 404 { 405 char *tmp; 406 int srclen; 407 int dstlen; 408 409 srclen = strlen(src); 410 411 /* demand that we are an absolute path */ 412 if ((src == 0) || (src[0] != '/') || strstr(src,"..")) { 413 return -1; 414 } 415 416 if (srclen > PKG_PATH_MAX) { // XXX: PKG_NAME_MAX? 417 return -1; 418 } 419 420 dstlen = srclen + strlen(DALVIK_CACHE_PREFIX) + 421 strlen(DALVIK_CACHE_POSTFIX) + 1; 422 423 if (dstlen > PKG_PATH_MAX) { 424 return -1; 425 } 426 427 sprintf(path,"%s%s%s", 428 DALVIK_CACHE_PREFIX, 429 src + 1, /* skip the leading / */ 430 DALVIK_CACHE_POSTFIX); 431 432 for(tmp = path + strlen(DALVIK_CACHE_PREFIX); *tmp; tmp++) { 433 if (*tmp == '/') { 434 *tmp = '@'; 435 } 436 } 437 438 return 0; 439 } 440 441 static void run_dexopt(int zip_fd, int odex_fd, const char* input_file_name, 442 const char* dexopt_flags) 443 { 444 static const char* DEX_OPT_BIN = "/system/bin/dexopt"; 445 static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig 446 char zip_num[MAX_INT_LEN]; 447 char odex_num[MAX_INT_LEN]; 448 449 sprintf(zip_num, "%d", zip_fd); 450 sprintf(odex_num, "%d", odex_fd); 451 452 execl(DEX_OPT_BIN, DEX_OPT_BIN, "--zip", zip_num, odex_num, input_file_name, 453 dexopt_flags, (char*) NULL); 454 LOGE("execl(%s) failed: %s\n", DEX_OPT_BIN, strerror(errno)); 455 } 456 457 static int wait_dexopt(pid_t pid, const char* apk_path) 458 { 459 int status; 460 pid_t got_pid; 461 462 /* 463 * Wait for the optimization process to finish. 464 */ 465 while (1) { 466 got_pid = waitpid(pid, &status, 0); 467 if (got_pid == -1 && errno == EINTR) { 468 printf("waitpid interrupted, retrying\n"); 469 } else { 470 break; 471 } 472 } 473 if (got_pid != pid) { 474 LOGW("waitpid failed: wanted %d, got %d: %s\n", 475 (int) pid, (int) got_pid, strerror(errno)); 476 return 1; 477 } 478 479 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 480 LOGD("DexInv: --- END '%s' (success) ---\n", apk_path); 481 return 0; 482 } else { 483 LOGW("DexInv: --- END '%s' --- status=0x%04x, process failed\n", 484 apk_path, status); 485 return status; /* always nonzero */ 486 } 487 } 488 489 int dexopt(const char *apk_path, uid_t uid, int is_public) 490 { 491 struct utimbuf ut; 492 struct stat apk_stat, dex_stat; 493 char dex_path[PKG_PATH_MAX]; 494 char dexopt_flags[PROPERTY_VALUE_MAX]; 495 char *end; 496 int res, zip_fd=-1, odex_fd=-1; 497 498 /* Before anything else: is there a .odex file? If so, we have 499 * pre-optimized the apk and there is nothing to do here. 500 */ 501 if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) { 502 return -1; 503 } 504 505 /* platform-specific flags affecting optimization and verification */ 506 property_get("dalvik.vm.dexopt-flags", dexopt_flags, ""); 507 508 strcpy(dex_path, apk_path); 509 end = strrchr(dex_path, '.'); 510 if (end != NULL) { 511 strcpy(end, ".odex"); 512 if (stat(dex_path, &dex_stat) == 0) { 513 return 0; 514 } 515 } 516 517 if (create_cache_path(dex_path, apk_path)) { 518 return -1; 519 } 520 521 memset(&apk_stat, 0, sizeof(apk_stat)); 522 stat(apk_path, &apk_stat); 523 524 zip_fd = open(apk_path, O_RDONLY, 0); 525 if (zip_fd < 0) { 526 LOGE("dexopt cannot open '%s' for input\n", apk_path); 527 return -1; 528 } 529 530 unlink(dex_path); 531 odex_fd = open(dex_path, O_RDWR | O_CREAT | O_EXCL, 0644); 532 if (odex_fd < 0) { 533 LOGE("dexopt cannot open '%s' for output\n", dex_path); 534 goto fail; 535 } 536 if (fchown(odex_fd, AID_SYSTEM, uid) < 0) { 537 LOGE("dexopt cannot chown '%s'\n", dex_path); 538 goto fail; 539 } 540 if (fchmod(odex_fd, 541 S_IRUSR|S_IWUSR|S_IRGRP | 542 (is_public ? S_IROTH : 0)) < 0) { 543 LOGE("dexopt cannot chmod '%s'\n", dex_path); 544 goto fail; 545 } 546 547 LOGD("DexInv: --- BEGIN '%s' ---\n", apk_path); 548 549 pid_t pid; 550 pid = fork(); 551 if (pid == 0) { 552 /* child -- drop privileges before continuing */ 553 if (setgid(uid) != 0) { 554 LOGE("setgid(%d) failed during dexopt\n", uid); 555 exit(64); 556 } 557 if (setuid(uid) != 0) { 558 LOGE("setuid(%d) during dexopt\n", uid); 559 exit(65); 560 } 561 if (flock(odex_fd, LOCK_EX | LOCK_NB) != 0) { 562 LOGE("flock(%s) failed: %s\n", dex_path, strerror(errno)); 563 exit(66); 564 } 565 566 run_dexopt(zip_fd, odex_fd, apk_path, dexopt_flags); 567 exit(67); /* only get here on exec failure */ 568 } else { 569 res = wait_dexopt(pid, apk_path); 570 if (res != 0) { 571 LOGE("dexopt failed on '%s' res = %d\n", dex_path, res); 572 goto fail; 573 } 574 } 575 576 ut.actime = apk_stat.st_atime; 577 ut.modtime = apk_stat.st_mtime; 578 utime(dex_path, &ut); 579 580 close(odex_fd); 581 close(zip_fd); 582 return 0; 583 584 fail: 585 if (odex_fd >= 0) { 586 close(odex_fd); 587 unlink(dex_path); 588 } 589 if (zip_fd >= 0) { 590 close(zip_fd); 591 } 592 return -1; 593 } 594 595 int create_move_path(char path[PKG_PATH_MAX], 596 const char* prefix, 597 const char* pkgname, 598 const char* leaf) 599 { 600 if ((strlen(prefix) + strlen(pkgname) + strlen(leaf) + 1) >= PKG_PATH_MAX) { 601 return -1; 602 } 603 604 sprintf(path, "%s%s/%s", prefix, pkgname, leaf); 605 return 0; 606 } 607 608 void mkinnerdirs(char* path, int basepos, mode_t mode, int uid, int gid, 609 struct stat* statbuf) 610 { 611 while (path[basepos] != 0) { 612 if (path[basepos] == '/') { 613 path[basepos] = 0; 614 if (lstat(path, statbuf) < 0) { 615 LOGI("Making directory: %s\n", path); 616 if (mkdir(path, mode) == 0) { 617 chown(path, uid, gid); 618 } else { 619 LOGW("Unable to make directory %s: %s\n", path, strerror(errno)); 620 } 621 } 622 path[basepos] = '/'; 623 basepos++; 624 } 625 basepos++; 626 } 627 } 628 629 int movefileordir(char* srcpath, char* dstpath, int dstbasepos, 630 int dstuid, int dstgid, struct stat* statbuf) 631 { 632 DIR *d; 633 struct dirent *de; 634 int res; 635 636 int srcend = strlen(srcpath); 637 int dstend = strlen(dstpath); 638 639 if (lstat(srcpath, statbuf) < 0) { 640 LOGW("Unable to stat %s: %s\n", srcpath, strerror(errno)); 641 return 1; 642 } 643 644 if ((statbuf->st_mode&S_IFDIR) == 0) { 645 mkinnerdirs(dstpath, dstbasepos, S_IRWXU|S_IRWXG|S_IXOTH, 646 dstuid, dstgid, statbuf); 647 LOGI("Renaming %s to %s (uid %d)\n", srcpath, dstpath, dstuid); 648 if (rename(srcpath, dstpath) >= 0) { 649 if (chown(dstpath, dstuid, dstgid) < 0) { 650 LOGE("cannot chown %s: %s\n", dstpath, strerror(errno)); 651 unlink(dstpath); 652 return 1; 653 } 654 } else { 655 LOGW("Unable to rename %s to %s: %s\n", 656 srcpath, dstpath, strerror(errno)); 657 return 1; 658 } 659 return 0; 660 } 661 662 d = opendir(srcpath); 663 if (d == NULL) { 664 LOGW("Unable to opendir %s: %s\n", srcpath, strerror(errno)); 665 return 1; 666 } 667 668 res = 0; 669 670 while ((de = readdir(d))) { 671 const char *name = de->d_name; 672 /* always skip "." and ".." */ 673 if (name[0] == '.') { 674 if (name[1] == 0) continue; 675 if ((name[1] == '.') && (name[2] == 0)) continue; 676 } 677 678 if ((srcend+strlen(name)) >= (PKG_PATH_MAX-2)) { 679 LOGW("Source path too long; skipping: %s/%s\n", srcpath, name); 680 continue; 681 } 682 683 if ((dstend+strlen(name)) >= (PKG_PATH_MAX-2)) { 684 LOGW("Destination path too long; skipping: %s/%s\n", dstpath, name); 685 continue; 686 } 687 688 srcpath[srcend] = dstpath[dstend] = '/'; 689 strcpy(srcpath+srcend+1, name); 690 strcpy(dstpath+dstend+1, name); 691 692 if (movefileordir(srcpath, dstpath, dstbasepos, dstuid, dstgid, statbuf) != 0) { 693 res = 1; 694 } 695 696 // Note: we will be leaving empty directories behind in srcpath, 697 // but that is okay, the package manager will be erasing all of the 698 // data associated with .apks that disappear. 699 700 srcpath[srcend] = dstpath[dstend] = 0; 701 } 702 703 closedir(d); 704 return res; 705 } 706 707 int movefiles() 708 { 709 DIR *d; 710 int dfd, subfd; 711 struct dirent *de; 712 struct stat s; 713 char buf[PKG_PATH_MAX+1]; 714 int bufp, bufe, bufi, readlen; 715 716 char srcpkg[PKG_NAME_MAX]; 717 char dstpkg[PKG_NAME_MAX]; 718 char srcpath[PKG_PATH_MAX]; 719 char dstpath[PKG_PATH_MAX]; 720 int dstuid=-1, dstgid=-1; 721 int hasspace; 722 723 d = opendir(UPDATE_COMMANDS_DIR_PREFIX); 724 if (d == NULL) { 725 goto done; 726 } 727 dfd = dirfd(d); 728 729 /* Iterate through all files in the directory, executing the 730 * file movements requested there-in. 731 */ 732 while ((de = readdir(d))) { 733 const char *name = de->d_name; 734 735 if (de->d_type == DT_DIR) { 736 continue; 737 } else { 738 subfd = openat(dfd, name, O_RDONLY); 739 if (subfd < 0) { 740 LOGW("Unable to open update commands at %s%s\n", 741 UPDATE_COMMANDS_DIR_PREFIX, name); 742 continue; 743 } 744 745 bufp = 0; 746 bufe = 0; 747 buf[PKG_PATH_MAX] = 0; 748 srcpkg[0] = dstpkg[0] = 0; 749 while (1) { 750 bufi = bufp; 751 while (bufi < bufe && buf[bufi] != '\n') { 752 bufi++; 753 } 754 if (bufi < bufe) { 755 buf[bufi] = 0; 756 LOGV("Processing line: %s\n", buf+bufp); 757 hasspace = 0; 758 while (bufp < bufi && isspace(buf[bufp])) { 759 hasspace = 1; 760 bufp++; 761 } 762 if (buf[bufp] == '#' || bufp == bufi) { 763 // skip comments and empty lines. 764 } else if (hasspace) { 765 if (dstpkg[0] == 0) { 766 LOGW("Path before package line in %s%s: %s\n", 767 UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp); 768 } else if (srcpkg[0] == 0) { 769 // Skip -- source package no longer exists. 770 } else { 771 LOGV("Move file: %s (from %s to %s)\n", buf+bufp, srcpkg, dstpkg); 772 if (!create_move_path(srcpath, PKG_DIR_PREFIX, srcpkg, buf+bufp) && 773 !create_move_path(dstpath, PKG_DIR_PREFIX, dstpkg, buf+bufp)) { 774 movefileordir(srcpath, dstpath, 775 strlen(dstpath)-strlen(buf+bufp), 776 dstuid, dstgid, &s); 777 } 778 } 779 } else { 780 char* div = strchr(buf+bufp, ':'); 781 if (div == NULL) { 782 LOGW("Bad package spec in %s%s; no ':' sep: %s\n", 783 UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp); 784 } else { 785 *div = 0; 786 div++; 787 if (strlen(buf+bufp) < PKG_NAME_MAX) { 788 strcpy(dstpkg, buf+bufp); 789 } else { 790 srcpkg[0] = dstpkg[0] = 0; 791 LOGW("Package name too long in %s%s: %s\n", 792 UPDATE_COMMANDS_DIR_PREFIX, name, buf+bufp); 793 } 794 if (strlen(div) < PKG_NAME_MAX) { 795 strcpy(srcpkg, div); 796 } else { 797 srcpkg[0] = dstpkg[0] = 0; 798 LOGW("Package name too long in %s%s: %s\n", 799 UPDATE_COMMANDS_DIR_PREFIX, name, div); 800 } 801 if (srcpkg[0] != 0) { 802 if (!create_pkg_path(srcpath, PKG_DIR_PREFIX, srcpkg, 803 PKG_DIR_POSTFIX)) { 804 if (lstat(srcpath, &s) < 0) { 805 // Package no longer exists -- skip. 806 srcpkg[0] = 0; 807 } 808 } else { 809 srcpkg[0] = 0; 810 LOGW("Can't create path %s in %s%s\n", 811 div, UPDATE_COMMANDS_DIR_PREFIX, name); 812 } 813 if (srcpkg[0] != 0) { 814 if (!create_pkg_path(dstpath, PKG_DIR_PREFIX, dstpkg, 815 PKG_DIR_POSTFIX)) { 816 if (lstat(dstpath, &s) == 0) { 817 dstuid = s.st_uid; 818 dstgid = s.st_gid; 819 } else { 820 // Destination package doesn't 821 // exist... due to original-package, 822 // this is normal, so don't be 823 // noisy about it. 824 srcpkg[0] = 0; 825 } 826 } else { 827 srcpkg[0] = 0; 828 LOGW("Can't create path %s in %s%s\n", 829 div, UPDATE_COMMANDS_DIR_PREFIX, name); 830 } 831 } 832 LOGV("Transfering from %s to %s: uid=%d\n", 833 srcpkg, dstpkg, dstuid); 834 } 835 } 836 } 837 bufp = bufi+1; 838 } else { 839 if (bufp == 0) { 840 if (bufp < bufe) { 841 LOGW("Line too long in %s%s, skipping: %s\n", 842 UPDATE_COMMANDS_DIR_PREFIX, name, buf); 843 } 844 } else if (bufp < bufe) { 845 memcpy(buf, buf+bufp, bufe-bufp); 846 bufe -= bufp; 847 bufp = 0; 848 } 849 readlen = read(subfd, buf+bufe, PKG_PATH_MAX-bufe); 850 if (readlen < 0) { 851 LOGW("Failure reading update commands in %s%s: %s\n", 852 UPDATE_COMMANDS_DIR_PREFIX, name, strerror(errno)); 853 break; 854 } else if (readlen == 0) { 855 break; 856 } 857 bufe += readlen; 858 buf[bufe] = 0; 859 LOGV("Read buf: %s\n", buf); 860 } 861 } 862 close(subfd); 863 } 864 } 865 closedir(d); 866 done: 867 return 0; 868 } 869