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