Exemplo n.º 1
0
Value* UIPrintFn(const char* name, State* state, int argc, Expr* argv[]) {
    char** args = ReadVarArgs(state, argc, argv);
    if (args == NULL) {
        return NULL;
    }

    int size = 0;
    int i;
    for (i = 0; i < argc; ++i) {
        size += strlen(args[i]);
    }
    char* buffer = malloc(size+1);
    size = 0;
    for (i = 0; i < argc; ++i) {
        strcpy(buffer+size, args[i]);
        size += strlen(args[i]);
        free(args[i]);
    }
    free(args);
    buffer[size] = '\0';

    char* line = strtok(buffer, "\n");
    while (line) {
        fprintf(((UpdaterInfo*)(state->cookie))->cmd_pipe,
                "ui_print %s\n", line);
        line = strtok(NULL, "\n");
    }
    fprintf(((UpdaterInfo*)(state->cookie))->cmd_pipe, "ui_print\n");

    return StringValue(buffer);
}
Exemplo n.º 2
0
// 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(""));
}
Exemplo n.º 3
0
// 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 *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;
}
/* 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"));
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
Value* RunProgramFn(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;

    fprintf(stderr, "about to run program [%s] with %d args\n", args2[0], argc);

    pid_t child = fork();
    if (child == 0) {
        execv(args2[0], args2);
        fprintf(stderr, "run_program: execv failed: %s\n", strerror(errno));
        _exit(1);
    }
    int status;
    waitpid(child, &status, 0);
    if (WIFEXITED(status)) {
        if (WEXITSTATUS(status) != 0) {
            fprintf(stderr, "run_program: child exited with status %d\n",
                    WEXITSTATUS(status));
        }
    } else if (WIFSIGNALED(status)) {
        fprintf(stderr, "run_program: child terminated by signal %d\n",
                WTERMSIG(status));
    }

    int i;
    for (i = 0; i < argc; ++i) {
        free(args[i]);
    }
    free(args);
    free(args2);

    char buffer[20];
    sprintf(buffer, "%d", status);

    return StringValue(strdup(buffer));
}
Exemplo n.º 8
0
// undo_retouch_binaries(lib1, lib2, ...)
Value* UndoRetouchBinariesFn(const char* name, State* state,
                             int argc, Expr* argv[]) {
    UpdaterInfo* ui = (UpdaterInfo*)(state->cookie);

    char **retouch_entries  = ReadVarArgs(state, argc, argv);
    if (retouch_entries == NULL) {
        return StringValue(strdup("t"));
    }

    int i = 0;
    bool success = true;
    int32_t override_base;
    while (i < (argc-1)) {
        success = success && retouch_one_library(retouch_entries[i],
                                                 retouch_entries[i+1],
                                                 0 /* undo => offset==0 */,
                                                 NULL);
        if (!success)
            ErrorAbort(state, "Failed to unretouch '%s'.",
                       retouch_entries[i]);

        free(retouch_entries[i]);
        free(retouch_entries[i+1]);
        i += 2;
    }
    if (i < argc) {
        free(retouch_entries[i]);
        success = false;
    }
    free(retouch_entries);

    if (!success) {
      Value* v = malloc(sizeof(Value));
      v->type = VAL_STRING;
      v->data = NULL;
      v->size = -1;
      return v;
    }
    return StringValue(strdup("t"));
}
Exemplo n.º 9
0
// apply_patch_check(file, [sha1_1, ...])
Value* ApplyPatchCheckFn(const char* name, State* state,
                         int argc, Expr* argv[]) {
    int result = 0;
    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;
    }

    /*
     * Some of the symbolic links to shared libraries are created at runtime
     * based on hw being used as these are created at runtime sha1 would be
     * different compared to the one generated by updater-script. As we anyway
     * update the actual file the sym link points to, we can skip ahead sym links.
     */
    if (!CheckSymLink(filename)) {
        result = 0;
        goto ret;
    }

    int patchcount = argc-1;
    char** sha1s = ReadVarArgs(state, argc-1, argv+1);

    result = applypatch_check(filename, patchcount, sha1s);

    int i;
    for (i = 0; i < patchcount; ++i) {
        free(sha1s[i]);
    }
    free(sha1s);

ret:
    return StringValue(strdup(result == 0 ? "t" : ""));
}
Exemplo n.º 10
0
Value* SetPermFn(const char* name, State* state, int argc, Expr* argv[]) {
    char* result = NULL;
    bool recursive = (strcmp(name, "set_perm_recursive") == 0);

    int min_args = 4 + (recursive ? 1 : 0);
    if (argc < min_args) {
        return ErrorAbort(state, "%s() expects %d+ args, got %d", name, argc);
    }

    char** args = ReadVarArgs(state, argc, argv);
    if (args == NULL) return NULL;

    char* end;
    int i;
    int bad = 0;

    int uid = strtoul(args[0], &end, 0);
    if (*end != '\0' || args[0][0] == 0) {
        ErrorAbort(state, "%s: \"%s\" not a valid uid", name, args[0]);
        goto done;
    }

    int gid = strtoul(args[1], &end, 0);
    if (*end != '\0' || args[1][0] == 0) {
        ErrorAbort(state, "%s: \"%s\" not a valid gid", name, args[1]);
        goto done;
    }

    if (recursive) {
        int dir_mode = strtoul(args[2], &end, 0);
        if (*end != '\0' || args[2][0] == 0) {
            ErrorAbort(state, "%s: \"%s\" not a valid dirmode", name, args[2]);
            goto done;
        }

        int file_mode = strtoul(args[3], &end, 0);
        if (*end != '\0' || args[3][0] == 0) {
            ErrorAbort(state, "%s: \"%s\" not a valid filemode",
                       name, args[3]);
            goto done;
        }

        for (i = 4; i < argc; ++i) {
            dirSetHierarchyPermissions(args[i], uid, gid, dir_mode, file_mode);
        }
    } else {
        int mode = strtoul(args[2], &end, 0);
        if (*end != '\0' || args[2][0] == 0) {
            ErrorAbort(state, "%s: \"%s\" not a valid mode", name, args[2]);
            goto done;
        }

        for (i = 3; i < argc; ++i) {
            if (chown(args[i], uid, gid) < 0) {
                fprintf(stderr, "%s: chown of %s to %d %d failed: %s\n",
                        name, args[i], uid, gid, strerror(errno));
                ++bad;
            }
            if (chmod(args[i], mode) < 0) {
                fprintf(stderr, "%s: chmod of %s to %o failed: %s\n",
                        name, args[i], mode, strerror(errno));
                ++bad;
            }
        }
    }
    result = strdup("");

done:
    for (i = 0; i < argc; ++i) {
        free(args[i]);
    }
    free(args);

    if (bad) {
        free(result);
        return ErrorAbort(state, "%s: some changes failed", name);
    }
    return StringValue(result);
}
Exemplo n.º 11
0
// retouch_binaries(lib1, lib2, ...)
Value* RetouchBinariesFn(const char* name, State* state,
                         int argc, Expr* argv[]) {
    UpdaterInfo* ui = (UpdaterInfo*)(state->cookie);

    char **retouch_entries  = ReadVarArgs(state, argc, argv);
    if (retouch_entries == NULL) {
        return StringValue(strdup("t"));
    }

    // some randomness from the clock
    int32_t override_base;
    bool override_set = false;
    int32_t random_base = time(NULL) % 1024;
    // some more randomness from /dev/random
    FILE *f_random = fopen("/dev/urandom", "rb");
    uint16_t random_bits = 0;
    if (f_random != NULL) {
        fread(&random_bits, 2, 1, f_random);
        random_bits = random_bits % 1024;
        fclose(f_random);
    }
    random_base = (random_base + random_bits) % 1024;
    fprintf(ui->cmd_pipe, "ui_print Random offset: 0x%x\n", random_base);
    fprintf(ui->cmd_pipe, "ui_print\n");

    // make sure we never randomize to zero; this let's us look at a file
    // and know for sure whether it has been processed; important in the
    // crash recovery process
    if (random_base == 0) random_base = 1;
    // make sure our randomization is page-aligned
    random_base *= -0x1000;
    override_base = random_base;

    int i = 0;
    bool success = true;
    while (i < (argc - 1)) {
        success = success && retouch_one_library(retouch_entries[i],
                                                 retouch_entries[i+1],
                                                 random_base,
                                                 override_set ?
                                                   NULL :
                                                   &override_base);
        if (!success)
            ErrorAbort(state, "Failed to retouch '%s'.", retouch_entries[i]);

        free(retouch_entries[i]);
        free(retouch_entries[i+1]);
        i += 2;

        if (success && override_base != 0) {
            random_base = override_base;
            override_set = true;
        }
    }
    if (i < argc) {
        free(retouch_entries[i]);
        success = false;
    }
    free(retouch_entries);

    if (!success) {
      Value* v = malloc(sizeof(Value));
      v->type = VAL_STRING;
      v->data = NULL;
      v->size = -1;
      return v;
    }
    return StringValue(strdup("t"));
}