aboutsummaryrefslogtreecommitdiffstats
path: root/updater/install.c
diff options
context:
space:
mode:
authorDoug Zongker <dougz@google.com>2012-08-06 16:19:09 -0700
committerDoug Zongker <dougz@google.com>2012-08-06 16:35:18 -0700
commita23075fb0e23978e5b8f3a7c92280ee1b2274e6d (patch)
treee9eef9c5eafbfcd6f45a97baea2a260c03f0ec5b /updater/install.c
parent64c5a59be97ce8c6d05fb16a9c9f49ba520a35b3 (diff)
downloadbootable_recovery-a23075fb0e23978e5b8f3a7c92280ee1b2274e6d.zip
bootable_recovery-a23075fb0e23978e5b8f3a7c92280ee1b2274e6d.tar.gz
bootable_recovery-a23075fb0e23978e5b8f3a7c92280ee1b2274e6d.tar.bz2
fix the symlink() command to create directories if needed
Full OTAs currently fail if the build contains a directory containing only symlinks, because nothing creates that directory. Change the symlink() command to create any ancestor directories that don't exist. They're created as owner root perms 0700 because we assume that in practice subsequent set_perm_recursive() calls will fix up their ownership and permissions. Change-Id: I4681cbc85863d9778e36b924f0532b2b3ef14310
Diffstat (limited to 'updater/install.c')
-rw-r--r--updater/install.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/updater/install.c b/updater/install.c
index f981017..ba27e9f 100644
--- a/updater/install.c
+++ b/updater/install.c
@@ -456,6 +456,26 @@ Value* PackageExtractFileFn(const char* name, State* state,
}
}
+// Create all parent directories of name, if necessary.
+static int make_parents(char* name) {
+ char* p;
+ for (p = name + (strlen(name)-1); p > name; --p) {
+ if (*p != '/') continue;
+ *p = '\0';
+ if (make_parents(name) < 0) return -1;
+ int result = mkdir(name, 0700);
+ if (result == 0) fprintf(stderr, "symlink(): created [%s]\n", name);
+ *p = '/';
+ if (result == 0 || errno == EEXIST) {
+ // successfully created or already existed; we're done
+ return 0;
+ } else {
+ fprintf(stderr, "failed to mkdir %s: %s\n", name, strerror(errno));
+ return -1;
+ }
+ }
+ return 0;
+}
// symlink target src1 src2 ...
// unlinks any previously existing src1, src2, etc before creating symlinks.
@@ -483,6 +503,11 @@ Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) {
++bad;
}
}
+ if (make_parents(srcs[i])) {
+ fprintf(stderr, "%s: failed to symlink %s to %s: making parents failed\n",
+ name, srcs[i], target);
+ ++bad;
+ }
if (symlink(target, srcs[i]) < 0) {
fprintf(stderr, "%s: failed to symlink %s to %s: %s\n",
name, srcs[i], target, strerror(errno));
@@ -504,7 +529,8 @@ Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
int min_args = 4 + (recursive ? 1 : 0);
if (argc < min_args) {
- return ErrorAbort(state, "%s() expects %d+ args, got %d", name, argc);
+ return ErrorAbort(state, "%s() expects %d+ args, got %d",
+ name, min_args, argc);
}
char** args = ReadVarArgs(state, argc, argv);
@@ -626,7 +652,7 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) {
buffer = malloc(st.st_size+1);
if (buffer == NULL) {
- ErrorAbort(state, "%s: failed to alloc %d bytes", name, st.st_size+1);
+ ErrorAbort(state, "%s: failed to alloc %lld bytes", name, st.st_size+1);
goto done;
}
@@ -638,7 +664,7 @@ Value* FileGetPropFn(const char* name, State* state, int argc, Expr* argv[]) {
}
if (fread(buffer, 1, st.st_size, f) != st.st_size) {
- ErrorAbort(state, "%s: failed to read %d bytes from %s",
+ ErrorAbort(state, "%s: failed to read %lld bytes from %s",
name, st.st_size+1, filename);
fclose(f);
goto done;