/* verify_trustzone("TZ_VERSION", "TZ_VERSION", ...) */ Value * VerifyTrustZoneFn(const char *name, State *state, int argc, Expr *argv[]) { char current_tz_version[TZ_VER_BUF_LEN]; int i, ret; ret = get_tz_version(current_tz_version, TZ_VER_BUF_LEN); if (ret) { return ErrorAbort(state, "%s() failed to read current TZ version: %d", name, ret); } char** tz_version = ReadVarArgs(state, argc, argv); if (tz_version == NULL) { return ErrorAbort(state, "%s() error parsing arguments", name); } ret = 0; for (i = 0; i < argc; i++) { uiPrintf(state, "Comparing TZ version %s to %s", tz_version[i], current_tz_version); if (strncmp(tz_version[i], current_tz_version, strlen(tz_version[i])) == 0) { ret = 1; break; } } for (i = 0; i < argc; i++) { free(tz_version[i]); } free(tz_version); return StringValue(strdup(ret ? "1" : "0")); }
Value* UpdateFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 1) { return ErrorAbort(state, "%s() expects 6 args, got %d", name, argc); } char* type = strrchr(name, '_'); if (type == NULL || *(type+1) == '\0') { return ErrorAbort(state, "%s() couldn't get type from function name", name); } ++type; Value* image; if (ReadValueArgs(state, argv, 1, &image) <0) { return NULL; } if (image->type != VAL_BLOB) { printf("image argument is not blob (is type %d)\n", image->type); goto done; } install_firmware_update(type, image->data, image->size, "/tmp/recovery.log"); printf("%s: install_firmware_update returned!\n", name); done: FreeValue(image); // install_firmware_update should reboot. If it returns, it failed. return StringValue(strdup("")); }
Value* WriteBootloaderFn(const char* name, State* state, int argc, Expr* argv[]) { int result = -1; Value* img; Value* xloader_loc; Value* sbl_loc; if (argc != 3) { return ErrorAbort(state, "%s() expects 3 args, got %d", name, argc); } if (ReadValueArgs(state, argv, 3, &img, &xloader_loc, &sbl_loc) < 0) { return NULL; } if(img->type != VAL_BLOB || xloader_loc->type != VAL_STRING || sbl_loc->type != VAL_STRING) { FreeValue(img); FreeValue(xloader_loc); FreeValue(sbl_loc); return ErrorAbort(state, "%s(): argument types are incorrect", name); } result = update_bootloader(img->data, img->size, xloader_loc->data, sbl_loc->data); FreeValue(img); FreeValue(xloader_loc); FreeValue(sbl_loc); return StringValue(strdup(result == 0 ? "t" : "")); }
// Read a local file and return its contents (the Value* returned // is actually a FileContents*). Value* ReadFileFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 1) { return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); } char* filename; if (ReadArgs(state, argv, 1, &filename) < 0) return NULL; Value* v = malloc(sizeof(Value)); v->type = VAL_BLOB; FileContents fc; if (LoadFileContents(filename, &fc, RETOUCH_DONT_MASK) != 0) { ErrorAbort(state, "%s() loading \"%s\" failed: %s", name, filename, strerror(errno)); free(filename); free(v); free(fc.data); return NULL; } v->size = fc.size; v->data = (char*)fc.data; free(filename); return v; }
Value *CommandFunction(int (*fun) (int, char **), const char *name, State * state, int argc, Expr * argv[]) { Value *ret = NULL; char *argv_str[argc + 1]; int i; char **argv_read = ReadVarArgs(state, argc, argv); if (argv_read == NULL) { ErrorAbort(state, "%s parameter parsing failed.", name); goto done; } argv_str[0] = (char *)name; for (i = 0; i < argc; i++) argv_str[i + 1] = argv_read[i]; if (fun(sizeof(argv_str) / sizeof(char *), argv_str) != EXIT_SUCCESS) { ErrorAbort(state, "%s failed.", name); goto done; } for (i = 0; i < argc; i++) free(argv_read[i]); free(argv_read); ret = StringValue(strdup("t")); done: return ret; }
Value* UnmountFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; if (argc != 1) { return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); } char* mount_point; if (ReadArgs(state, argv, 1, &mount_point) < 0) { return NULL; } if (strlen(mount_point) == 0) { ErrorAbort(state, "mount_point argument to unmount() can't be empty"); goto done; } scan_mounted_volumes(); const MountedVolume* vol = find_mounted_volume_by_mount_point(mount_point); if (vol == NULL) { fprintf(stderr, "unmount of %s failed; no such volume\n", mount_point); result = strdup(""); } else { unmount_mounted_volume(vol); result = mount_point; } done: if (result != mount_point) free(mount_point); return StringValue(result); }
Value *ExecuteOsipFunction(const char *name, State * state, int argc, Expr * argv[], int (*action) (char *)) { Value *ret = NULL; char *destination = NULL; if (ReadArgs(state, argv, 1, &destination) < 0) { return NULL; } if (destination == NULL || strlen(destination) == 0) { ErrorAbort(state, "destination argument to %s can't be empty", name); goto done; } if (action(destination) == -1) { ErrorAbort(state, "Error writing %s to OSIP", destination); goto done; } ret = StringValue(strdup("t")); done: if (destination) free(destination); return ret; }
char* UnloadWifiFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 0) return ErrorAbort(state, "%s() expects 0 arg, got %d", name, argc); if (wifi_unload_driver() != 0) { return ErrorAbort(state, "Unable to unload wifi-driver: %s", strerror(errno)); } return strdup("t"); }
// write_raw_image(file, partition) Value* WriteRawImageFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; char* partition; char* filename; if (ReadArgs(state, argv, 2, &filename, &partition) < 0) { return NULL; } if (strlen(partition) == 0) { ErrorAbort(state, "partition argument to %s can't be empty", name); goto done; } if (strlen(filename) == 0) { ErrorAbort(state, "file argument to %s can't be empty", name); goto done; } mtd_scan_partitions(); const MtdPartition* mtd = mtd_find_partition_by_name(partition); if (mtd == NULL) { fprintf(stderr, "%s: no mtd partition named \"%s\"\n", name, partition); result = strdup(""); goto done; } char mtddevname[32]=""; sprintf(mtddevname, "/dev/mtd/mtd%d", mtd_get_partition_index((MtdPartition*)mtd)); bool success; FILE* f = fopen(filename, "rb"); if (f == NULL) { fprintf(stderr, "%s: can't open %s: %s\n", name, filename, strerror(errno)); result = strdup(""); goto done; } success = !write_recovery(filename, partition); printf("%s %s partition from %s\n", success ? "wrote" : "failed to write", partition, filename); result = success ? partition : strdup(""); done: if (result != partition) free(partition); free(filename); return StringValue(result); }
Value* RangeSha1Fn(const char* name, State* state, int argc, Expr* argv[]) { Value* blockdev_filename; Value* ranges; const uint8_t* digest = NULL; if (ReadValueArgs(state, argv, 2, &blockdev_filename, &ranges) < 0) { return NULL; } if (blockdev_filename->type != VAL_STRING) { ErrorAbort(state, "blockdev_filename argument to %s must be string", name); goto done; } if (ranges->type != VAL_STRING) { ErrorAbort(state, "ranges argument to %s must be string", name); goto done; } int fd = open(blockdev_filename->data, O_RDWR); if (fd < 0) { ErrorAbort(state, "failed to open %s: %s", blockdev_filename->data, strerror(errno)); goto done; } RangeSet* rs = parse_range(ranges->data); uint8_t buffer[BLOCKSIZE]; SHA_CTX ctx; SHA_init(&ctx); int i, j; for (i = 0; i < rs->count; ++i) { check_lseek(fd, (off64_t)rs->pos[i*2] * BLOCKSIZE, SEEK_SET); for (j = rs->pos[i*2]; j < rs->pos[i*2+1]; ++j) { readblock(fd, buffer, BLOCKSIZE); SHA_update(&ctx, buffer, BLOCKSIZE); } } digest = SHA_final(&ctx); close(fd); done: FreeValue(blockdev_filename); FreeValue(ranges); if (digest == NULL) { return StringValue(strdup("")); } else { return StringValue(PrintSha1(digest)); } }
char* UnloadWifiFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 0) return ErrorAbort(state, "%s() expects 0 arg, got %d", name, argc); void *h = dlopen("/system/lib/libhardware_legacy.so",RTLD_LAZY); int (*wifi_unload_driver)() = dlsym(h,"wifi_unload_driver"); if (wifi_unload_driver) { if (wifi_unload_driver() != 0) { return ErrorAbort(state, "Unable to unload wifi-driver: %s", strerror(errno)); } return strdup("t"); } return ErrorAbort(state, "libhardware_legacy is not available."); }
Value* WipeCacheFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 0) { return ErrorAbort(state, "%s() expects no args, got %d", name, argc); } fprintf(((UpdaterInfo*)(state->cookie))->cmd_pipe, "wipe_cache\n"); return StringValue(strdup("t")); }
char* WriteFileFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 2) return ErrorAbort(state, "%s() expects 2 args, got %d", name, argc); char *filename; char *line; int retval; if (ReadArgs(state, argv, 2, &filename, &line) < 0) return NULL; FILE *fd; if (! (fd = fopen(filename, "w")) ) { fprintf(stderr, "Can't open %s for write \n", filename); free(filename); free(line); return strdup(""); } if (fwrite(line, strlen(line), 1, fd) == 1) { fclose(fd); free(filename); free(line); return strdup("t"); } else { fclose(fd); free(filename); free(line); return strdup(""); } }
char* ModuleLoadedFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 1) return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); char *module_name; int retval; if (ReadArgs(state, argv, 1, &module_name) < 0) return NULL; int module_found = -1; FILE *modules; char buffer[READ_BUF_SIZE]; char mname[READ_BUF_SIZE]; if (! (modules = fopen("/proc/modules", "r")) ) { fprintf(stderr, "Can't open /proc/modules for read \n"); return strdup(""); } while(fgets(buffer, sizeof(buffer), modules)) { /* process the line */ sscanf(buffer, "%s %*s", mname); if ((strstr(mname, module_name)) != NULL) { module_found = 0; } } fclose(modules); free(module_name); return (module_found == 0 ? strdup("t") : strdup("")); }
// package_extract_dir(package_path, destination_path) Value * PackageExtractDirFn (const char *name, State * state, int argc, Expr * argv[]) { if (argc != 2) { return ErrorAbort (state, "%s() expects 2 args, got %d", name, argc); } char *zip_path; char *dest_path; if (ReadArgs (state, argv, 2, &zip_path, &dest_path) < 0) return NULL; ZipArchive *za = ((UpdaterInfo *) (state->cookie))->package_zip; // To create a consistent system image, never use the clock for timestamps. struct utimbuf timestamp = { 1217592000, 1217592000 }; // 8/1/2008 default bool success = mzExtractRecursive (za, zip_path, dest_path, MZ_EXTRACT_FILES_ONLY, ×tamp, NULL, NULL); free (zip_path); free (dest_path); return StringValue (strdup (success ? "t" : "")); }
char* WhiteListMacsFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 1) return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); char *filename; int retval; int returncode = 0; if (ReadArgs(state, argv, 1, &filename) < 0) return NULL; if (file_exists(filename) == 0) { FILE *macs; char buffer[20]; char command[100]; if (! (macs = fopen(filename, "r")) ) { fprintf(stderr, "Can't open %s for read \n", filename); free(filename); return strdup(""); } while(fgets(buffer, sizeof(buffer), macs) && returncode == 0) { /* process the line */ sscanf(buffer, "%s", buffer); sprintf(command,"/data/data/za.co.csir.walkiemesh/bin/iptables -t nat -I PREROUTING -m mac --mac-source %s -j ACCEPT", buffer); //fprintf(stdout, "Enabling whitelist for: %s \n", command); returncode = system(command); } fclose(macs); } free(filename); return (returncode == 0 ? strdup("t") : strdup("")); }
// log("some message"); // log("t", "some message"); char* LogFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 1 && argc != 2) { return ErrorAbort(state, "%s() expects 1 or 2 args", name); } char *status; char *message; time_t time_now; time(&time_now); if (argc == 1) { if (ReadArgs(state, argv, 1, &message) < 0) return NULL; status = strdup("t"); } else { if (ReadArgs(state, argv, 2, &status, &message) < 0) return NULL; } if (strcmp(status,"t") == 0) { fprintf(((UpdaterInfo*)(state->cookie))->log_fd, "<div class=\"date\">%s</div><div class=\"action\">%s...</div><div class=\"output\"></div><div class=\"done\">done</div><hr>",asctime(localtime(&time_now)),message); } else { property_set("tether.status","failed"); fprintf(((UpdaterInfo*)(state->cookie))->log_fd, "<div class=\"date\">%s</div><div class=\"action\">%s...</div><div class=\"output\"></div><div class=\"failed\">failed</div><hr>",asctime(localtime(&time_now)),message); } return strdup(""); }
// symlink target src1 src2 ... // unlinks any previously existing src1, src2, etc before creating symlinks. Value* SymlinkFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc == 0) { return ErrorAbort(state, "%s() expects 1+ args, got %d", name, argc); } char* target; target = Evaluate(state, argv[0]); if (target == NULL) return NULL; char** srcs = ReadVarArgs(state, argc-1, argv+1); if (srcs == NULL) { free(target); return NULL; } int i; for (i = 0; i < argc-1; ++i) { if (unlink(srcs[i]) < 0) { if (errno != ENOENT) { fprintf(stderr, "%s: failed to remove %s: %s\n", name, srcs[i], strerror(errno)); } } if (symlink(target, srcs[i]) < 0) { fprintf(stderr, "%s: failed to symlink %s to %s: %s\n", name, srcs[i], target, strerror(errno)); } free(srcs[i]); } free(srcs); return StringValue(strdup("")); }
char* InsModuleFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 2) return ErrorAbort(state, "%s() expects 2 args, got %d", name, argc); char *module_name; char *options; if (ReadArgs(state, argv, 2, &module_name, &options) < 0) { return NULL; } ssize_t len; void *image; int rc; if (!options) options = ""; len = INT_MAX - 4095; errno = ENOMEM; image = read_file(module_name, &len); if (!image) return strdup(""); errno = 0; init_module(image, len, options); rc = errno; free(image); free(module_name); return (rc == 0 ? strdup("t") : strdup("")); }
Value * ShowProgressFn (const char *name, State * state, int argc, Expr * argv[]) { if (argc != 2) { return ErrorAbort (state, "%s() expects 2 args, got %d", name, argc); } char *frac_str; char *sec_str; if (ReadArgs (state, argv, 2, &frac_str, &sec_str) < 0) { return NULL; } double frac = strtod (frac_str, NULL); int sec = strtol (sec_str, NULL, 10); UpdaterInfo *ui = (UpdaterInfo *) (state->cookie); fprintf (ui->cmd_pipe, "progress %f %d\n", frac, sec); free (sec_str); return StringValue (frac_str); }
Value* DownloadModemFn(const char* name, State* state, int argc, Expr* argv[]) { char* modemImg; int result = -1; if (argc != 1) return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); if (ReadArgs(state, argv, 1, &modemImg) != 0) { return NULL; } printf("DownloadModemFn: %s\n", modemImg); result = DownloadFiles(modemImg); if (result < 0) { printf("Download failed!\n"); } else { printf("Download success!\n"); ResetModem(); sleep(6); } return StringValue(strdup(result >= 0 ? "t" : "")); }
// apply_patch_check(file, [sha1_1, ...]) Value* ApplyPatchCheckFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc < 1) { return ErrorAbort(state, "%s(): expected at least 1 arg, got %d", name, argc); } char* filename; if (ReadArgs(state, argv, 1, &filename) < 0) { return NULL; } int patchcount = argc-1; char** sha1s = ReadVarArgs(state, argc-1, argv+1); int result = applypatch_check(filename, patchcount, sha1s); int i; for (i = 0; i < patchcount; ++i) { free(sha1s[i]); } free(sha1s); return StringValue(strdup(result == 0 ? "t" : "")); }
Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) { char* result = NULL; if (argc != 1) { return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); } char *path; if (ReadArgs(state, argv, 1, &path) < 0) { return NULL; } ui_print("Formatting %s...\n", path); if (0 != format_volume(path)) { free(path); return StringValue(strdup("")); } if (strcmp(path, "/data") == 0 && has_datadata()) { ui_print("Formatting /datadata...\n", path); if (0 != format_volume("/datadata")) { free(path); return StringValue(strdup("")); } if (0 != format_volume(get_android_secure_path())) { free(path); return StringValue(strdup("")); } } done: return StringValue(strdup(path)); }
Value *FlashOSImage(const char *name, State * state, int argc, Expr * argv[]) { char* result = NULL; Value *funret = NULL; char *image_type; int ret; Value* partition_value; Value* contents; if (ReadValueArgs(state, argv, 2, &contents, &partition_value) < 0) { return NULL; } char* partition = NULL; if (partition_value->type != VAL_STRING) { ErrorAbort(state, "partition argument to %s must be string", name); goto exit; } partition = partition_value->data; if (strlen(partition) == 0) { ErrorAbort(state, "partition argument to %s can't be empty", name); goto exit; } if (contents->type == VAL_STRING && strlen((char*) contents->data) == 0) { ErrorAbort(state, "file argument to %s can't be empty", name); goto exit; } image_type = basename(partition); ret = flash_image(contents->data, contents->size, image_type); if (ret != 0) { ErrorAbort(state, "%s: Failed to flash image %s, %s.", name, image_type, strerror(errno)); goto free; } funret = StringValue(strdup("t")); free: free(image_type); exit: return funret; }
Value *ExtractImageFn(const char *name, State * state, int argc, Expr * argv[]) { Value *ret = NULL; char *filename = NULL; char *source = NULL; void *data = NULL; int size; if (ReadArgs(state, argv, 2, &filename, &source) < 0) { return NULL; } if (filename == NULL || strlen(filename) == 0) { ErrorAbort(state, "filename argument to %s can't be empty", name); goto done; } if (source == NULL || strlen(source) == 0) { ErrorAbort(state, "source argument to %s can't be empty", name); goto done; } if ((size = read_image(source, &data)) < 0) { ErrorAbort(state, "Couldn't read image %s", source); goto done; } if (file_write(filename, data, size) < 0) { ErrorAbort(state, "Couldn't write %s data to %s", source, filename); goto done; } ret = StringValue(strdup("t")); done: if (source) free(source); if (filename) free(filename); if (data) free(data); return ret; }
char* Evaluate(State* state, Expr* expr) { Value* v = expr->fn(expr->name, state, expr->argc, expr->argv); if (v == NULL) return NULL; if (v->type != VAL_STRING) { ErrorAbort(state, "expecting string, got value type %d", v->type); FreeValue(v); return NULL; } char* result = v->data; free(v); return result; }
char* RmModuleFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 1) return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); char *module_name; int retval; if (ReadArgs(state, argv, 1, &module_name) < 0) return NULL; retval = delete_module(module_name, O_NONBLOCK | O_EXCL); free(module_name); return (retval == 0? strdup("t") : strdup("")); }
char* KillProcessByPIDFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc != 1) return ErrorAbort(state, "%s() expects 1 arg, got %d", name, argc); char *pidfile; int retval; if (ReadArgs(state, argv, 1, &pidfile) < 0) return NULL; kill_processes_by_pidfile(2, pidfile); kill_processes_by_pidfile(9, pidfile); return strdup("t"); }
Value* RestoreFn(const char* name, State* state, int argc, Expr* argv[]) { if (argc < 1) { return ErrorAbort(state, "%s() expects at least 1 arg", name); } char** args = ReadVarArgs(state, argc, argv); if (args == NULL) { return NULL; } char** args2 = malloc(sizeof(char*) * (argc+1)); memcpy(args2, args, sizeof(char*) * argc); args2[argc] = NULL; char* path = strdup(args2[0]); int restoreboot = 1; int restoresystem = 1; int restoredata = 1; int restorecache = 1; int restoresdext = 1; int restorewebtop = 1; int i; for (i = 1; i < argc; i++) { if (args2[i] == NULL) continue; if (strcmp(args2[i], "noboot") == 0) restoreboot = 0; else if (strcmp(args2[i], "nosystem") == 0) restoresystem = 0; else if (strcmp(args2[i], "nodata") == 0) restoredata = 0; else if (strcmp(args2[i], "nocache") == 0) restorecache = 0; else if (strcmp(args2[i], "nosd-ext") == 0) restoresdext = 0; else if (strcmp(args2[i], "nowebtop") == 0) restorewebtop = 0; } for (i = 0; i < argc; ++i) { free(args[i]); } free(args); free(args2); if (0 != nandroid_restore(path, restoreboot, restoresystem, restoredata, restorecache, restoresdext, 0, restorewebtop, 0)) { free(path); return StringValue(strdup("")); } return StringValue(path); }
Value* SetRadioFn(const char* name, State* state, int argc, Expr* argv[]) { char *part_type; if (argc != 1) { return ErrorAbort(state, "%s() expects arg, got %d", name, argc); } char* type = strrchr(name, '_'); if (type == NULL || *(type+1) == '\0') { return ErrorAbort(state, "%s() couldn't get type from function name", name); } ++type; if (ReadArgs(state, argv, 1, &part_type) <0) { return NULL; } start_firmware_update(type,part_type); return StringValue(strdup("")); }