/* compatible_with(<version>) * * Returns "true" if this version of the script parser and command * set supports the named version. */ static int fn_compatible_with(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { UNUSED(name); UNUSED(cookie); CHECK_FN(); NO_PERMS(permissions); if (argc != 1) { fprintf(stderr, "%s: wrong number of arguments (%d)\n", name, argc); return 1; } if (!strcmp(argv[0], "0.1") || !strcmp(argv[0], "0.2")) { *result = strdup("true"); } else { *result = strdup(""); } if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }
/* update_forced() * * Returns "true" if some system setting has determined that * the update should happen no matter what. */ static int fn_update_forced(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { UNUSED(name); UNUSED(cookie); CHECK_FN(); NO_PERMS(permissions); if (argc != 0) { fprintf(stderr, "%s: wrong number of arguments (%d)\n", name, argc); return 1; } //xxx check some global or property bool force = true; if (force) { *result = strdup("true"); } else { *result = strdup(""); } if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }
/* concat(<str>, <str1> [, <strN>...]) * Returns the concatenation of all strings. */ static int fn_concat(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { UNUSED(name); UNUSED(cookie); CHECK_FN(); NO_PERMS(permissions); size_t totalLen = 0; int i; for (i = 0; i < argc; i++) { totalLen += strlen(argv[i]); } char *s = (char *)malloc(totalLen + 1); if (s == NULL) { return -1; } s[totalLen] = '\0'; for (i = 0; i < argc; i++) { //TODO: keep track of the end to avoid walking the string each time strcat(s, argv[i]); } *result = s; if (resultLen != NULL) { *resultLen = strlen(s); } return 0; }
/* matches(<str>, <str1> [, <strN>...]) * If <str> matches (strcmp) any of <str1>...<strN>, returns <str>, * otherwise returns "". * * E.g., assert matches(hash_dir("/path"), "hash1", "hash2") */ static int fn_matches(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { UNUSED(name); UNUSED(cookie); CHECK_FN(); NO_PERMS(permissions); if (argc < 2) { fprintf(stderr, "%s: not enough arguments (%d < 2)\n", name, argc); return 1; } int i; for (i = 1; i < argc; i++) { if (strcmp(argv[0], argv[i]) == 0) { *result = strdup(argv[0]); if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; } } *result = strdup(""); if (resultLen != NULL) { *resultLen = 1; } return 0; }
/* file_contains(<filename>, <substring>) * Returns "true" if the file exists and contains the specified substring. */ static int fn_file_contains(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { UNUSED(cookie); CHECK_FN(); NO_PERMS(permissions); if (argc != 2) { LOGE("Command %s requires exactly two arguments\n", name); return 1; } char pathbuf[PATH_MAX]; const char *root_path = argv[0]; const char *path = translate_root_path(root_path, pathbuf, sizeof(pathbuf)); if (path == NULL) { LOGE("Command %s: bad path \"%s\"\n", name, root_path); return 1; } if (ensure_root_path_mounted(root_path)) { LOGE("Can't mount %s\n", root_path); return 1; } const char *needle = argv[1]; char *haystack = (char*) load_file(path, NULL); if (haystack == NULL) { LOGI("%s: Can't read \"%s\" (%s)\n", name, path, strerror(errno)); *result = ""; /* File not found is not an error. */ } else if (strstr(haystack, needle) == NULL) { LOGI("%s: Can't find \"%s\" in \"%s\"\n", name, needle, path); *result = strdup(""); free(haystack); } else { *result = strdup("true"); free(haystack); } if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }
/* assert <boolexpr> */ static int cmd_assert(const char *name, void *cookie, int argc, const char *argv[], PermissionRequestList *permissions) { UNUSED(name); UNUSED(cookie); CHECK_BOOL(); NO_PERMS(permissions); /* If our argument is false, return non-zero (failure) * If our argument is true, return zero (success) */ if (argc) { return 0; } else { return 1; } }
/* get_mark(<resource>) * * Returns the current mark associated with the provided resource. */ static int fn_get_mark(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { UNUSED(name); UNUSED(cookie); CHECK_FN(); NO_PERMS(permissions); if (argc != 1) { fprintf(stderr, "%s: wrong number of arguments (%d)\n", name, argc); return 1; } //xxx look up the value *result = strdup(""); if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }
/* getprop(<property>) * Returns the named Android system property value, or "" if not set. */ static int fn_getprop(const char *name, void *cookie, int argc, const char *argv[], char **result, size_t *resultLen, PermissionRequestList *permissions) { UNUSED(cookie); CHECK_FN(); NO_PERMS(permissions); if (argc != 1) { LOGE("Command %s requires exactly one argument\n", name); return 1; } char value[PROPERTY_VALUE_MAX]; property_get(argv[0], value, ""); *result = strdup(value); if (resultLen != NULL) { *resultLen = strlen(*result); } return 0; }