aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'updater/install.c')
-rw-r--r--updater/install.c275
1 files changed, 272 insertions, 3 deletions
diff --git a/updater/install.c b/updater/install.c
index 2336f614..2e965cee 100644
--- a/updater/install.c
+++ b/updater/install.c
@@ -24,6 +24,8 @@
24#include <sys/types.h> 24#include <sys/types.h>
25#include <unistd.h> 25#include <unistd.h>
26 26
27#include "cutils/misc.h"
28#include "cutils/properties.h"
27#include "edify/expr.h" 29#include "edify/expr.h"
28#include "minzip/DirUtil.h" 30#include "minzip/DirUtil.h"
29#include "mtdutils/mounts.h" 31#include "mtdutils/mounts.h"
@@ -40,6 +42,7 @@ char* ErrorAbort(void* cookie, char* format, ...) {
40 return NULL; 42 return NULL;
41} 43}
42 44
45
43// mount(type, location, mount_point) 46// mount(type, location, mount_point)
44// 47//
45// what: type="MTD" location="<partition>" to mount a yaffs2 filesystem 48// what: type="MTD" location="<partition>" to mount a yaffs2 filesystem
@@ -104,6 +107,36 @@ done:
104 return result; 107 return result;
105} 108}
106 109
110
111// is_mounted(mount_point)
112char* IsMountedFn(const char* name, void* cookie, int argc, Expr* argv[]) {
113 char* result = NULL;
114 if (argc != 1) {
115 return ErrorAbort(cookie, "%s() expects 1 arg, got %d", name, argc);
116 }
117 char* mount_point;
118 if (ReadArgs(cookie, argv, 1, &mount_point) < 0) {
119 return NULL;
120 }
121 if (strlen(mount_point) == 0) {
122 ErrorAbort(cookie, "mount_point argument to unmount() can't be empty");
123 goto done;
124 }
125
126 scan_mounted_volumes();
127 const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point);
128 if (vol == NULL) {
129 result = strdup("");
130 } else {
131 result = mount_point;
132 }
133
134done:
135 if (result != mount_point) free(mount_point);
136 return result;
137}
138
139
107char* UnmountFn(const char* name, void* cookie, int argc, Expr* argv[]) { 140char* UnmountFn(const char* name, void* cookie, int argc, Expr* argv[]) {
108 char* result = NULL; 141 char* result = NULL;
109 if (argc != 1) { 142 if (argc != 1) {
@@ -132,6 +165,8 @@ done:
132 if (result != mount_point) free(mount_point); 165 if (result != mount_point) free(mount_point);
133 return result; 166 return result;
134} 167}
168
169
135// format(type, location) 170// format(type, location)
136// 171//
137// type="MTD" location=partition 172// type="MTD" location=partition
@@ -192,6 +227,7 @@ done:
192 return result; 227 return result;
193} 228}
194 229
230
195char* DeleteFn(const char* name, void* cookie, int argc, Expr* argv[]) { 231char* DeleteFn(const char* name, void* cookie, int argc, Expr* argv[]) {
196 char** paths = malloc(argc * sizeof(char*)); 232 char** paths = malloc(argc * sizeof(char*));
197 int i; 233 int i;
@@ -222,6 +258,7 @@ char* DeleteFn(const char* name, void* cookie, int argc, Expr* argv[]) {
222 return strdup(buffer); 258 return strdup(buffer);
223} 259}
224 260
261
225char* ShowProgressFn(const char* name, void* cookie, int argc, Expr* argv[]) { 262char* ShowProgressFn(const char* name, void* cookie, int argc, Expr* argv[]) {
226 if (argc != 2) { 263 if (argc != 2) {
227 return ErrorAbort(cookie, "%s() expects 2 args, got %d", name, argc); 264 return ErrorAbort(cookie, "%s() expects 2 args, got %d", name, argc);
@@ -243,8 +280,9 @@ char* ShowProgressFn(const char* name, void* cookie, int argc, Expr* argv[]) {
243 return strdup(""); 280 return strdup("");
244} 281}
245 282
246// package_extract package_path destination_path 283// package_extract_dir(package_path, destination_path)
247char* PackageExtractFn(const char* name, void* cookie, int argc, Expr* argv[]) { 284char* PackageExtractDirFn(const char* name, void* cookie,
285 int argc, Expr* argv[]) {
248 if (argc != 2) { 286 if (argc != 2) {
249 return ErrorAbort(cookie, "%s() expects 2 args, got %d", name, argc); 287 return ErrorAbort(cookie, "%s() expects 2 args, got %d", name, argc);
250 } 288 }
@@ -265,6 +303,42 @@ char* PackageExtractFn(const char* name, void* cookie, int argc, Expr* argv[]) {
265 return strdup(success ? "t" : ""); 303 return strdup(success ? "t" : "");
266} 304}
267 305
306
307// package_extract_file(package_path, destination_path)
308char* PackageExtractFileFn(const char* name, void* cookie,
309 int argc, Expr* argv[]) {
310 if (argc != 2) {
311 return ErrorAbort(cookie, "%s() expects 2 args, got %d", name, argc);
312 }
313 char* zip_path;
314 char* dest_path;
315 if (ReadArgs(cookie, argv, 2, &zip_path, &dest_path) < 0) return NULL;
316
317 bool success = false;
318
319 ZipArchive* za = ((UpdaterInfo*)cookie)->package_zip;
320 const ZipEntry* entry = mzFindZipEntry(za, zip_path);
321 if (entry == NULL) {
322 fprintf(stderr, "%s: no %s in package\n", name, zip_path);
323 goto done;
324 }
325
326 FILE* f = fopen(dest_path, "wb");
327 if (f == NULL) {
328 fprintf(stderr, "%s: can't open %s for write: %s\n",
329 name, dest_path, strerror(errno));
330 goto done;
331 }
332 success = mzExtractZipEntryToFile(za, entry, fileno(f));
333 fclose(f);
334
335 done:
336 free(zip_path);
337 free(dest_path);
338 return strdup(success ? "t" : "");
339}
340
341
268// symlink target src1 src2 ... 342// symlink target src1 src2 ...
269char* SymlinkFn(const char* name, void* cookie, int argc, Expr* argv[]) { 343char* SymlinkFn(const char* name, void* cookie, int argc, Expr* argv[]) {
270 if (argc == 0) { 344 if (argc == 0) {
@@ -289,6 +363,7 @@ char* SymlinkFn(const char* name, void* cookie, int argc, Expr* argv[]) {
289 return strdup(""); 363 return strdup("");
290} 364}
291 365
366
292char* SetPermFn(const char* name, void* cookie, int argc, Expr* argv[]) { 367char* SetPermFn(const char* name, void* cookie, int argc, Expr* argv[]) {
293 char* result = NULL; 368 char* result = NULL;
294 bool recursive = (strcmp(name, "set_perm_recursive") == 0); 369 bool recursive = (strcmp(name, "set_perm_recursive") == 0);
@@ -356,15 +431,209 @@ done:
356 return result; 431 return result;
357} 432}
358 433
434
435char* GetPropFn(const char* name, void* cookie, int argc, Expr* argv[]) {
436 if (argc != 1) {
437 return ErrorAbort(cookie, "%s() expects 1 arg, got %d", name, argc);
438 }
439 char* key;
440 key = Evaluate(cookie, argv[0]);
441 if (key == NULL) return NULL;
442
443 char value[PROPERTY_VALUE_MAX];
444 property_get(key, value, "");
445 free(key);
446
447 return strdup(value);
448}
449
450
451static bool write_raw_image_cb(const unsigned char* data,
452 int data_len, void* ctx) {
453 int r = mtd_write_data((MtdWriteContext*)ctx, (const char *)data, data_len);
454 if (r == data_len) return true;
455 fprintf(stderr, "%s\n", strerror(errno));
456 return false;
457}
458
459// write_raw_image(file, partition)
460char* WriteRawImageFn(const char* name, void* cookie, int argc, Expr* argv[]) {
461 char* result = NULL;
462
463 char* partition;
464 char* filename;
465 if (ReadArgs(cookie, argv, 2, &filename, &partition) < 0) {
466 return NULL;
467 }
468
469 if (strlen(partition) == 0) {
470 ErrorAbort(cookie, "partition argument to %s can't be empty", name);
471 goto done;
472 }
473 if (strlen(filename) == 0) {
474 ErrorAbort(cookie, "file argument to %s can't be empty", name);
475 goto done;
476 }
477
478 mtd_scan_partitions();
479 const MtdPartition* mtd = mtd_find_partition_by_name(partition);
480 if (mtd == NULL) {
481 fprintf(stderr, "%s: no mtd partition named \"%s\"\n", name, partition);
482 result = strdup("");
483 goto done;
484 }
485
486 MtdWriteContext* ctx = mtd_write_partition(mtd);
487 if (ctx == NULL) {
488 fprintf(stderr, "%s: can't write mtd partition \"%s\"\n",
489 name, partition);
490 result = strdup("");
491 goto done;
492 }
493
494 bool success;
495
496 FILE* f = fopen(filename, "rb");
497 if (f == NULL) {
498 fprintf(stderr, "%s: can't open %s: %s\n",
499 name, filename, strerror(errno));
500 result = strdup("");
501 goto done;
502 }
503
504 success = true;
505 char* buffer = malloc(BUFSIZ);
506 int read;
507 while (success && (read = fread(buffer, 1, BUFSIZ, f)) > 0) {
508 int wrote = mtd_write_data(ctx, buffer, read);
509 success = success && (wrote == read);
510 if (!success) {
511 fprintf(stderr, "mtd_write_data to %s failed: %s\n",
512 partition, strerror(errno));
513 }
514 }
515 free(buffer);
516 fclose(f);
517
518 printf("%s %s partition from %s\n",
519 success ? "wrote" : "failed to write", partition, filename);
520
521 result = success ? partition : strdup("");
522
523done:
524 if (result != partition) free(partition);
525 free(filename);
526 return result;
527}
528
529// write_firmware_image(file, partition)
530//
531// partition is "radio" or "hboot"
532// file is not used until after updater exits
533//
534// TODO: this should live in some HTC-specific library
535char* WriteFirmwareImageFn(const char* name, void* cookie,
536 int argc, Expr* argv[]) {
537 char* result = NULL;
538
539 char* partition;
540 char* filename;
541 if (ReadArgs(cookie, argv, 2, &filename, &partition) < 0) {
542 return NULL;
543 }
544
545 if (strlen(partition) == 0) {
546 ErrorAbort(cookie, "partition argument to %s can't be empty", name);
547 goto done;
548 }
549 if (strlen(filename) == 0) {
550 ErrorAbort(cookie, "file argument to %s can't be empty", name);
551 goto done;
552 }
553
554 FILE* cmd = ((UpdaterInfo*)cookie)->cmd_pipe;
555 fprintf(cmd, "firmware %s %s\n", partition, filename);
556
557 printf("will write %s firmware from %s\n", partition, filename);
558 result = partition;
559
560done:
561 if (result != partition) free(partition);
562 free(filename);
563 return result;
564}
565
566
567extern int applypatch(int argc, char** argv);
568
569// apply_patch(srcfile, tgtfile, tgtsha1, tgtsize, sha1:patch, ...)
570// apply_patch_check(file, sha1, ...)
571// apply_patch_space(bytes)
572char* ApplyPatchFn(const char* name, void* cookie, int argc, Expr* argv[]) {
573 printf("in applypatchfn (%s)\n", name);
574
575 char* prepend = NULL;
576 if (strstr(name, "check") != NULL) {
577 prepend = "-c";
578 } else if (strstr(name, "space") != NULL) {
579 prepend = "-s";
580 }
581
582 char** args = ReadVarArgs(cookie, argc, argv);
583 if (args == NULL) return NULL;
584
585 // insert the "program name" argv[0] and a copy of the "prepend"
586 // string (if any) at the start of the args.
587
588 int extra = 1 + (prepend != NULL ? 1 : 0);
589 char** temp = malloc((argc+extra) * sizeof(char*));
590 memcpy(temp+extra, args, argc * sizeof(char*));
591 temp[0] = strdup("updater");
592 if (prepend) {
593 temp[1] = strdup(prepend);
594 }
595 free(args);
596 args = temp;
597 argc += extra;
598
599 printf("calling applypatch\n");
600 fflush(stdout);
601 int result = applypatch(argc, args);
602 printf("applypatch returned %d\n", result);
603
604 int i;
605 for (i = 0; i < argc; ++i) {
606 free(args[i]);
607 }
608 free(args);
609
610 switch (result) {
611 case 0: return strdup("t");
612 case 1: return strdup("");
613 default: return ErrorAbort(cookie, "applypatch couldn't parse args");
614 }
615}
616
617
359void RegisterInstallFunctions() { 618void RegisterInstallFunctions() {
360 RegisterFunction("mount", MountFn); 619 RegisterFunction("mount", MountFn);
620 RegisterFunction("is_mounted", IsMountedFn);
361 RegisterFunction("unmount", UnmountFn); 621 RegisterFunction("unmount", UnmountFn);
362 RegisterFunction("format", FormatFn); 622 RegisterFunction("format", FormatFn);
363 RegisterFunction("show_progress", ShowProgressFn); 623 RegisterFunction("show_progress", ShowProgressFn);
364 RegisterFunction("delete", DeleteFn); 624 RegisterFunction("delete", DeleteFn);
365 RegisterFunction("delete_recursive", DeleteFn); 625 RegisterFunction("delete_recursive", DeleteFn);
366 RegisterFunction("package_extract", PackageExtractFn); 626 RegisterFunction("package_extract_dir", PackageExtractDirFn);
627 RegisterFunction("package_extract_file", PackageExtractFileFn);
367 RegisterFunction("symlink", SymlinkFn); 628 RegisterFunction("symlink", SymlinkFn);
368 RegisterFunction("set_perm", SetPermFn); 629 RegisterFunction("set_perm", SetPermFn);
369 RegisterFunction("set_perm_recursive", SetPermFn); 630 RegisterFunction("set_perm_recursive", SetPermFn);
631
632 RegisterFunction("getprop", GetPropFn);
633 RegisterFunction("write_raw_image", WriteRawImageFn);
634 RegisterFunction("write_firmware_image", WriteFirmwareImageFn);
635
636 RegisterFunction("apply_patch", ApplyPatchFn);
637 RegisterFunction("apply_patch_check", ApplyPatchFn);
638 RegisterFunction("apply_patch_space", ApplyPatchFn);
370} 639}