auto import from //depot/cupcake/@135843
diff --git a/Android.mk b/Android.mk
deleted file mode 100644
index 816d143..0000000
--- a/Android.mk
+++ /dev/null
@@ -1,60 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-commands_recovery_local_path := $(LOCAL_PATH)
-
-ifneq ($(TARGET_SIMULATOR),true)
-ifeq ($(TARGET_ARCH),arm)
-
-LOCAL_SRC_FILES := \
- recovery.c \
- bootloader.c \
- commands.c \
- firmware.c \
- install.c \
- roots.c \
- ui.c \
- verifier.c
-
-LOCAL_SRC_FILES += test_roots.c
-
-LOCAL_MODULE := recovery
-
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-
-# This binary is in the recovery ramdisk, which is otherwise a copy of root.
-# It gets copied there in config/Makefile. LOCAL_MODULE_TAGS suppresses
-# a (redundant) copy of the binary in /system/bin for user builds.
-# TODO: Build the ramdisk image in a more principled way.
-
-LOCAL_MODULE_TAGS := eng
-
-LOCAL_STATIC_LIBRARIES := libminzip libunz libamend libmtdutils libmincrypt
-LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libcutils
-LOCAL_STATIC_LIBRARIES += libstdc++ libc
-
-# Specify a C-includable file containing the OTA public keys.
-# This is built in config/Makefile.
-# *** THIS IS A TOTAL HACK; EXECUTABLES MUST NOT CHANGE BETWEEN DIFFERENT
-# PRODUCTS/BUILD TYPES. ***
-# TODO: make recovery read the keys from an external file.
-RECOVERY_INSTALL_OTA_KEYS_INC := \
- $(call intermediates-dir-for,PACKAGING,ota_keys_inc)/keys.inc
-# Let install.c say #include "keys.inc"
-LOCAL_C_INCLUDES += $(dir $(RECOVERY_INSTALL_OTA_KEYS_INC))
-
-include $(BUILD_EXECUTABLE)
-
-# Depend on the generated keys.inc containing the OTA public keys.
-$(intermediates)/install.o: $(RECOVERY_INSTALL_OTA_KEYS_INC)
-
-include $(commands_recovery_local_path)/minui/Android.mk
-
-endif # TARGET_ARCH == arm
-endif # !TARGET_SIMULATOR
-
-include $(commands_recovery_local_path)/amend/Android.mk
-include $(commands_recovery_local_path)/minzip/Android.mk
-include $(commands_recovery_local_path)/mtdutils/Android.mk
-include $(commands_recovery_local_path)/tools/Android.mk
-commands_recovery_local_path :=
diff --git a/amend/Android.mk b/amend/Android.mk
deleted file mode 100644
index ae2d44a..0000000
--- a/amend/Android.mk
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-
-LOCAL_PATH := $(call my-dir)
-
-amend_src_files := \
- amend.c \
- lexer.l \
- parser_y.y \
- ast.c \
- symtab.c \
- commands.c \
- permissions.c \
- execute.c
-
-amend_test_files := \
- test_symtab.c \
- test_commands.c \
- test_permissions.c
-
-# "-x c" forces the lex/yacc files to be compiled as c;
-# the build system otherwise forces them to be c++.
-amend_cflags := -Wall -x c
-
-#
-# Build the host-side command line tool
-#
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- $(amend_src_files) \
- $(amend_test_files) \
- register.c \
- main.c
-
-LOCAL_CFLAGS := $(amend_cflags) -g -O0
-LOCAL_MODULE := amend
-LOCAL_YACCFLAGS := -v
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#
-# Build the device-side library
-#
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(amend_src_files)
-LOCAL_SRC_FILES += $(amend_test_files)
-
-LOCAL_CFLAGS := $(amend_cflags)
-LOCAL_MODULE := libamend
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/amend/amend.c b/amend/amend.c
deleted file mode 100644
index 49cd64e..0000000
--- a/amend/amend.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include "amend.h"
-#include "lexer.h"
-
-extern const AmCommandList *gCommands;
-
-const AmCommandList *
-parseAmendScript(const char *buf, size_t bufLen)
-{
- setLexerInputBuffer(buf, bufLen);
- int ret = yyparse();
- if (ret != 0) {
- return NULL;
- }
- return gCommands;
-}
diff --git a/amend/amend.h b/amend/amend.h
deleted file mode 100644
index 416f974..0000000
--- a/amend/amend.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AMEND_H_
-#define AMEND_H_
-
-#include "ast.h"
-#include "execute.h"
-
-const AmCommandList *parseAmendScript(const char *buf, size_t bufLen);
-
-#endif // AMEND_H_
diff --git a/amend/ast.c b/amend/ast.c
deleted file mode 100644
index f53efdc..0000000
--- a/amend/ast.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include "ast.h"
-
-static const char gSpaces[] =
- " "
- " "
- " "
- " "
- " "
- " "
- " ";
-const int gSpacesMax = sizeof(gSpaces) - 1;
-
-static const char *
-pad(int level)
-{
- level *= 4;
- if (level > gSpacesMax) {
- level = gSpacesMax;
- }
- return gSpaces + gSpacesMax - level;
-}
-
-void dumpBooleanValue(int level, const AmBooleanValue *booleanValue);
-void dumpStringValue(int level, const AmStringValue *stringValue);
-
-void
-dumpBooleanExpression(int level, const AmBooleanExpression *booleanExpression)
-{
- const char *op;
- bool unary = false;
-
- switch (booleanExpression->op) {
- case AM_BOP_NOT:
- op = "NOT";
- unary = true;
- break;
- case AM_BOP_EQ:
- op = "EQ";
- break;
- case AM_BOP_NE:
- op = "NE";
- break;
- case AM_BOP_AND:
- op = "AND";
- break;
- case AM_BOP_OR:
- op = "OR";
- break;
- default:
- op = "??";
- break;
- }
-
- printf("%sBOOLEAN %s {\n", pad(level), op);
- dumpBooleanValue(level + 1, booleanExpression->arg1);
- if (!unary) {
- dumpBooleanValue(level + 1, booleanExpression->arg2);
- }
- printf("%s}\n", pad(level));
-}
-
-void
-dumpFunctionArguments(int level, const AmFunctionArguments *functionArguments)
-{
- int i;
- for (i = 0; i < functionArguments->argc; i++) {
- dumpStringValue(level, &functionArguments->argv[i]);
- }
-}
-
-void
-dumpFunctionCall(int level, const AmFunctionCall *functionCall)
-{
- printf("%sFUNCTION %s (\n", pad(level), functionCall->name);
- dumpFunctionArguments(level + 1, functionCall->args);
- printf("%s)\n", pad(level));
-}
-
-void
-dumpStringValue(int level, const AmStringValue *stringValue)
-{
- switch (stringValue->type) {
- case AM_SVAL_LITERAL:
- printf("%s\"%s\"\n", pad(level), stringValue->u.literal);
- break;
- case AM_SVAL_FUNCTION:
- dumpFunctionCall(level, stringValue->u.function);
- break;
- default:
- printf("%s<UNKNOWN SVAL TYPE %d>\n", pad(level), stringValue->type);
- break;
- }
-}
-
-void
-dumpStringComparisonExpression(int level,
- const AmStringComparisonExpression *stringComparisonExpression)
-{
- const char *op;
-
- switch (stringComparisonExpression->op) {
- case AM_SOP_LT:
- op = "LT";
- break;
- case AM_SOP_LE:
- op = "LE";
- break;
- case AM_SOP_GT:
- op = "GT";
- break;
- case AM_SOP_GE:
- op = "GE";
- break;
- case AM_SOP_EQ:
- op = "EQ";
- break;
- case AM_SOP_NE:
- op = "NE";
- break;
- default:
- op = "??";
- break;
- }
- printf("%sSTRING %s {\n", pad(level), op);
- dumpStringValue(level + 1, stringComparisonExpression->arg1);
- dumpStringValue(level + 1, stringComparisonExpression->arg2);
- printf("%s}\n", pad(level));
-}
-
-void
-dumpBooleanValue(int level, const AmBooleanValue *booleanValue)
-{
- switch (booleanValue->type) {
- case AM_BVAL_EXPRESSION:
- dumpBooleanExpression(level, &booleanValue->u.expression);
- break;
- case AM_BVAL_STRING_COMPARISON:
- dumpStringComparisonExpression(level,
- &booleanValue->u.stringComparison);
- break;
- default:
- printf("%s<UNKNOWN BVAL TYPE %d>\n", pad(1), booleanValue->type);
- break;
- }
-}
-
-void
-dumpWordList(const AmWordList *wordList)
-{
- int i;
- for (i = 0; i < wordList->argc; i++) {
- printf("%s\"%s\"\n", pad(1), wordList->argv[i]);
- }
-}
-
-void
-dumpCommandArguments(const AmCommandArguments *commandArguments)
-{
- if (commandArguments->booleanArgs) {
- dumpBooleanValue(1, commandArguments->u.b);
- } else {
- dumpWordList(commandArguments->u.w);
- }
-}
-
-void
-dumpCommand(const AmCommand *command)
-{
- printf("command \"%s\" {\n", command->name);
- dumpCommandArguments(command->args);
- printf("}\n");
-}
-
-void
-dumpCommandList(const AmCommandList *commandList)
-{
- int i;
- for (i = 0; i < commandList->commandCount; i++) {
- dumpCommand(commandList->commands[i]);
- }
-}
diff --git a/amend/ast.h b/amend/ast.h
deleted file mode 100644
index 7834a2b..0000000
--- a/amend/ast.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AMEND_AST_H_
-#define AMEND_AST_H_
-
-#include "commands.h"
-
-typedef struct AmStringValue AmStringValue;
-
-typedef struct {
- int argc;
- AmStringValue *argv;
-} AmFunctionArguments;
-
-/* An internal structure used only by the parser;
- * will not appear in the output AST.
-xxx try to move this into parser.h
- */
-typedef struct AmFunctionArgumentBuilder AmFunctionArgumentBuilder;
-struct AmFunctionArgumentBuilder {
- AmFunctionArgumentBuilder *next;
- AmStringValue *arg;
- int argCount;
-};
-
-typedef struct AmWordListBuilder AmWordListBuilder;
-struct AmWordListBuilder {
- AmWordListBuilder *next;
- const char *word;
- int wordCount;
-};
-
-typedef struct {
- const char *name;
- Function *fn;
- AmFunctionArguments *args;
-} AmFunctionCall;
-
-
-/* <string-value> ::=
- * <literal-string> |
- * <function-call>
- */
-struct AmStringValue {
- unsigned int line;
-
- enum {
- AM_SVAL_LITERAL,
- AM_SVAL_FUNCTION,
- } type;
- union {
- const char *literal;
-//xxx inline instead of using pointers
- AmFunctionCall *function;
- } u;
-};
-
-
-/* <string-comparison-expression> ::=
- * <string-value> <string-comparison-operator> <string-value>
- */
-typedef struct {
- unsigned int line;
-
- enum {
- AM_SOP_LT,
- AM_SOP_LE,
- AM_SOP_GT,
- AM_SOP_GE,
- AM_SOP_EQ,
- AM_SOP_NE,
- } op;
- AmStringValue *arg1;
- AmStringValue *arg2;
-} AmStringComparisonExpression;
-
-
-/* <boolean-expression> ::=
- * ! <boolean-value> |
- * <boolean-value> <binary-boolean-operator> <boolean-value>
- */
-typedef struct AmBooleanValue AmBooleanValue;
-typedef struct {
- unsigned int line;
-
- enum {
- AM_BOP_NOT,
-
- AM_BOP_EQ,
- AM_BOP_NE,
-
- AM_BOP_AND,
-
- AM_BOP_OR,
- } op;
- AmBooleanValue *arg1;
- AmBooleanValue *arg2;
-} AmBooleanExpression;
-
-
-/* <boolean-value> ::=
- * <boolean-expression> |
- * <string-comparison-expression>
- */
-struct AmBooleanValue {
- unsigned int line;
-
- enum {
- AM_BVAL_EXPRESSION,
- AM_BVAL_STRING_COMPARISON,
- } type;
- union {
- AmBooleanExpression expression;
- AmStringComparisonExpression stringComparison;
- } u;
-};
-
-
-typedef struct {
- unsigned int line;
-
- int argc;
- const char **argv;
-} AmWordList;
-
-
-typedef struct {
- bool booleanArgs;
- union {
- AmWordList *w;
- AmBooleanValue *b;
- } u;
-} AmCommandArguments;
-
-typedef struct {
- unsigned int line;
-
- const char *name;
- Command *cmd;
- AmCommandArguments *args;
-} AmCommand;
-
-typedef struct {
- AmCommand **commands;
- int commandCount;
- int arraySize;
-} AmCommandList;
-
-void dumpCommandList(const AmCommandList *commandList);
-
-#endif // AMEND_AST_H_
diff --git a/amend/commands.c b/amend/commands.c
deleted file mode 100644
index 75ff828..0000000
--- a/amend/commands.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "symtab.h"
-#include "commands.h"
-
-#if 1
-#define TRACE(...) printf(__VA_ARGS__)
-#else
-#define TRACE(...) /**/
-#endif
-
-typedef enum {
- CMD_TYPE_UNKNOWN = -1,
- CMD_TYPE_COMMAND = 0,
- CMD_TYPE_FUNCTION
-} CommandType;
-
-typedef struct {
- const char *name;
- void *cookie;
- CommandType type;
- CommandArgumentType argType;
- CommandHook hook;
-} CommandEntry;
-
-static struct {
- SymbolTable *symbolTable;
- bool commandStateInitialized;
-} gCommandState;
-
-int
-commandInit()
-{
- if (gCommandState.commandStateInitialized) {
- return -1;
- }
- gCommandState.symbolTable = createSymbolTable();
- if (gCommandState.symbolTable == NULL) {
- return -1;
- }
- gCommandState.commandStateInitialized = true;
- return 0;
-}
-
-void
-commandCleanup()
-{
- if (gCommandState.commandStateInitialized) {
- gCommandState.commandStateInitialized = false;
- deleteSymbolTable(gCommandState.symbolTable);
- gCommandState.symbolTable = NULL;
-//xxx need to free the entries and names in the symbol table
- }
-}
-
-static int
-registerCommandInternal(const char *name, CommandType type,
- CommandArgumentType argType, CommandHook hook, void *cookie)
-{
- CommandEntry *entry;
-
- if (!gCommandState.commandStateInitialized) {
- return -1;
- }
- if (name == NULL || hook == NULL) {
- return -1;
- }
- if (type != CMD_TYPE_COMMAND && type != CMD_TYPE_FUNCTION) {
- return -1;
- }
- if (argType != CMD_ARGS_BOOLEAN && argType != CMD_ARGS_WORDS) {
- return -1;
- }
-
- entry = (CommandEntry *)malloc(sizeof(CommandEntry));
- if (entry != NULL) {
- entry->name = strdup(name);
- if (entry->name != NULL) {
- int ret;
-
- entry->cookie = cookie;
- entry->type = type;
- entry->argType = argType;
- entry->hook = hook;
- ret = addToSymbolTable(gCommandState.symbolTable,
- entry->name, entry->type, entry);
- if (ret == 0) {
- return 0;
- }
- }
- free(entry);
- }
-
- return -1;
-}
-
-int
-registerCommand(const char *name,
- CommandArgumentType argType, CommandHook hook, void *cookie)
-{
- return registerCommandInternal(name,
- CMD_TYPE_COMMAND, argType, hook, cookie);
-}
-
-int
-registerFunction(const char *name, FunctionHook hook, void *cookie)
-{
- return registerCommandInternal(name,
- CMD_TYPE_FUNCTION, CMD_ARGS_WORDS, (CommandHook)hook, cookie);
-}
-
-Command *
-findCommand(const char *name)
-{
- return (Command *)findInSymbolTable(gCommandState.symbolTable,
- name, CMD_TYPE_COMMAND);
-}
-
-Function *
-findFunction(const char *name)
-{
- return (Function *)findInSymbolTable(gCommandState.symbolTable,
- name, CMD_TYPE_FUNCTION);
-}
-
-CommandArgumentType
-getCommandArgumentType(Command *cmd)
-{
- CommandEntry *entry = (CommandEntry *)cmd;
-
- if (entry != NULL) {
- return entry->argType;
- }
- return CMD_ARGS_UNKNOWN;
-}
-
-static int
-callCommandInternal(CommandEntry *entry, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- if (entry != NULL && entry->argType == CMD_ARGS_WORDS &&
- (argc == 0 || (argc > 0 && argv != NULL)))
- {
- if (permissions == NULL) {
- int i;
- for (i = 0; i < argc; i++) {
- if (argv[i] == NULL) {
- goto bail;
- }
- }
- }
- TRACE("calling command %s\n", entry->name);
- return entry->hook(entry->name, entry->cookie, argc, argv, permissions);
-//xxx if permissions, make sure the entry has added at least one element.
- }
-bail:
- return -1;
-}
-
-static int
-callBooleanCommandInternal(CommandEntry *entry, bool arg,
- PermissionRequestList *permissions)
-{
- if (entry != NULL && entry->argType == CMD_ARGS_BOOLEAN) {
- TRACE("calling boolean command %s\n", entry->name);
- return entry->hook(entry->name, entry->cookie, arg ? 1 : 0, NULL,
- permissions);
-//xxx if permissions, make sure the entry has added at least one element.
- }
- return -1;
-}
-
-int
-callCommand(Command *cmd, int argc, const char *argv[])
-{
- return callCommandInternal((CommandEntry *)cmd, argc, argv, NULL);
-}
-
-int
-callBooleanCommand(Command *cmd, bool arg)
-{
- return callBooleanCommandInternal((CommandEntry *)cmd, arg, NULL);
-}
-
-int
-getCommandPermissions(Command *cmd, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- if (permissions != NULL) {
- return callCommandInternal((CommandEntry *)cmd, argc, argv,
- permissions);
- }
- return -1;
-}
-
-int
-getBooleanCommandPermissions(Command *cmd, bool arg,
- PermissionRequestList *permissions)
-{
- if (permissions != NULL) {
- return callBooleanCommandInternal((CommandEntry *)cmd, arg,
- permissions);
- }
- return -1;
-}
-
-int
-callFunctionInternal(CommandEntry *entry, int argc, const char *argv[],
- char **result, size_t *resultLen, PermissionRequestList *permissions)
-{
- if (entry != NULL && entry->argType == CMD_ARGS_WORDS &&
- (argc == 0 || (argc > 0 && argv != NULL)))
- {
- if ((permissions == NULL && result != NULL) ||
- (permissions != NULL && result == NULL))
- {
- if (permissions == NULL) {
- /* This is the actual invocation of the function,
- * which means that none of the arguments are allowed
- * to be NULL.
- */
- int i;
- for (i = 0; i < argc; i++) {
- if (argv[i] == NULL) {
- goto bail;
- }
- }
- }
- TRACE("calling function %s\n", entry->name);
- return ((FunctionHook)entry->hook)(entry->name, entry->cookie,
- argc, argv, result, resultLen, permissions);
-//xxx if permissions, make sure the entry has added at least one element.
- }
- }
-bail:
- return -1;
-}
-
-int
-callFunction(Function *fn, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- return callFunctionInternal((CommandEntry *)fn, argc, argv,
- result, resultLen, NULL);
-}
-
-int
-getFunctionPermissions(Function *fn, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- if (permissions != NULL) {
- return callFunctionInternal((CommandEntry *)fn, argc, argv,
- NULL, NULL, permissions);
- }
- return -1;
-}
diff --git a/amend/commands.h b/amend/commands.h
deleted file mode 100644
index 38931c0..0000000
--- a/amend/commands.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AMEND_COMMANDS_H_
-#define AMEND_COMMANDS_H_
-
-#include "permissions.h"
-
-/* Invoke or dry-run a command. If "permissions" is non-NULL,
- * the hook should fill it out with the list of files and operations that
- * it would need to complete its operation. If "permissions" is NULL,
- * the hook should do the actual work specified by its arguments.
- *
- * When a command is called with non-NULL "permissions", some arguments
- * may be NULL. A NULL argument indicates that the argument is actually
- * the output of another function, so is not known at permissions time.
- * The permissions of leaf-node functions (those that have only literal
- * strings as arguments) will get appended to the permissions of the
- * functions that call them. However, to be completely safe, functions
- * that receive a NULL argument should request the broadest-possible
- * permissions for the range of the input argument.
- *
- * When a boolean command is called, "argc" is the boolean value and
- * "argv" is NULL.
- */
-typedef int (*CommandHook)(const char *name, void *cookie,
- int argc, const char *argv[],
- PermissionRequestList *permissions);
-
-int commandInit(void);
-void commandCleanup(void);
-
-/*
- * Command management
- */
-
-struct Command;
-typedef struct Command Command;
-
-typedef enum {
- CMD_ARGS_UNKNOWN = -1,
- CMD_ARGS_BOOLEAN = 0,
- CMD_ARGS_WORDS
-} CommandArgumentType;
-
-int registerCommand(const char *name,
- CommandArgumentType argType, CommandHook hook, void *cookie);
-
-Command *findCommand(const char *name);
-
-CommandArgumentType getCommandArgumentType(Command *cmd);
-
-int callCommand(Command *cmd, int argc, const char *argv[]);
-int callBooleanCommand(Command *cmd, bool arg);
-
-int getCommandPermissions(Command *cmd, int argc, const char *argv[],
- PermissionRequestList *permissions);
-int getBooleanCommandPermissions(Command *cmd, bool arg,
- PermissionRequestList *permissions);
-
-/*
- * Function management
- */
-
-typedef int (*FunctionHook)(const char *name, void *cookie,
- int argc, const char *argv[],
- char **result, size_t *resultLen,
- PermissionRequestList *permissions);
-
-struct Function;
-typedef struct Function Function;
-
-int registerFunction(const char *name, FunctionHook hook, void *cookie);
-
-Function *findFunction(const char *name);
-
-int callFunction(Function *fn, int argc, const char *argv[],
- char **result, size_t *resultLen);
-
-int getFunctionPermissions(Function *fn, int argc, const char *argv[],
- PermissionRequestList *permissions);
-
-#endif // AMEND_COMMANDS_H_
diff --git a/amend/execute.c b/amend/execute.c
deleted file mode 100644
index 9162ad6..0000000
--- a/amend/execute.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#undef NDEBUG
-#include <assert.h>
-#include "ast.h"
-#include "execute.h"
-
-typedef struct {
- int c;
- const char **v;
-} StringList;
-
-static int execBooleanValue(ExecContext *ctx,
- const AmBooleanValue *booleanValue, bool *result);
-static int execStringValue(ExecContext *ctx, const AmStringValue *stringValue,
- const char **result);
-
-static int
-execBooleanExpression(ExecContext *ctx,
- const AmBooleanExpression *booleanExpression, bool *result)
-{
- int ret;
- bool arg1, arg2;
- bool unary;
-
- assert(ctx != NULL);
- assert(booleanExpression != NULL);
- assert(result != NULL);
- if (ctx == NULL || booleanExpression == NULL || result == NULL) {
- return -__LINE__;
- }
-
- if (booleanExpression->op == AM_BOP_NOT) {
- unary = true;
- } else {
- unary = false;
- }
-
- ret = execBooleanValue(ctx, booleanExpression->arg1, &arg1);
- if (ret != 0) return ret;
-
- if (!unary) {
- ret = execBooleanValue(ctx, booleanExpression->arg2, &arg2);
- if (ret != 0) return ret;
- } else {
- arg2 = false;
- }
-
- switch (booleanExpression->op) {
- case AM_BOP_NOT:
- *result = !arg1;
- break;
- case AM_BOP_EQ:
- *result = (arg1 == arg2);
- break;
- case AM_BOP_NE:
- *result = (arg1 != arg2);
- break;
- case AM_BOP_AND:
- *result = (arg1 && arg2);
- break;
- case AM_BOP_OR:
- *result = (arg1 || arg2);
- break;
- default:
- return -__LINE__;
- }
-
- return 0;
-}
-
-static int
-execFunctionArguments(ExecContext *ctx,
- const AmFunctionArguments *functionArguments, StringList *result)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(functionArguments != NULL);
- assert(result != NULL);
- if (ctx == NULL || functionArguments == NULL || result == NULL) {
- return -__LINE__;
- }
-
- result->c = functionArguments->argc;
- result->v = (const char **)malloc(result->c * sizeof(const char *));
- if (result->v == NULL) {
- result->c = 0;
- return -__LINE__;
- }
-
- int i;
- for (i = 0; i < functionArguments->argc; i++) {
- ret = execStringValue(ctx, &functionArguments->argv[i], &result->v[i]);
- if (ret != 0) {
- result->c = 0;
- free(result->v);
- //TODO: free the individual args, if we're responsible for them.
- result->v = NULL;
- return ret;
- }
- }
-
- return 0;
-}
-
-static int
-execFunctionCall(ExecContext *ctx, const AmFunctionCall *functionCall,
- const char **result)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(functionCall != NULL);
- assert(result != NULL);
- if (ctx == NULL || functionCall == NULL || result == NULL) {
- return -__LINE__;
- }
-
- StringList args;
- ret = execFunctionArguments(ctx, functionCall->args, &args);
- if (ret != 0) {
- return ret;
- }
-
- ret = callFunction(functionCall->fn, args.c, args.v, (char **)result, NULL);
- if (ret != 0) {
- return ret;
- }
-
- //TODO: clean up args
-
- return 0;
-}
-
-static int
-execStringValue(ExecContext *ctx, const AmStringValue *stringValue,
- const char **result)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(stringValue != NULL);
- assert(result != NULL);
- if (ctx == NULL || stringValue == NULL || result == NULL) {
- return -__LINE__;
- }
-
- switch (stringValue->type) {
- case AM_SVAL_LITERAL:
- *result = strdup(stringValue->u.literal);
- break;
- case AM_SVAL_FUNCTION:
- ret = execFunctionCall(ctx, stringValue->u.function, result);
- if (ret != 0) {
- return ret;
- }
- break;
- default:
- return -__LINE__;
- }
-
- return 0;
-}
-
-static int
-execStringComparisonExpression(ExecContext *ctx,
- const AmStringComparisonExpression *stringComparisonExpression,
- bool *result)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(stringComparisonExpression != NULL);
- assert(result != NULL);
- if (ctx == NULL || stringComparisonExpression == NULL || result == NULL) {
- return -__LINE__;
- }
-
- const char *arg1, *arg2;
- ret = execStringValue(ctx, stringComparisonExpression->arg1, &arg1);
- if (ret != 0) {
- return ret;
- }
- ret = execStringValue(ctx, stringComparisonExpression->arg2, &arg2);
- if (ret != 0) {
- return ret;
- }
-
- int cmp = strcmp(arg1, arg2);
-
- switch (stringComparisonExpression->op) {
- case AM_SOP_LT:
- *result = (cmp < 0);
- break;
- case AM_SOP_LE:
- *result = (cmp <= 0);
- break;
- case AM_SOP_GT:
- *result = (cmp > 0);
- break;
- case AM_SOP_GE:
- *result = (cmp >= 0);
- break;
- case AM_SOP_EQ:
- *result = (cmp == 0);
- break;
- case AM_SOP_NE:
- *result = (cmp != 0);
- break;
- default:
- return -__LINE__;
- break;
- }
-
- return 0;
-}
-
-static int
-execBooleanValue(ExecContext *ctx, const AmBooleanValue *booleanValue,
- bool *result)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(booleanValue != NULL);
- assert(result != NULL);
- if (ctx == NULL || booleanValue == NULL || result == NULL) {
- return -__LINE__;
- }
-
- switch (booleanValue->type) {
- case AM_BVAL_EXPRESSION:
- ret = execBooleanExpression(ctx, &booleanValue->u.expression, result);
- break;
- case AM_BVAL_STRING_COMPARISON:
- ret = execStringComparisonExpression(ctx,
- &booleanValue->u.stringComparison, result);
- break;
- default:
- ret = -__LINE__;
- break;
- }
-
- return ret;
-}
-
-static int
-execCommand(ExecContext *ctx, const AmCommand *command)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(command != NULL);
- if (ctx == NULL || command == NULL) {
- return -__LINE__;
- }
-
- CommandArgumentType argType;
- argType = getCommandArgumentType(command->cmd);
- switch (argType) {
- case CMD_ARGS_BOOLEAN:
- {
- bool bVal;
- ret = execBooleanValue(ctx, command->args->u.b, &bVal);
- if (ret == 0) {
- ret = callBooleanCommand(command->cmd, bVal);
- }
- }
- break;
- case CMD_ARGS_WORDS:
- {
- AmWordList *words = command->args->u.w;
- ret = callCommand(command->cmd, words->argc, words->argv);
- }
- break;
- default:
- ret = -__LINE__;
- break;
- }
-
- return ret;
-}
-
-int
-execCommandList(ExecContext *ctx, const AmCommandList *commandList)
-{
- int i;
- for (i = 0; i < commandList->commandCount; i++) {
- int ret = execCommand(ctx, commandList->commands[i]);
- if (ret != 0) {
- int line = commandList->commands[i]->line;
- return line > 0 ? line : ret;
- }
- }
-
- return 0;
-}
diff --git a/amend/execute.h b/amend/execute.h
deleted file mode 100644
index 3becb48..0000000
--- a/amend/execute.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AMEND_EXECUTE_H_
-#define AMEND_EXECUTE_H_
-
-typedef struct ExecContext ExecContext;
-
-/* Returns 0 on success, otherwise the line number that failed. */
-int execCommandList(ExecContext *ctx, const AmCommandList *commandList);
-
-#endif // AMEND_EXECUTE_H_
diff --git a/amend/lexer.h b/amend/lexer.h
deleted file mode 100644
index fc716fd..0000000
--- a/amend/lexer.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AMEND_LEXER_H_
-#define AMEND_LEXER_H_
-
-#define AMEND_LEXER_BUFFER_INPUT 1
-
-void yyerror(const char *msg);
-int yylex(void);
-
-#if AMEND_LEXER_BUFFER_INPUT
-void setLexerInputBuffer(const char *buf, size_t buflen);
-#else
-#include <stdio.h>
-void yyset_in(FILE *in_str);
-#endif
-
-const char *tokenToString(int token);
-
-typedef enum {
- AM_UNKNOWN_ARGS,
- AM_WORD_ARGS,
- AM_BOOLEAN_ARGS,
-} AmArgumentType;
-
-void setLexerArgumentType(AmArgumentType type);
-int getLexerLineNumber(void);
-
-#endif // AMEND_LEXER_H_
diff --git a/amend/lexer.l b/amend/lexer.l
deleted file mode 100644
index 80896d1..0000000
--- a/amend/lexer.l
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-%{
- #include <stdio.h>
- #include <stdlib.h>
- #include "ast.h"
- #include "lexer.h"
- #include "parser.h"
-
- const char *tokenToString(int token)
- {
- static char scratch[128];
-
- switch (token) {
- case TOK_AND:
- return "&&";
- case TOK_OR:
- return "||";
- case TOK_EQ:
- return "==";
- case TOK_NE:
- return "!=";
- case TOK_GE:
- return ">=";
- case TOK_LE:
- return "<=";
- case TOK_EOF:
- return "EOF";
- case TOK_EOL:
- return "EOL\n";
- case TOK_STRING:
- snprintf(scratch, sizeof(scratch),
- "STRING<%s>", yylval.literalString);
- return scratch;
- case TOK_IDENTIFIER:
- snprintf(scratch, sizeof(scratch), "IDENTIFIER<%s>",
- yylval.literalString);
- return scratch;
- case TOK_WORD:
- snprintf(scratch, sizeof(scratch), "WORD<%s>",
- yylval.literalString);
- return scratch;
- default:
- if (token > ' ' && token <= '~') {
- scratch[0] = (char)token;
- scratch[1] = '\0';
- } else {
- snprintf(scratch, sizeof(scratch), "??? <%d>", token);
- }
- return scratch;
- }
- }
-
- typedef struct {
- char *value;
- char *nextc;
- unsigned int alloc_size;
- } AmString;
-
- static int addCharToString(AmString *str, char c)
- {
- if ((unsigned int)(str->nextc - str->value) >= str->alloc_size) {
- char *new_value;
- unsigned int new_size;
-
- new_size = (str->alloc_size + 1) * 2;
- if (new_size < 64) {
- new_size = 64;
- }
-
- new_value = (char *)realloc(str->value, new_size);
- if (new_value == NULL) {
- yyerror("out of memory");
- return -1;
- }
- str->nextc = str->nextc - str->value + new_value;
- str->value = new_value;
- str->alloc_size = new_size;
- }
- *str->nextc++ = c;
- return 0;
- }
-
- static int setString(AmString *str, const char *p)
- {
- str->nextc = str->value;
- while (*p != '\0') {
-//TODO: add the whole string at once
- addCharToString(str, *p++);
- }
- return addCharToString(str, '\0');
- }
-
- static AmString gStr = { NULL, NULL, 0 };
- static int gLineNumber = 1;
- static AmArgumentType gArgumentType = AM_UNKNOWN_ARGS;
- static const char *gErrorMessage = NULL;
-
-#if AMEND_LEXER_BUFFER_INPUT
- static const char *gInputBuffer;
- static const char *gInputBufferNext;
- static const char *gInputBufferEnd;
-
-# define YY_INPUT(buf, result, max_size) \
- do { \
- int nbytes = gInputBufferEnd - gInputBufferNext; \
- if (nbytes > 0) { \
- if (nbytes > max_size) { \
- nbytes = max_size; \
- } \
- memcpy(buf, gInputBufferNext, nbytes); \
- gInputBufferNext += nbytes; \
- result = nbytes; \
- } else { \
- result = YY_NULL; \
- } \
- } while (false)
-#endif // AMEND_LEXER_BUFFER_INPUT
-
-%}
-
-%option noyywrap
-
-%x QUOTED_STRING BOOLEAN WORDS
-
-ident [a-zA-Z_][a-zA-Z_0-9]*
-word [^ \t\r\n"]+
-
-%%
- /* This happens at the beginning of each call to yylex().
- */
- if (gArgumentType == AM_WORD_ARGS) {
- BEGIN(WORDS);
- } else if (gArgumentType == AM_BOOLEAN_ARGS) {
- BEGIN(BOOLEAN);
- }
-
- /*xxx require everything to be 7-bit-clean, printable characters */
-<INITIAL>{
- {ident}/[ \t\r\n] {
- /* The only token we recognize in the initial
- * state is an identifier followed by whitespace.
- */
- setString(&gStr, yytext);
- yylval.literalString = gStr.value;
- return TOK_IDENTIFIER;
- }
- }
-
-<BOOLEAN>{
- {ident} {
- /* Non-quoted identifier-style string */
- setString(&gStr, yytext);
- yylval.literalString = gStr.value;
- return TOK_IDENTIFIER;
- }
- "&&" return TOK_AND;
- "||" return TOK_OR;
- "==" return TOK_EQ;
- "!=" return TOK_NE;
- ">=" return TOK_GE;
- "<=" return TOK_LE;
- [<>()!,] return yytext[0];
- }
-
- /* Double-quoted string handling */
-
-<WORDS,BOOLEAN>\" {
- /* Initial quote */
- gStr.nextc = gStr.value;
- BEGIN(QUOTED_STRING);
- }
-
-<QUOTED_STRING>{
- \" {
- /* Closing quote */
- BEGIN(INITIAL);
- addCharToString(&gStr, '\0');
- yylval.literalString = gStr.value;
- if (gArgumentType == AM_WORD_ARGS) {
- return TOK_WORD;
- } else {
- return TOK_STRING;
- }
- }
-
- <<EOF>> |
- \n {
- /* Unterminated string */
- yyerror("unterminated string");
- return TOK_ERROR;
- }
-
- \\\" {
- /* Escaped quote */
- addCharToString(&gStr, '"');
- }
-
- \\\\ {
- /* Escaped backslash */
- addCharToString(&gStr, '\\');
- }
-
- \\. {
- /* No other escapes allowed. */
- gErrorMessage = "illegal escape";
- return TOK_ERROR;
- }
-
- [^\\\n\"]+ {
- /* String contents */
- char *p = yytext;
- while (*p != '\0') {
- /* TODO: add the whole string at once */
- addCharToString(&gStr, *p++);
- }
- }
- }
-
-<WORDS>{
- /*xxx look out for backslashes; escape backslashes and quotes */
- /*xxx if a quote is right against a char, we should append */
- {word} {
- /* Whitespace-separated word */
- setString(&gStr, yytext);
- yylval.literalString = gStr.value;
- return TOK_WORD;
- }
- }
-
-<INITIAL,WORDS,BOOLEAN>{
- \n {
- /* Count lines */
- gLineNumber++;
- gArgumentType = AM_UNKNOWN_ARGS;
- BEGIN(INITIAL);
- return TOK_EOL;
- }
-
- /*xxx backslashes to extend lines? */
- /* Skip whitespace and comments.
- */
- [ \t\r]+ ;
- #.* ;
-
- . {
- /* Fail on anything we didn't expect. */
- gErrorMessage = "unexpected character";
- return TOK_ERROR;
- }
- }
-%%
-
-void
-yyerror(const char *msg)
-{
- if (!strcmp(msg, "syntax error") && gErrorMessage != NULL) {
- msg = gErrorMessage;
- gErrorMessage = NULL;
- }
- fprintf(stderr, "line %d: %s at '%s'\n", gLineNumber, msg, yytext);
-}
-
-#if AMEND_LEXER_BUFFER_INPUT
-void
-setLexerInputBuffer(const char *buf, size_t buflen)
-{
- gLineNumber = 1;
- gInputBuffer = buf;
- gInputBufferNext = gInputBuffer;
- gInputBufferEnd = gInputBuffer + buflen;
-}
-#endif // AMEND_LEXER_BUFFER_INPUT
-
-void
-setLexerArgumentType(AmArgumentType type)
-{
- gArgumentType = type;
-}
-
-int
-getLexerLineNumber(void)
-{
- return gLineNumber;
-}
diff --git a/amend/main.c b/amend/main.c
deleted file mode 100644
index 9bb0785..0000000
--- a/amend/main.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "ast.h"
-#include "lexer.h"
-#include "parser.h"
-#include "register.h"
-#include "execute.h"
-
-void
-lexTest()
-{
- int token;
- do {
- token = yylex();
- if (token == 0) {
- printf(" EOF");
- fflush(stdout);
- break;
- } else {
- printf(" %s", tokenToString(token));
- fflush(stdout);
- if (token == TOK_IDENTIFIER) {
- if (strcmp(yylval.literalString, "assert") == 0) {
- setLexerArgumentType(AM_BOOLEAN_ARGS);
- } else {
- setLexerArgumentType(AM_WORD_ARGS);
- }
- do {
- token = yylex();
- printf(" %s", tokenToString(token));
- fflush(stdout);
- } while (token != TOK_EOL && token != TOK_EOF && token != 0);
- } else if (token != TOK_EOL) {
- fprintf(stderr, "syntax error: expected identifier\n");
- break;
- }
- }
- } while (token != 0);
- printf("\n");
-}
-
-void
-usage()
-{
- printf("usage: amend [--debug-lex|--debug-ast] [<filename>]\n");
- exit(1);
-}
-
-extern const AmCommandList *gCommands;
-int
-main(int argc, char *argv[])
-{
- FILE *inputFile = NULL;
- bool debugLex = false;
- bool debugAst = false;
- const char *fileName = NULL;
- int err;
-
-#if 1
- extern int test_symtab(void);
- int ret = test_symtab();
- if (ret != 0) {
- fprintf(stderr, "test_symtab() failed: %d\n", ret);
- exit(ret);
- }
- extern int test_cmd_fn(void);
- ret = test_cmd_fn();
- if (ret != 0) {
- fprintf(stderr, "test_cmd_fn() failed: %d\n", ret);
- exit(ret);
- }
- extern int test_permissions(void);
- ret = test_permissions();
- if (ret != 0) {
- fprintf(stderr, "test_permissions() failed: %d\n", ret);
- exit(ret);
- }
-#endif
-
- argc--;
- argv++;
- while (argc > 0) {
- if (strcmp("--debug-lex", argv[0]) == 0) {
- debugLex = true;
- } else if (strcmp("--debug-ast", argv[0]) == 0) {
- debugAst = true;
- } else if (argv[0][0] == '-') {
- fprintf(stderr, "amend: Unknown option \"%s\"\n", argv[0]);
- usage();
- } else {
- fileName = argv[0];
- }
- argc--;
- argv++;
- }
-
- if (fileName != NULL) {
- inputFile = fopen(fileName, "r");
- if (inputFile == NULL) {
- fprintf(stderr, "amend: Can't open input file '%s'\n", fileName);
- usage();
- }
- }
-
- commandInit();
-//xxx clean up
-
- err = registerUpdateCommands();
- if (err < 0) {
- fprintf(stderr, "amend: Error registering commands: %d\n", err);
- exit(-err);
- }
- err = registerUpdateFunctions();
- if (err < 0) {
- fprintf(stderr, "amend: Error registering functions: %d\n", err);
- exit(-err);
- }
-
-#if AMEND_LEXER_BUFFER_INPUT
- if (inputFile == NULL) {
- fprintf(stderr, "amend: No input file\n");
- usage();
- }
- char *fileData;
- int fileDataLen;
- fseek(inputFile, 0, SEEK_END);
- fileDataLen = ftell(inputFile);
- rewind(inputFile);
- if (fileDataLen < 0) {
- fprintf(stderr, "amend: Can't get file length\n");
- exit(2);
- } else if (fileDataLen == 0) {
- printf("amend: Empty input file\n");
- exit(0);
- }
- fileData = (char *)malloc(fileDataLen + 1);
- if (fileData == NULL) {
- fprintf(stderr, "amend: Can't allocate %d bytes\n", fileDataLen + 1);
- exit(2);
- }
- size_t nread = fread(fileData, 1, fileDataLen, inputFile);
- if (nread != (size_t)fileDataLen) {
- fprintf(stderr, "amend: Didn't read %d bytes, only %zd\n", fileDataLen,
- nread);
- exit(2);
- }
- fileData[fileDataLen] = '\0';
- setLexerInputBuffer(fileData, fileDataLen);
-#else
- if (inputFile == NULL) {
- inputFile = stdin;
- }
- yyset_in(inputFile);
-#endif
-
- if (debugLex) {
- lexTest();
- } else {
- int ret = yyparse();
- if (ret != 0) {
- fprintf(stderr, "amend: Parse failed (%d)\n", ret);
- exit(2);
- } else {
- if (debugAst) {
- dumpCommandList(gCommands);
- }
-printf("amend: Parse successful.\n");
- ret = execCommandList((ExecContext *)1, gCommands);
- if (ret != 0) {
- fprintf(stderr, "amend: Execution failed (%d)\n", ret);
- exit(3);
- }
-printf("amend: Execution successful.\n");
- }
- }
-
- return 0;
-}
diff --git a/amend/parser.h b/amend/parser.h
deleted file mode 100644
index aeb8657..0000000
--- a/amend/parser.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AMEND_PARSER_H_
-#define AMEND_PARSER_H_
-
-#include "parser_y.h"
-
-int yyparse(void);
-
-#endif // AMEND_PARSER_H_
diff --git a/amend/parser_y.y b/amend/parser_y.y
deleted file mode 100644
index b634016..0000000
--- a/amend/parser_y.y
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-%{
-#undef NDEBUG
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <stdio.h>
- #include "ast.h"
- #include "lexer.h"
- #include "commands.h"
-
- void yyerror(const char *msg);
- int yylex(void);
-
-#define STRING_COMPARISON(out, a1, sop, a2) \
- do { \
- out = (AmBooleanValue *)malloc(sizeof(AmBooleanValue)); \
- if (out == NULL) { \
- YYABORT; \
- } \
- out->type = AM_BVAL_STRING_COMPARISON; \
- out->u.stringComparison.op = sop; \
- out->u.stringComparison.arg1 = a1; \
- out->u.stringComparison.arg2 = a2; \
- } while (false)
-
-#define BOOLEAN_EXPRESSION(out, a1, bop, a2) \
- do { \
- out = (AmBooleanValue *)malloc(sizeof(AmBooleanValue)); \
- if (out == NULL) { \
- YYABORT; \
- } \
- out->type = AM_BVAL_EXPRESSION; \
- out->u.expression.op = bop; \
- out->u.expression.arg1 = a1; \
- out->u.expression.arg2 = a2; \
- } while (false)
-
-AmCommandList *gCommands = NULL;
-%}
-
-%start lines
-
-%union {
- char *literalString;
- AmFunctionArgumentBuilder *functionArgumentBuilder;
- AmFunctionArguments *functionArguments;
- AmFunctionCall *functionCall;
- AmStringValue *stringValue;
- AmBooleanValue *booleanValue;
- AmWordListBuilder *wordListBuilder;
- AmCommandArguments *commandArguments;
- AmCommand *command;
- AmCommandList *commandList;
- }
-
-%token TOK_AND TOK_OR TOK_EQ TOK_NE TOK_GE TOK_LE TOK_EOF TOK_EOL TOK_ERROR
-%token <literalString> TOK_STRING TOK_IDENTIFIER TOK_WORD
-
-%type <commandList> lines
-%type <command> command line
-%type <functionArgumentBuilder> function_arguments
-%type <functionArguments> function_arguments_or_empty
-%type <functionCall> function_call
-%type <literalString> function_name
-%type <stringValue> string_value
-%type <booleanValue> boolean_expression
-%type <wordListBuilder> word_list
-%type <commandArguments> arguments
-
-/* Operator precedence, weakest to strongest.
- * Same as C/Java precedence.
- */
-
-%left TOK_OR
-%left TOK_AND
-%left TOK_EQ TOK_NE
-%left '<' '>' TOK_LE TOK_GE
-%right '!'
-
-%%
-
-lines : /* empty */
- {
- $$ = (AmCommandList *)malloc(sizeof(AmCommandList));
- if ($$ == NULL) {
- YYABORT;
- }
-gCommands = $$;
- $$->arraySize = 64;
- $$->commandCount = 0;
- $$->commands = (AmCommand **)malloc(
- sizeof(AmCommand *) * $$->arraySize);
- if ($$->commands == NULL) {
- YYABORT;
- }
- }
- | lines line
- {
- if ($2 != NULL) {
- if ($1->commandCount >= $1->arraySize) {
- AmCommand **newArray;
- newArray = (AmCommand **)realloc($$->commands,
- sizeof(AmCommand *) * $$->arraySize * 2);
- if (newArray == NULL) {
- YYABORT;
- }
- $$->commands = newArray;
- $$->arraySize *= 2;
- }
- $1->commands[$1->commandCount++] = $2;
- }
- }
- ;
-
-line : line_ending
- {
- $$ = NULL; /* ignore blank lines */
- }
- | command arguments line_ending
- {
- $$ = $1;
- $$->args = $2;
- setLexerArgumentType(AM_UNKNOWN_ARGS);
- }
- ;
-
-command : TOK_IDENTIFIER
- {
- Command *cmd = findCommand($1);
- if (cmd == NULL) {
- fprintf(stderr, "Unknown command \"%s\"\n", $1);
- YYABORT;
- }
- $$ = (AmCommand *)malloc(sizeof(AmCommand));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->line = getLexerLineNumber();
- $$->name = strdup($1);
- if ($$->name == NULL) {
- YYABORT;
- }
- $$->args = NULL;
- CommandArgumentType argType = getCommandArgumentType(cmd);
- if (argType == CMD_ARGS_BOOLEAN) {
- setLexerArgumentType(AM_BOOLEAN_ARGS);
- } else {
- setLexerArgumentType(AM_WORD_ARGS);
- }
- $$->cmd = cmd;
- }
- ;
-
-line_ending :
- TOK_EOL
- | TOK_EOF
- ;
-
-arguments : boolean_expression
- {
- $$ = (AmCommandArguments *)malloc(
- sizeof(AmCommandArguments));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->booleanArgs = true;
- $$->u.b = $1;
- }
- | word_list
- {
- /* Convert the builder list into an array.
- * Do it in reverse order; the words were pushed
- * onto the list in LIFO order.
- */
- AmWordList *w = (AmWordList *)malloc(sizeof(AmWordList));
- if (w == NULL) {
- YYABORT;
- }
- if ($1 != NULL) {
- AmWordListBuilder *words = $1;
-
- w->argc = words->wordCount;
- w->argv = (const char **)malloc(w->argc *
- sizeof(char *));
- if (w->argv == NULL) {
- YYABORT;
- }
- int i;
- for (i = w->argc; words != NULL && i > 0; --i) {
- AmWordListBuilder *f = words;
- w->argv[i-1] = words->word;
- words = words->next;
- free(f);
- }
- assert(i == 0);
- assert(words == NULL);
- } else {
- w->argc = 0;
- w->argv = NULL;
- }
- $$ = (AmCommandArguments *)malloc(
- sizeof(AmCommandArguments));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->booleanArgs = false;
- $$->u.w = w;
- }
- ;
-
-word_list : /* empty */
- { $$ = NULL; }
- | word_list TOK_WORD
- {
- if ($1 == NULL) {
- $$ = (AmWordListBuilder *)malloc(
- sizeof(AmWordListBuilder));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->next = NULL;
- $$->wordCount = 1;
- } else {
- $$ = (AmWordListBuilder *)malloc(
- sizeof(AmWordListBuilder));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->next = $1;
- $$->wordCount = $$->next->wordCount + 1;
- }
- $$->word = strdup($2);
- if ($$->word == NULL) {
- YYABORT;
- }
- }
- ;
-
-boolean_expression :
- '!' boolean_expression
- {
- $$ = (AmBooleanValue *)malloc(sizeof(AmBooleanValue));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->type = AM_BVAL_EXPRESSION;
- $$->u.expression.op = AM_BOP_NOT;
- $$->u.expression.arg1 = $2;
- $$->u.expression.arg2 = NULL;
- }
- /* TODO: if both expressions are literals, evaluate now */
- | boolean_expression TOK_AND boolean_expression
- { BOOLEAN_EXPRESSION($$, $1, AM_BOP_AND, $3); }
- | boolean_expression TOK_OR boolean_expression
- { BOOLEAN_EXPRESSION($$, $1, AM_BOP_OR, $3); }
- | boolean_expression TOK_EQ boolean_expression
- { BOOLEAN_EXPRESSION($$, $1, AM_BOP_EQ, $3); }
- | boolean_expression TOK_NE boolean_expression
- { BOOLEAN_EXPRESSION($$, $1, AM_BOP_NE, $3); }
- | '(' boolean_expression ')'
- { $$ = $2; }
- /* TODO: if both strings are literals, evaluate now */
- | string_value '<' string_value
- { STRING_COMPARISON($$, $1, AM_SOP_LT, $3); }
- | string_value '>' string_value
- { STRING_COMPARISON($$, $1, AM_SOP_GT, $3); }
- | string_value TOK_EQ string_value
- { STRING_COMPARISON($$, $1, AM_SOP_EQ, $3); }
- | string_value TOK_NE string_value
- { STRING_COMPARISON($$, $1, AM_SOP_NE, $3); }
- | string_value TOK_LE string_value
- { STRING_COMPARISON($$, $1, AM_SOP_LE, $3); }
- | string_value TOK_GE string_value
- { STRING_COMPARISON($$, $1, AM_SOP_GE, $3); }
- ;
-
-string_value :
- TOK_IDENTIFIER
- {
- $$ = (AmStringValue *)malloc(sizeof(AmStringValue));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->type = AM_SVAL_LITERAL;
- $$->u.literal = strdup($1);
- if ($$->u.literal == NULL) {
- YYABORT;
- }
- }
- | TOK_STRING
- {
- $$ = (AmStringValue *)malloc(sizeof(AmStringValue));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->type = AM_SVAL_LITERAL;
- $$->u.literal = strdup($1);
- if ($$->u.literal == NULL) {
- YYABORT;
- }
- }
- | function_call
- {
- $$ = (AmStringValue *)malloc(sizeof(AmStringValue));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->type = AM_SVAL_FUNCTION;
- $$->u.function = $1;
- }
- ;
-
- /* We can't just say
- * TOK_IDENTIFIER '(' function_arguments_or_empty ')'
- * because parsing function_arguments_or_empty will clobber
- * the underlying string that yylval.literalString points to.
- */
-function_call :
- function_name '(' function_arguments_or_empty ')'
- {
- Function *fn = findFunction($1);
- if (fn == NULL) {
- fprintf(stderr, "Unknown function \"%s\"\n", $1);
- YYABORT;
- }
- $$ = (AmFunctionCall *)malloc(sizeof(AmFunctionCall));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->name = $1;
- if ($$->name == NULL) {
- YYABORT;
- }
- $$->fn = fn;
- $$->args = $3;
- }
- ;
-
-function_name :
- TOK_IDENTIFIER
- {
- $$ = strdup($1);
- }
- ;
-
-function_arguments_or_empty :
- /* empty */
- {
- $$ = (AmFunctionArguments *)malloc(
- sizeof(AmFunctionArguments));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->argc = 0;
- $$->argv = NULL;
- }
- | function_arguments
- {
- AmFunctionArgumentBuilder *args = $1;
- assert(args != NULL);
-
- /* Convert the builder list into an array.
- * Do it in reverse order; the args were pushed
- * onto the list in LIFO order.
- */
- $$ = (AmFunctionArguments *)malloc(
- sizeof(AmFunctionArguments));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->argc = args->argCount;
- $$->argv = (AmStringValue *)malloc(
- $$->argc * sizeof(AmStringValue));
- if ($$->argv == NULL) {
- YYABORT;
- }
- int i;
- for (i = $$->argc; args != NULL && i > 0; --i) {
- AmFunctionArgumentBuilder *f = args;
- $$->argv[i-1] = *args->arg;
- args = args->next;
- free(f->arg);
- free(f);
- }
- assert(i == 0);
- assert(args == NULL);
- }
- ;
-
-function_arguments :
- string_value
- {
- $$ = (AmFunctionArgumentBuilder *)malloc(
- sizeof(AmFunctionArgumentBuilder));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->next = NULL;
- $$->argCount = 1;
- $$->arg = $1;
- }
- | function_arguments ',' string_value
- {
- $$ = (AmFunctionArgumentBuilder *)malloc(
- sizeof(AmFunctionArgumentBuilder));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->next = $1;
- $$->argCount = $$->next->argCount + 1;
- $$->arg = $3;
- }
- ;
- /* xxx this whole tool needs to be hardened */
diff --git a/amend/permissions.c b/amend/permissions.c
deleted file mode 100644
index a642d0b..0000000
--- a/amend/permissions.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "permissions.h"
-
-int
-initPermissionRequestList(PermissionRequestList *list)
-{
- if (list != NULL) {
- list->requests = NULL;
- list->numRequests = 0;
- list->requestsAllocated = 0;
- return 0;
- }
- return -1;
-}
-
-int
-addPermissionRequestToList(PermissionRequestList *list,
- const char *path, bool recursive, unsigned int permissions)
-{
- if (list == NULL || list->numRequests < 0 ||
- list->requestsAllocated < list->numRequests || path == NULL)
- {
- return -1;
- }
-
- if (list->numRequests == list->requestsAllocated) {
- int newSize;
- PermissionRequest *newRequests;
-
- newSize = list->requestsAllocated * 2;
- if (newSize < 16) {
- newSize = 16;
- }
- newRequests = (PermissionRequest *)realloc(list->requests,
- newSize * sizeof(PermissionRequest));
- if (newRequests == NULL) {
- return -2;
- }
- list->requests = newRequests;
- list->requestsAllocated = newSize;
- }
-
- PermissionRequest *req;
- req = &list->requests[list->numRequests++];
- req->path = strdup(path);
- if (req->path == NULL) {
- list->numRequests--;
- return -3;
- }
- req->recursive = recursive;
- req->requested = permissions;
- req->allowed = 0;
-
- return 0;
-}
-
-void
-freePermissionRequestListElements(PermissionRequestList *list)
-{
- if (list != NULL && list->numRequests >= 0 &&
- list->requestsAllocated >= list->numRequests)
- {
- int i;
- for (i = 0; i < list->numRequests; i++) {
- free((void *)list->requests[i].path);
- }
- free(list->requests);
- initPermissionRequestList(list);
- }
-}
-
-/*
- * Global permission table
- */
-
-static struct {
- Permission *permissions;
- int numPermissionEntries;
- int allocatedPermissionEntries;
- bool permissionStateInitialized;
-} gPermissionState = {
-#if 1
- NULL, 0, 0, false
-#else
- .permissions = NULL,
- .numPermissionEntries = 0,
- .allocatedPermissionEntries = 0,
- .permissionStateInitialized = false
-#endif
-};
-
-int
-permissionInit()
-{
- if (gPermissionState.permissionStateInitialized) {
- return -1;
- }
- gPermissionState.permissions = NULL;
- gPermissionState.numPermissionEntries = 0;
- gPermissionState.allocatedPermissionEntries = 0;
- gPermissionState.permissionStateInitialized = true;
-//xxx maybe add an "namespace root gets no permissions" fallback by default
- return 0;
-}
-
-void
-permissionCleanup()
-{
- if (gPermissionState.permissionStateInitialized) {
- gPermissionState.permissionStateInitialized = false;
- if (gPermissionState.permissions != NULL) {
- int i;
- for (i = 0; i < gPermissionState.numPermissionEntries; i++) {
- free((void *)gPermissionState.permissions[i].path);
- }
- free(gPermissionState.permissions);
- }
- }
-}
-
-int
-getPermissionCount()
-{
- if (gPermissionState.permissionStateInitialized) {
- return gPermissionState.numPermissionEntries;
- }
- return -1;
-}
-
-const Permission *
-getPermissionAt(int index)
-{
- if (!gPermissionState.permissionStateInitialized) {
- return NULL;
- }
- if (index < 0 || index >= gPermissionState.numPermissionEntries) {
- return NULL;
- }
- return &gPermissionState.permissions[index];
-}
-
-int
-getAllowedPermissions(const char *path, bool recursive,
- unsigned int *outAllowed)
-{
- if (!gPermissionState.permissionStateInitialized) {
- return -2;
- }
- if (outAllowed == NULL) {
- return -1;
- }
- *outAllowed = 0;
- if (path == NULL) {
- return -1;
- }
- //TODO: implement this for real.
- recursive = false;
- *outAllowed = PERMSET_ALL;
- return 0;
-}
-
-int
-countPermissionConflicts(PermissionRequestList *requests, bool updateAllowed)
-{
- if (!gPermissionState.permissionStateInitialized) {
- return -2;
- }
- if (requests == NULL || requests->requests == NULL ||
- requests->numRequests < 0 ||
- requests->requestsAllocated < requests->numRequests)
- {
- return -1;
- }
- int conflicts = 0;
- int i;
- for (i = 0; i < requests->numRequests; i++) {
- PermissionRequest *req;
- unsigned int allowed;
- int ret;
-
- req = &requests->requests[i];
- ret = getAllowedPermissions(req->path, req->recursive, &allowed);
- if (ret < 0) {
- return ret;
- }
- if ((req->requested & ~allowed) != 0) {
- conflicts++;
- }
- if (updateAllowed) {
- req->allowed = allowed;
- }
- }
- return conflicts;
-}
-
-int
-registerPermissionSet(int count, Permission *set)
-{
- if (!gPermissionState.permissionStateInitialized) {
- return -2;
- }
- if (count < 0 || (count > 0 && set == NULL)) {
- return -1;
- }
- if (count == 0) {
- return 0;
- }
-
- if (gPermissionState.numPermissionEntries + count >=
- gPermissionState.allocatedPermissionEntries)
- {
- Permission *newList;
- int newSize;
-
- newSize = (gPermissionState.allocatedPermissionEntries + count) * 2;
- if (newSize < 16) {
- newSize = 16;
- }
- newList = (Permission *)realloc(gPermissionState.permissions,
- newSize * sizeof(Permission));
- if (newList == NULL) {
- return -3;
- }
- gPermissionState.permissions = newList;
- gPermissionState.allocatedPermissionEntries = newSize;
- }
-
- Permission *p = &gPermissionState.permissions[
- gPermissionState.numPermissionEntries];
- int i;
- for (i = 0; i < count; i++) {
- *p = set[i];
- //TODO: cache the strlen of the path
- //TODO: normalize; strip off trailing /
- p->path = strdup(p->path);
- if (p->path == NULL) {
- /* If we can't add all of the entries, we don't
- * add any of them.
- */
- Permission *pp = &gPermissionState.permissions[
- gPermissionState.numPermissionEntries];
- while (pp != p) {
- free((void *)pp->path);
- pp++;
- }
- return -4;
- }
- p++;
- }
- gPermissionState.numPermissionEntries += count;
-
- return 0;
-}
diff --git a/amend/permissions.h b/amend/permissions.h
deleted file mode 100644
index 5b1d14d..0000000
--- a/amend/permissions.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AMEND_PERMISSIONS_H_
-#define AMEND_PERMISSIONS_H_
-
-#include <stdbool.h>
-
-#define PERM_NONE (0)
-#define PERM_STAT (1<<0)
-#define PERM_READ (1<<1)
-#define PERM_WRITE (1<<2) // including create, delete, mkdir, rmdir
-#define PERM_CHMOD (1<<3)
-#define PERM_CHOWN (1<<4)
-#define PERM_CHGRP (1<<5)
-#define PERM_SETUID (1<<6)
-#define PERM_SETGID (1<<7)
-
-#define PERMSET_READ (PERM_STAT | PERM_READ)
-#define PERMSET_WRITE (PERMSET_READ | PERM_WRITE)
-
-#define PERMSET_ALL \
- (PERM_STAT | PERM_READ | PERM_WRITE | PERM_CHMOD | \
- PERM_CHOWN | PERM_CHGRP | PERM_SETUID | PERM_SETGID)
-
-typedef struct {
- unsigned int requested;
- unsigned int allowed;
- const char *path;
- bool recursive;
-} PermissionRequest;
-
-typedef struct {
- PermissionRequest *requests;
- int numRequests;
- int requestsAllocated;
-} PermissionRequestList;
-
-/* Properly clear out a PermissionRequestList.
- *
- * @return 0 if list is non-NULL, negative otherwise.
- */
-int initPermissionRequestList(PermissionRequestList *list);
-
-/* Add a permission request to the list, allocating more space
- * if necessary.
- *
- * @return 0 on success or a negative value on failure.
- */
-int addPermissionRequestToList(PermissionRequestList *list,
- const char *path, bool recursive, unsigned int permissions);
-
-/* Free anything allocated by addPermissionRequestToList(). The caller
- * is responsible for freeing the actual PermissionRequestList.
- */
-void freePermissionRequestListElements(PermissionRequestList *list);
-
-
-/*
- * Global permission table
- */
-
-typedef struct {
- const char *path;
- unsigned int allowed;
-} Permission;
-
-int permissionInit(void);
-void permissionCleanup(void);
-
-/* Returns the allowed permissions for the path in "outAllowed".
- * Returns 0 if successful, negative if a parameter or global state
- * is bad.
- */
-int getAllowedPermissions(const char *path, bool recursive,
- unsigned int *outAllowed);
-
-/* More-recently-registered permissions override older permissions.
- */
-int registerPermissionSet(int count, Permission *set);
-
-/* Check to make sure that each request is allowed.
- *
- * @param requests The list of permission requests
- * @param updateAllowed If true, update the "allowed" field in each
- * element of the list
- * @return the number of requests that were denied, or negative if
- * an error occurred.
- */
-int countPermissionConflicts(PermissionRequestList *requests,
- bool updateAllowed);
-
-/* Inspection/testing/debugging functions
- */
-int getPermissionCount(void);
-const Permission *getPermissionAt(int index);
-
-#endif // AMEND_PERMISSIONS_H_
diff --git a/amend/register.c b/amend/register.c
deleted file mode 100644
index 167dd32..0000000
--- a/amend/register.c
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#undef NDEBUG
-#include <assert.h>
-#include "commands.h"
-
-#include "register.h"
-
-#define UNUSED(p) ((void)(p))
-
-#define CHECK_BOOL() \
- do { \
- assert(argv == NULL); \
- if (argv != NULL) return -1; \
- assert(argc == true || argc == false); \
- if (argc != true && argc != false) return -1; \
- } while (false)
-
-#define CHECK_WORDS() \
- do { \
- assert(argc >= 0); \
- if (argc < 0) return -1; \
- assert(argc == 0 || argv != NULL); \
- if (argc != 0 && argv == NULL) return -1; \
- if (permissions != NULL) { \
- int CW_I_; \
- for (CW_I_ = 0; CW_I_ < argc; CW_I_++) { \
- assert(argv[CW_I_] != NULL); \
- if (argv[CW_I_] == NULL) return -1; \
- } \
- } \
- } while (false)
-
-#define CHECK_FN() \
- do { \
- CHECK_WORDS(); \
- if (permissions != NULL) { \
- assert(result == NULL); \
- if (result != NULL) return -1; \
- } else { \
- assert(result != NULL); \
- if (result == NULL) return -1; \
- } \
- } while (false)
-
-#define NO_PERMS(perms) \
- do { \
- PermissionRequestList *NP_PRL_ = (perms); \
- if (NP_PRL_ != NULL) { \
- int NP_RET_ = addPermissionRequestToList(NP_PRL_, \
- "", false, PERM_NONE); \
- if (NP_RET_ < 0) { \
- /* Returns from the calling function. \
- */ \
- return NP_RET_; \
- } \
- } \
- } while (false)
-
-/*
- * Command definitions
- */
-
-/* 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;
- }
-}
-
-/* format <root>
- */
-static int
-cmd_format(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx
- return -1;
-}
-
-/* copy_dir <srcdir> <dstdir>
- */
-static int
-cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx
- return -1;
-}
-
-/* mark <resource> dirty|clean
- */
-static int
-cmd_mark(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx when marking, save the top-level hash at the mark point
-// so we can retry on failure. Otherwise the hashes won't match,
-// or someone could intentionally dirty the FS to force a downgrade
-//xxx
- return -1;
-}
-
-/* done
- */
-static int
-cmd_done(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx
- return -1;
-}
-
-int
-registerUpdateCommands()
-{
- int ret;
-
- ret = registerCommand("assert", CMD_ARGS_BOOLEAN, cmd_assert, NULL);
- if (ret < 0) return ret;
-
- ret = registerCommand("copy_dir", CMD_ARGS_WORDS, cmd_copy_dir, NULL);
- if (ret < 0) return ret;
-
- ret = registerCommand("format", CMD_ARGS_WORDS, cmd_format, NULL);
- if (ret < 0) return ret;
-
- ret = registerCommand("mark", CMD_ARGS_WORDS, cmd_mark, NULL);
- if (ret < 0) return ret;
-
- ret = registerCommand("done", CMD_ARGS_WORDS, cmd_done, NULL);
- if (ret < 0) return ret;
-
-//xxx some way to fix permissions
-//xxx could have "installperms" commands that build the fs_config list
-//xxx along with a "commitperms", and any copy_dir etc. needs to see
-// a commitperms before it will work
-
- return 0;
-}
-
-
-/*
- * Function definitions
- */
-
-/* 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;
-}
-
-/* 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;
-}
-
-/* hash_dir(<path-to-directory>)
- */
-static int
-fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen,
- PermissionRequestList *permissions)
-{
- int ret = -1;
-
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- const char *dir;
- if (argc != 1) {
- fprintf(stderr, "%s: wrong number of arguments (%d)\n",
- name, argc);
- return 1;
- } else {
- dir = argv[0];
- }
-
- if (permissions != NULL) {
- if (dir == NULL) {
- /* The argument is the result of another function.
- * Assume the worst case, where the function returns
- * the root.
- */
- dir = "/";
- }
- ret = addPermissionRequestToList(permissions, dir, true, PERM_READ);
- } else {
-//xxx build and return the string
- *result = strdup("hashvalue");
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
- ret = 0;
- }
-
- return ret;
-}
-
-/* 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;
-}
-
-/* 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;
-}
-
-int
-registerUpdateFunctions()
-{
- int ret;
-
- ret = registerFunction("update_forced", fn_update_forced, NULL);
- if (ret < 0) return ret;
-
- ret = registerFunction("get_mark", fn_get_mark, NULL);
- if (ret < 0) return ret;
-
- ret = registerFunction("hash_dir", fn_hash_dir, NULL);
- if (ret < 0) return ret;
-
- ret = registerFunction("matches", fn_matches, NULL);
- if (ret < 0) return ret;
-
- ret = registerFunction("concat", fn_concat, NULL);
- if (ret < 0) return ret;
-
- return 0;
-}
diff --git a/amend/register.h b/amend/register.h
deleted file mode 100644
index 1d9eacb..0000000
--- a/amend/register.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AMEND_REGISTER_H_
-#define AMEND_REGISTER_H_
-
-int registerUpdateCommands(void);
-int registerUpdateFunctions(void);
-
-#endif // AMEND_REGISTER_H_
diff --git a/amend/symtab.c b/amend/symtab.c
deleted file mode 100644
index 835d2fc..0000000
--- a/amend/symtab.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "symtab.h"
-
-#define DEFAULT_TABLE_SIZE 16
-
-typedef struct {
- char *symbol;
- const void *cookie;
- unsigned int flags;
-} SymbolTableEntry;
-
-struct SymbolTable {
- SymbolTableEntry *table;
- int numEntries;
- int maxSize;
-};
-
-SymbolTable *
-createSymbolTable()
-{
- SymbolTable *tab;
-
- tab = (SymbolTable *)malloc(sizeof(SymbolTable));
- if (tab != NULL) {
- tab->numEntries = 0;
- tab->maxSize = DEFAULT_TABLE_SIZE;
- tab->table = (SymbolTableEntry *)malloc(
- tab->maxSize * sizeof(SymbolTableEntry));
- if (tab->table == NULL) {
- free(tab);
- tab = NULL;
- }
- }
- return tab;
-}
-
-void
-deleteSymbolTable(SymbolTable *tab)
-{
- if (tab != NULL) {
- while (tab->numEntries > 0) {
- free(tab->table[--tab->numEntries].symbol);
- }
- free(tab->table);
- }
-}
-
-void *
-findInSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags)
-{
- int i;
-
- if (tab == NULL || symbol == NULL) {
- return NULL;
- }
-
- // TODO: Sort the table and binary search
- for (i = 0; i < tab->numEntries; i++) {
- if (strcmp(tab->table[i].symbol, symbol) == 0 &&
- tab->table[i].flags == flags)
- {
- return (void *)tab->table[i].cookie;
- }
- }
-
- return NULL;
-}
-
-int
-addToSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags,
- const void *cookie)
-{
- if (tab == NULL || symbol == NULL || cookie == NULL) {
- return -1;
- }
-
- /* Make sure that this symbol isn't already in the table.
- */
- if (findInSymbolTable(tab, symbol, flags) != NULL) {
- return -2;
- }
-
- /* Make sure there's enough space for the new entry.
- */
- if (tab->numEntries == tab->maxSize) {
- SymbolTableEntry *newTable;
- int newSize;
-
- newSize = tab->numEntries * 2;
- if (newSize < DEFAULT_TABLE_SIZE) {
- newSize = DEFAULT_TABLE_SIZE;
- }
- newTable = (SymbolTableEntry *)realloc(tab->table,
- newSize * sizeof(SymbolTableEntry));
- if (newTable == NULL) {
- return -1;
- }
- tab->maxSize = newSize;
- tab->table = newTable;
- }
-
- /* Insert the new entry.
- */
- symbol = strdup(symbol);
- if (symbol == NULL) {
- return -1;
- }
- // TODO: Sort the table
- tab->table[tab->numEntries].symbol = (char *)symbol;
- tab->table[tab->numEntries].cookie = cookie;
- tab->table[tab->numEntries].flags = flags;
- tab->numEntries++;
-
- return 0;
-}
diff --git a/amend/symtab.h b/amend/symtab.h
deleted file mode 100644
index f83c65b..0000000
--- a/amend/symtab.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef AMEND_SYMTAB_H_
-#define AMEND_SYMTAB_H_
-
-typedef struct SymbolTable SymbolTable;
-
-SymbolTable *createSymbolTable(void);
-
-void deleteSymbolTable(SymbolTable *tab);
-
-/* symbol and cookie must be non-NULL.
- */
-int addToSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags,
- const void *cookie);
-
-void *findInSymbolTable(SymbolTable *tab, const char *symbol,
- unsigned int flags);
-
-#endif // AMEND_SYMTAB_H_
diff --git a/amend/test_commands.c b/amend/test_commands.c
deleted file mode 100644
index be938ac..0000000
--- a/amend/test_commands.c
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#undef NDEBUG
-#include <assert.h>
-#include "commands.h"
-
-static struct {
- bool called;
- const char *name;
- void *cookie;
- int argc;
- const char **argv;
- PermissionRequestList *permissions;
- int returnValue;
- char *functionResult;
-} gTestCommandState;
-
-static int
-testCommand(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- gTestCommandState.called = true;
- gTestCommandState.name = name;
- gTestCommandState.cookie = cookie;
- gTestCommandState.argc = argc;
- gTestCommandState.argv = argv;
- gTestCommandState.permissions = permissions;
- return gTestCommandState.returnValue;
-}
-
-static int
-testFunction(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen, PermissionRequestList *permissions)
-{
- gTestCommandState.called = true;
- gTestCommandState.name = name;
- gTestCommandState.cookie = cookie;
- gTestCommandState.argc = argc;
- gTestCommandState.argv = argv;
- gTestCommandState.permissions = permissions;
- if (result != NULL) {
- *result = gTestCommandState.functionResult;
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
- }
- return gTestCommandState.returnValue;
-}
-
-static int
-test_commands()
-{
- Command *cmd;
- int ret;
- CommandArgumentType argType;
-
- ret = commandInit();
- assert(ret == 0);
-
- /* Make sure we can't initialize twice.
- */
- ret = commandInit();
- assert(ret < 0);
-
- /* Try calling with some bad values.
- */
- ret = registerCommand(NULL, CMD_ARGS_UNKNOWN, NULL, NULL);
- assert(ret < 0);
-
- ret = registerCommand("hello", CMD_ARGS_UNKNOWN, NULL, NULL);
- assert(ret < 0);
-
- ret = registerCommand("hello", CMD_ARGS_WORDS, NULL, NULL);
- assert(ret < 0);
-
- cmd = findCommand(NULL);
- assert(cmd == NULL);
-
- argType = getCommandArgumentType(NULL);
- assert((int)argType < 0);
-
- ret = callCommand(NULL, -1, NULL);
- assert(ret < 0);
-
- ret = callBooleanCommand(NULL, false);
- assert(ret < 0);
-
- /* Register some commands.
- */
- ret = registerCommand("one", CMD_ARGS_WORDS, testCommand,
- &gTestCommandState);
- assert(ret == 0);
-
- ret = registerCommand("two", CMD_ARGS_WORDS, testCommand,
- &gTestCommandState);
- assert(ret == 0);
-
- ret = registerCommand("bool", CMD_ARGS_BOOLEAN, testCommand,
- &gTestCommandState);
- assert(ret == 0);
-
- /* Make sure that all of those commands exist and that their
- * argument types are correct.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
- argType = getCommandArgumentType(cmd);
- assert(argType == CMD_ARGS_WORDS);
-
- cmd = findCommand("two");
- assert(cmd != NULL);
- argType = getCommandArgumentType(cmd);
- assert(argType == CMD_ARGS_WORDS);
-
- cmd = findCommand("bool");
- assert(cmd != NULL);
- argType = getCommandArgumentType(cmd);
- assert(argType == CMD_ARGS_BOOLEAN);
-
- /* Make sure that no similar commands exist.
- */
- cmd = findCommand("on");
- assert(cmd == NULL);
-
- cmd = findCommand("onee");
- assert(cmd == NULL);
-
- /* Make sure that a double insertion fails.
- */
- ret = registerCommand("one", CMD_ARGS_WORDS, testCommand,
- &gTestCommandState);
- assert(ret < 0);
-
- /* Make sure that bad args fail.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
-
- ret = callCommand(cmd, -1, NULL); // argc must be non-negative
- assert(ret < 0);
-
- ret = callCommand(cmd, 1, NULL); // argv can't be NULL if argc > 0
- assert(ret < 0);
-
- /* Make sure that you can't make a boolean call on a regular command.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
-
- ret = callBooleanCommand(cmd, false);
- assert(ret < 0);
-
- /* Make sure that you can't make a regular call on a boolean command.
- */
- cmd = findCommand("bool");
- assert(cmd != NULL);
-
- ret = callCommand(cmd, 0, NULL);
- assert(ret < 0);
-
- /* Set up some arguments.
- */
- int argc = 4;
- const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
-
- /* Make a call and make sure that it occurred.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 25;
- gTestCommandState.permissions = (PermissionRequestList *)1;
- ret = callCommand(cmd, argc, argv);
-//xxx also try calling with a null argv element (should fail)
- assert(ret == 25);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "one") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == argc);
- assert(gTestCommandState.argv == argv);
- assert(gTestCommandState.permissions == NULL);
-
- /* Make a boolean call and make sure that it occurred.
- */
- cmd = findCommand("bool");
- assert(cmd != NULL);
-
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 12;
- gTestCommandState.permissions = (PermissionRequestList *)1;
- ret = callBooleanCommand(cmd, false);
- assert(ret == 12);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "bool") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == 0);
- assert(gTestCommandState.argv == NULL);
- assert(gTestCommandState.permissions == NULL);
-
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 13;
- gTestCommandState.permissions = (PermissionRequestList *)1;
- ret = callBooleanCommand(cmd, true);
- assert(ret == 13);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "bool") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == 1);
- assert(gTestCommandState.argv == NULL);
- assert(gTestCommandState.permissions == NULL);
-
- /* Try looking up permissions.
- */
- PermissionRequestList permissions;
- cmd = findCommand("one");
- assert(cmd != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 27;
- gTestCommandState.permissions = (PermissionRequestList *)1;
- argv[1] = NULL; // null out an arg, which should be ok
- ret = getCommandPermissions(cmd, argc, argv, &permissions);
- assert(ret == 27);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "one") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == argc);
- assert(gTestCommandState.argv == argv);
- assert(gTestCommandState.permissions == &permissions);
-
- /* Boolean command permissions
- */
- cmd = findCommand("bool");
- assert(cmd != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 55;
- gTestCommandState.permissions = (PermissionRequestList *)1;
- // argv[1] is still NULL
- ret = getBooleanCommandPermissions(cmd, true, &permissions);
- assert(ret == 55);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "bool") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == 1);
- assert(gTestCommandState.argv == NULL);
- assert(gTestCommandState.permissions == &permissions);
-
-
- /* Smoke test commandCleanup().
- */
- commandCleanup();
-
- return 0;
-}
-
-static int
-test_functions()
-{
- Function *fn;
- int ret;
-
- ret = commandInit();
- assert(ret == 0);
-
- /* Try calling with some bad values.
- */
- ret = registerFunction(NULL, NULL, NULL);
- assert(ret < 0);
-
- ret = registerFunction("hello", NULL, NULL);
- assert(ret < 0);
-
- fn = findFunction(NULL);
- assert(fn == NULL);
-
- ret = callFunction(NULL, -1, NULL, NULL, NULL);
- assert(ret < 0);
-
- /* Register some functions.
- */
- ret = registerFunction("one", testFunction, &gTestCommandState);
- assert(ret == 0);
-
- ret = registerFunction("two", testFunction, &gTestCommandState);
- assert(ret == 0);
-
- ret = registerFunction("three", testFunction, &gTestCommandState);
- assert(ret == 0);
-
- /* Make sure that all of those functions exist.
- * argument types are correct.
- */
- fn = findFunction("one");
- assert(fn != NULL);
-
- fn = findFunction("two");
- assert(fn != NULL);
-
- fn = findFunction("three");
- assert(fn != NULL);
-
- /* Make sure that no similar functions exist.
- */
- fn = findFunction("on");
- assert(fn == NULL);
-
- fn = findFunction("onee");
- assert(fn == NULL);
-
- /* Make sure that a double insertion fails.
- */
- ret = registerFunction("one", testFunction, &gTestCommandState);
- assert(ret < 0);
-
- /* Make sure that bad args fail.
- */
- fn = findFunction("one");
- assert(fn != NULL);
-
- // argc must be non-negative
- ret = callFunction(fn, -1, NULL, (char **)1, NULL);
- assert(ret < 0);
-
- // argv can't be NULL if argc > 0
- ret = callFunction(fn, 1, NULL, (char **)1, NULL);
- assert(ret < 0);
-
- // result can't be NULL
- ret = callFunction(fn, 0, NULL, NULL, NULL);
- assert(ret < 0);
-
- /* Set up some arguments.
- */
- int argc = 4;
- const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
-
- /* Make a call and make sure that it occurred.
- */
- char *functionResult;
- size_t functionResultLen;
- fn = findFunction("one");
- assert(fn != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 25;
- gTestCommandState.functionResult = "1234";
- gTestCommandState.permissions = (PermissionRequestList *)1;
- functionResult = NULL;
- functionResultLen = 55;
- ret = callFunction(fn, argc, argv,
- &functionResult, &functionResultLen);
-//xxx also try calling with a null resultLen arg (should succeed)
-//xxx also try calling with a null argv element (should fail)
- assert(ret == 25);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "one") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == argc);
- assert(gTestCommandState.argv == argv);
- assert(gTestCommandState.permissions == NULL);
- assert(strcmp(functionResult, "1234") == 0);
- assert(functionResultLen == strlen(functionResult));
-
- /* Try looking up permissions.
- */
- PermissionRequestList permissions;
- fn = findFunction("one");
- assert(fn != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 27;
- gTestCommandState.permissions = (PermissionRequestList *)1;
- argv[1] = NULL; // null out an arg, which should be ok
- ret = getFunctionPermissions(fn, argc, argv, &permissions);
- assert(ret == 27);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "one") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == argc);
- assert(gTestCommandState.argv == argv);
- assert(gTestCommandState.permissions == &permissions);
-
- /* Smoke test commandCleanup().
- */
- commandCleanup();
-
- return 0;
-}
-
-static int
-test_interaction()
-{
- Command *cmd;
- Function *fn;
- int ret;
-
- ret = commandInit();
- assert(ret == 0);
-
- /* Register some commands.
- */
- ret = registerCommand("one", CMD_ARGS_WORDS, testCommand, (void *)0xc1);
- assert(ret == 0);
-
- ret = registerCommand("two", CMD_ARGS_WORDS, testCommand, (void *)0xc2);
- assert(ret == 0);
-
- /* Register some functions, one of which shares a name with a command.
- */
- ret = registerFunction("one", testFunction, (void *)0xf1);
- assert(ret == 0);
-
- ret = registerFunction("three", testFunction, (void *)0xf3);
- assert(ret == 0);
-
- /* Look up each of the commands, and make sure no command exists
- * with the name used only by our function.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
-
- cmd = findCommand("two");
- assert(cmd != NULL);
-
- cmd = findCommand("three");
- assert(cmd == NULL);
-
- /* Look up each of the functions, and make sure no function exists
- * with the name used only by our command.
- */
- fn = findFunction("one");
- assert(fn != NULL);
-
- fn = findFunction("two");
- assert(fn == NULL);
-
- fn = findFunction("three");
- assert(fn != NULL);
-
- /* Set up some arguments.
- */
- int argc = 4;
- const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
-
- /* Call the overlapping command and make sure that the cookie is correct.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 123;
- gTestCommandState.permissions = (PermissionRequestList *)1;
- ret = callCommand(cmd, argc, argv);
- assert(ret == 123);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "one") == 0);
- assert((int)gTestCommandState.cookie == 0xc1);
- assert(gTestCommandState.argc == argc);
- assert(gTestCommandState.argv == argv);
- assert(gTestCommandState.permissions == NULL);
-
- /* Call the overlapping function and make sure that the cookie is correct.
- */
- char *functionResult;
- size_t functionResultLen;
- fn = findFunction("one");
- assert(fn != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 125;
- gTestCommandState.functionResult = "5678";
- gTestCommandState.permissions = (PermissionRequestList *)2;
- functionResult = NULL;
- functionResultLen = 66;
- ret = callFunction(fn, argc, argv, &functionResult, &functionResultLen);
- assert(ret == 125);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "one") == 0);
- assert((int)gTestCommandState.cookie == 0xf1);
- assert(gTestCommandState.argc == argc);
- assert(gTestCommandState.argv == argv);
- assert(gTestCommandState.permissions == NULL);
- assert(strcmp(functionResult, "5678") == 0);
- assert(functionResultLen == strlen(functionResult));
-
- /* Clean up.
- */
- commandCleanup();
-
- return 0;
-}
-
-int
-test_cmd_fn()
-{
- int ret;
-
- ret = test_commands();
- if (ret != 0) {
- fprintf(stderr, "test_commands() failed: %d\n", ret);
- return ret;
- }
-
- ret = test_functions();
- if (ret != 0) {
- fprintf(stderr, "test_functions() failed: %d\n", ret);
- return ret;
- }
-
- ret = test_interaction();
- if (ret != 0) {
- fprintf(stderr, "test_interaction() failed: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
diff --git a/amend/test_permissions.c b/amend/test_permissions.c
deleted file mode 100644
index c389456..0000000
--- a/amend/test_permissions.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#undef NDEBUG
-#include <assert.h>
-#include "permissions.h"
-
-static int
-test_permission_list()
-{
- PermissionRequestList list;
- int ret;
- int numRequests;
-
- /* Bad parameter
- */
- ret = initPermissionRequestList(NULL);
- assert(ret < 0);
-
- /* Good parameter
- */
- ret = initPermissionRequestList(&list);
- assert(ret == 0);
-
- /* Bad parameters
- */
- ret = addPermissionRequestToList(NULL, NULL, false, 0);
- assert(ret < 0);
-
- ret = addPermissionRequestToList(&list, NULL, false, 0);
- assert(ret < 0);
-
- /* Good parameters
- */
- numRequests = 0;
-
- ret = addPermissionRequestToList(&list, "one", false, 1);
- assert(ret == 0);
- numRequests++;
-
- ret = addPermissionRequestToList(&list, "two", false, 2);
- assert(ret == 0);
- numRequests++;
-
- ret = addPermissionRequestToList(&list, "three", false, 3);
- assert(ret == 0);
- numRequests++;
-
- ret = addPermissionRequestToList(&list, "recursive", true, 55);
- assert(ret == 0);
- numRequests++;
-
- /* Validate the list
- */
- assert(list.requests != NULL);
- assert(list.numRequests == numRequests);
- assert(list.numRequests <= list.requestsAllocated);
- bool sawOne = false;
- bool sawTwo = false;
- bool sawThree = false;
- bool sawRecursive = false;
- int i;
- for (i = 0; i < list.numRequests; i++) {
- PermissionRequest *req = &list.requests[i];
- assert(req->allowed == 0);
-
- /* Order isn't guaranteed, so we have to switch every time.
- */
- if (strcmp(req->path, "one") == 0) {
- assert(!sawOne);
- assert(req->requested == 1);
- assert(!req->recursive);
- sawOne = true;
- } else if (strcmp(req->path, "two") == 0) {
- assert(!sawTwo);
- assert(req->requested == 2);
- assert(!req->recursive);
- sawTwo = true;
- } else if (strcmp(req->path, "three") == 0) {
- assert(!sawThree);
- assert(req->requested == 3);
- assert(!req->recursive);
- sawThree = true;
- } else if (strcmp(req->path, "recursive") == 0) {
- assert(!sawRecursive);
- assert(req->requested == 55);
- assert(req->recursive);
- sawRecursive = true;
- } else {
- assert(false);
- }
- }
- assert(sawOne);
- assert(sawTwo);
- assert(sawThree);
- assert(sawRecursive);
-
- /* Smoke test the teardown
- */
- freePermissionRequestListElements(&list);
-
- return 0;
-}
-
-static int
-test_permission_table()
-{
- int ret;
-
- /* Test the global permissions table.
- * Try calling functions without initializing first.
- */
- ret = registerPermissionSet(0, NULL);
- assert(ret < 0);
-
- ret = countPermissionConflicts((PermissionRequestList *)16, false);
- assert(ret < 0);
-
- ret = getPermissionCount();
- assert(ret < 0);
-
- const Permission *p;
- p = getPermissionAt(0);
- assert(p == NULL);
-
- /* Initialize.
- */
- ret = permissionInit();
- assert(ret == 0);
-
- /* Make sure we can't initialize twice.
- */
- ret = permissionInit();
- assert(ret < 0);
-
- /* Test the inspection functions.
- */
- ret = getPermissionCount();
- assert(ret == 0);
-
- p = getPermissionAt(-1);
- assert(p == NULL);
-
- p = getPermissionAt(0);
- assert(p == NULL);
-
- p = getPermissionAt(1);
- assert(p == NULL);
-
- /* Test registerPermissionSet().
- * Try some bad parameter values.
- */
- ret = registerPermissionSet(-1, NULL);
- assert(ret < 0);
-
- ret = registerPermissionSet(1, NULL);
- assert(ret < 0);
-
- /* Register some permissions.
- */
- Permission p1;
- p1.path = "one";
- p1.allowed = 1;
- ret = registerPermissionSet(1, &p1);
- assert(ret == 0);
- ret = getPermissionCount();
- assert(ret == 1);
-
- Permission p2[2];
- p2[0].path = "two";
- p2[0].allowed = 2;
- p2[1].path = "three";
- p2[1].allowed = 3;
- ret = registerPermissionSet(2, p2);
- assert(ret == 0);
- ret = getPermissionCount();
- assert(ret == 3);
-
- ret = registerPermissionSet(0, NULL);
- assert(ret == 0);
- ret = getPermissionCount();
- assert(ret == 3);
-
- p1.path = "four";
- p1.allowed = 4;
- ret = registerPermissionSet(1, &p1);
- assert(ret == 0);
-
- /* Make sure the table looks correct.
- * Order is important; more-recent additions
- * should appear at higher indices.
- */
- ret = getPermissionCount();
- assert(ret == 4);
-
- int i;
- for (i = 0; i < ret; i++) {
- const Permission *p;
- p = getPermissionAt(i);
- assert(p != NULL);
- assert(p->allowed == (unsigned int)(i + 1));
- switch (i) {
- case 0:
- assert(strcmp(p->path, "one") == 0);
- break;
- case 1:
- assert(strcmp(p->path, "two") == 0);
- break;
- case 2:
- assert(strcmp(p->path, "three") == 0);
- break;
- case 3:
- assert(strcmp(p->path, "four") == 0);
- break;
- default:
- assert(!"internal error");
- break;
- }
- }
- p = getPermissionAt(ret);
- assert(p == NULL);
-
- /* Smoke test the teardown
- */
- permissionCleanup();
-
- return 0;
-}
-
-static int
-test_allowed_permissions()
-{
- int ret;
- int numPerms;
-
- /* Make sure these fail before initialization.
- */
- ret = countPermissionConflicts((PermissionRequestList *)1, false);
- assert(ret < 0);
-
- ret = getAllowedPermissions((const char *)1, false, (unsigned int *)1);
- assert(ret < 0);
-
- /* Initialize.
- */
- ret = permissionInit();
- assert(ret == 0);
-
- /* Make sure countPermissionConflicts() fails with bad parameters.
- */
- ret = countPermissionConflicts(NULL, false);
- assert(ret < 0);
-
- /* Register a set of permissions.
- */
- Permission perms[] = {
- { "/", PERM_NONE },
- { "/stat", PERM_STAT },
- { "/read", PERMSET_READ },
- { "/write", PERMSET_WRITE },
- { "/.stat", PERM_STAT },
- { "/.stat/.read", PERMSET_READ },
- { "/.stat/.read/.write", PERMSET_WRITE },
- { "/.stat/.write", PERMSET_WRITE },
- };
- numPerms = sizeof(perms) / sizeof(perms[0]);
- ret = registerPermissionSet(numPerms, perms);
- assert(ret == 0);
-
- /* Build a permission request list.
- */
- PermissionRequestList list;
- ret = initPermissionRequestList(&list);
- assert(ret == 0);
-
- ret = addPermissionRequestToList(&list, "/stat", false, PERM_STAT);
- assert(ret == 0);
-
- ret = addPermissionRequestToList(&list, "/read", false, PERM_READ);
- assert(ret == 0);
-
- ret = addPermissionRequestToList(&list, "/write", false, PERM_WRITE);
- assert(ret == 0);
-
- //TODO: cover more cases once the permission stuff has been implemented
-
- /* All of the requests in the list should be allowed.
- */
- ret = countPermissionConflicts(&list, false);
- assert(ret == 0);
-
- /* Add a request that will be denied.
- */
- ret = addPermissionRequestToList(&list, "/stat", false, 1<<31 | PERM_STAT);
- assert(ret == 0);
-
- ret = countPermissionConflicts(&list, false);
- assert(ret == 1);
-
- //TODO: more tests
-
- permissionCleanup();
-
- return 0;
-}
-
-int
-test_permissions()
-{
- int ret;
-
- ret = test_permission_list();
- if (ret != 0) {
- fprintf(stderr, "test_permission_list() failed: %d\n", ret);
- return ret;
- }
-
- ret = test_permission_table();
- if (ret != 0) {
- fprintf(stderr, "test_permission_table() failed: %d\n", ret);
- return ret;
- }
-
- ret = test_allowed_permissions();
- if (ret != 0) {
- fprintf(stderr, "test_permission_table() failed: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
diff --git a/amend/test_symtab.c b/amend/test_symtab.c
deleted file mode 100644
index 017d18c..0000000
--- a/amend/test_symtab.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#undef NDEBUG
-#include <assert.h>
-#include "symtab.h"
-
-int
-test_symtab()
-{
- SymbolTable *tab;
- void *cookie;
- int ret;
-
- /* Test creation */
- tab = createSymbolTable();
- assert(tab != NULL);
-
- /* Smoke-test deletion */
- deleteSymbolTable(tab);
-
-
- tab = createSymbolTable();
- assert(tab != NULL);
-
-
- /* table parameter must be non-NULL. */
- ret = addToSymbolTable(NULL, NULL, 0, NULL);
- assert(ret < 0);
-
- /* symbol parameter must be non-NULL. */
- ret = addToSymbolTable(tab, NULL, 0, NULL);
- assert(ret < 0);
-
- /* cookie parameter must be non-NULL. */
- ret = addToSymbolTable(tab, "null", 0, NULL);
- assert(ret < 0);
-
-
- /* table parameter must be non-NULL. */
- cookie = findInSymbolTable(NULL, NULL, 0);
- assert(cookie == NULL);
-
- /* symbol parameter must be non-NULL. */
- cookie = findInSymbolTable(tab, NULL, 0);
- assert(cookie == NULL);
-
-
- /* Try some actual inserts.
- */
- ret = addToSymbolTable(tab, "one", 0, (void *)1);
- assert(ret == 0);
-
- ret = addToSymbolTable(tab, "two", 0, (void *)2);
- assert(ret == 0);
-
- ret = addToSymbolTable(tab, "three", 0, (void *)3);
- assert(ret == 0);
-
- /* Try some lookups.
- */
- cookie = findInSymbolTable(tab, "one", 0);
- assert((int)cookie == 1);
-
- cookie = findInSymbolTable(tab, "two", 0);
- assert((int)cookie == 2);
-
- cookie = findInSymbolTable(tab, "three", 0);
- assert((int)cookie == 3);
-
- /* Try to insert something that's already there.
- */
- ret = addToSymbolTable(tab, "one", 0, (void *)1111);
- assert(ret < 0);
-
- /* Make sure that the failed duplicate insert didn't
- * clobber the original cookie value.
- */
- cookie = findInSymbolTable(tab, "one", 0);
- assert((int)cookie == 1);
-
- /* Try looking up something that isn't there.
- */
- cookie = findInSymbolTable(tab, "FOUR", 0);
- assert(cookie == NULL);
-
- /* Try looking up something that's similar to an existing entry.
- */
- cookie = findInSymbolTable(tab, "on", 0);
- assert(cookie == NULL);
-
- cookie = findInSymbolTable(tab, "onee", 0);
- assert(cookie == NULL);
-
- /* Test flags.
- * Try inserting something with a different flag.
- */
- ret = addToSymbolTable(tab, "ten", 333, (void *)10);
- assert(ret == 0);
-
- /* Make sure it's there.
- */
- cookie = findInSymbolTable(tab, "ten", 333);
- assert((int)cookie == 10);
-
- /* Make sure it's not there when looked up with a different flag.
- */
- cookie = findInSymbolTable(tab, "ten", 0);
- assert(cookie == NULL);
-
- /* Try inserting something that has the same name as something
- * with a different flag.
- */
- ret = addToSymbolTable(tab, "one", 333, (void *)11);
- assert(ret == 0);
-
- /* Make sure the new entry exists.
- */
- cookie = findInSymbolTable(tab, "one", 333);
- assert((int)cookie == 11);
-
- /* Make sure the old entry still has the right value.
- */
- cookie = findInSymbolTable(tab, "one", 0);
- assert((int)cookie == 1);
-
- /* Try deleting again, now that there's stuff in the table.
- */
- deleteSymbolTable(tab);
-
- return 0;
-}
diff --git a/amend/tests/001-nop/expected.txt b/amend/tests/001-nop/expected.txt
deleted file mode 100644
index d4a85ce..0000000
--- a/amend/tests/001-nop/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-I am a jelly donut.
diff --git a/amend/tests/001-nop/info.txt b/amend/tests/001-nop/info.txt
deleted file mode 100644
index 9942f10..0000000
--- a/amend/tests/001-nop/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This is a sample no-op test, which does at least serve to verify that the
-test harness is working.
diff --git a/amend/tests/001-nop/run b/amend/tests/001-nop/run
deleted file mode 100644
index 51637c1..0000000
--- a/amend/tests/001-nop/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-echo 'I am a jelly donut.'
diff --git a/amend/tests/002-lex-empty/SKIP b/amend/tests/002-lex-empty/SKIP
deleted file mode 100644
index e69de29..0000000
--- a/amend/tests/002-lex-empty/SKIP
+++ /dev/null
diff --git a/amend/tests/002-lex-empty/expected.txt b/amend/tests/002-lex-empty/expected.txt
deleted file mode 100644
index 822a54c..0000000
--- a/amend/tests/002-lex-empty/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
- EOF
diff --git a/amend/tests/002-lex-empty/info.txt b/amend/tests/002-lex-empty/info.txt
deleted file mode 100644
index 090083f..0000000
--- a/amend/tests/002-lex-empty/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test to make sure that an empty file is accepted properly.
diff --git a/amend/tests/002-lex-empty/input b/amend/tests/002-lex-empty/input
deleted file mode 100644
index e69de29..0000000
--- a/amend/tests/002-lex-empty/input
+++ /dev/null
diff --git a/amend/tests/002-lex-empty/run b/amend/tests/002-lex-empty/run
deleted file mode 100644
index 35c4a4f..0000000
--- a/amend/tests/002-lex-empty/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-amend --debug-lex input
diff --git a/amend/tests/003-lex-command/expected.txt b/amend/tests/003-lex-command/expected.txt
deleted file mode 100644
index e40db0c..0000000
--- a/amend/tests/003-lex-command/expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
- IDENTIFIER<this_identifier_is_not_assert> EOL
- IDENTIFIER<NEITHER_IS_THIS_123> EOL
- IDENTIFIER<but_the_next_one_is> EOL
- IDENTIFIER<assert> EOL
- IDENTIFIER<next_one_is_not_an_identifier> EOL
-line 6: unexpected character at '1'
- EOF
-line 1: unexpected character at '"'
- EOF
-line 1: unexpected character at '='
- EOF
-line 1: unexpected character at '9'
- EOF
diff --git a/amend/tests/003-lex-command/info.txt b/amend/tests/003-lex-command/info.txt
deleted file mode 100644
index 9296648..0000000
--- a/amend/tests/003-lex-command/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test to make sure that simple command names are tokenized properly.
diff --git a/amend/tests/003-lex-command/input b/amend/tests/003-lex-command/input
deleted file mode 100644
index b9ef231..0000000
--- a/amend/tests/003-lex-command/input
+++ /dev/null
@@ -1,6 +0,0 @@
-this_identifier_is_not_assert
-NEITHER_IS_THIS_123
-but_the_next_one_is
-assert
-next_one_is_not_an_identifier
-12not_an_identifier
diff --git a/amend/tests/003-lex-command/input2 b/amend/tests/003-lex-command/input2
deleted file mode 100644
index eb5daf7..0000000
--- a/amend/tests/003-lex-command/input2
+++ /dev/null
@@ -1 +0,0 @@
-"quoted"
diff --git a/amend/tests/003-lex-command/input3 b/amend/tests/003-lex-command/input3
deleted file mode 100644
index f1c8738..0000000
--- a/amend/tests/003-lex-command/input3
+++ /dev/null
@@ -1 +0,0 @@
-==
diff --git a/amend/tests/003-lex-command/input4 b/amend/tests/003-lex-command/input4
deleted file mode 100644
index 3ad5abd..0000000
--- a/amend/tests/003-lex-command/input4
+++ /dev/null
@@ -1 +0,0 @@
-99
diff --git a/amend/tests/003-lex-command/run b/amend/tests/003-lex-command/run
deleted file mode 100644
index 2e21fab..0000000
--- a/amend/tests/003-lex-command/run
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-amend --debug-lex input
-amend --debug-lex input2
-amend --debug-lex input3
-amend --debug-lex input4
diff --git a/amend/tests/004-lex-comment/expected.txt b/amend/tests/004-lex-comment/expected.txt
deleted file mode 100644
index a728a5e..0000000
--- a/amend/tests/004-lex-comment/expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
- IDENTIFIER<comment_on_this_line> EOL
- IDENTIFIER<none_on_this_one> EOL
- EOL
- EOL
- EOF
diff --git a/amend/tests/004-lex-comment/info.txt b/amend/tests/004-lex-comment/info.txt
deleted file mode 100644
index 0691248..0000000
--- a/amend/tests/004-lex-comment/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test to make sure that comments are stripped out.
diff --git a/amend/tests/004-lex-comment/input b/amend/tests/004-lex-comment/input
deleted file mode 100644
index 6736c95..0000000
--- a/amend/tests/004-lex-comment/input
+++ /dev/null
@@ -1,4 +0,0 @@
-comment_on_this_line # this is a "comment" (with / a bunch) # \\ of stuff \
-none_on_this_one
-# beginning of line
- # preceded by whitespace
diff --git a/amend/tests/004-lex-comment/run b/amend/tests/004-lex-comment/run
deleted file mode 100644
index 35c4a4f..0000000
--- a/amend/tests/004-lex-comment/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-amend --debug-lex input
diff --git a/amend/tests/005-lex-quoted-string/expected.txt b/amend/tests/005-lex-quoted-string/expected.txt
deleted file mode 100644
index 9bb5ac4..0000000
--- a/amend/tests/005-lex-quoted-string/expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
- IDENTIFIER<test> WORD<string> EOL
- IDENTIFIER<test> WORD<string with spaces> EOL
- IDENTIFIER<test> WORD<string with "escaped" quotes> EOL
- IDENTIFIER<test> WORD<string with \escaped\ backslashes> EOL
- IDENTIFIER<test> WORD<string with # a comment character> EOL
- EOF
- EOL
- IDENTIFIER<test1>line 2: unterminated string at '
-'
- ??? <0>
- EOL
- IDENTIFIER<test1>line 2: illegal escape at '\n'
- ??? <0>
diff --git a/amend/tests/005-lex-quoted-string/info.txt b/amend/tests/005-lex-quoted-string/info.txt
deleted file mode 100644
index be458bd..0000000
--- a/amend/tests/005-lex-quoted-string/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test to make sure that quoted strings are tokenized properly.
diff --git a/amend/tests/005-lex-quoted-string/input b/amend/tests/005-lex-quoted-string/input
deleted file mode 100644
index 2b34bbc..0000000
--- a/amend/tests/005-lex-quoted-string/input
+++ /dev/null
@@ -1,5 +0,0 @@
-test "string"
-test "string with spaces"
-test "string with \"escaped\" quotes"
-test "string with \\escaped\\ backslashes"
-test "string with # a comment character"
diff --git a/amend/tests/005-lex-quoted-string/input2 b/amend/tests/005-lex-quoted-string/input2
deleted file mode 100644
index 09e6689..0000000
--- a/amend/tests/005-lex-quoted-string/input2
+++ /dev/null
@@ -1,2 +0,0 @@
-# This should fail
-test1 "unterminated string
diff --git a/amend/tests/005-lex-quoted-string/input3 b/amend/tests/005-lex-quoted-string/input3
deleted file mode 100644
index 02f3f85..0000000
--- a/amend/tests/005-lex-quoted-string/input3
+++ /dev/null
@@ -1,2 +0,0 @@
-# This should fail
-test1 "string with illegal escape \n in the middle"
diff --git a/amend/tests/005-lex-quoted-string/run b/amend/tests/005-lex-quoted-string/run
deleted file mode 100644
index 7b1292a..0000000
--- a/amend/tests/005-lex-quoted-string/run
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-amend --debug-lex input
-amend --debug-lex input2
-amend --debug-lex input3
diff --git a/amend/tests/006-lex-words/SKIP b/amend/tests/006-lex-words/SKIP
deleted file mode 100644
index e69de29..0000000
--- a/amend/tests/006-lex-words/SKIP
+++ /dev/null
diff --git a/amend/tests/006-lex-words/expected.txt b/amend/tests/006-lex-words/expected.txt
deleted file mode 100644
index a78a0b1..0000000
--- a/amend/tests/006-lex-words/expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
- IDENTIFIER<test> WORD<this> WORD<has> WORD<a> WORD<bunch> WORD<of> WORD<BARE> WORD<ALPHA> WORD<WORDS> EOL
- IDENTIFIER<test> WORD<12> WORD<this> WORD<has(some> WORD<)> WORD<ALPHANUMER1C> WORD<and> WORD<\\> WORD<whatever> WORD<characters> EOL
- IDENTIFIER<test> WORD<this> WORD<has> WORD<mixed> WORD<bare> WORD<and quoted> WORD<words> EOL
- IDENTIFIER<test> WORD<what> WORD<about> WORD<quotesin the middle?> EOL
- IDENTIFIER<test> WORD<"""shouldn't> WORD<be> WORD<a> WORD<quoted> WORD<string> EOL
- EOF
diff --git a/amend/tests/006-lex-words/info.txt b/amend/tests/006-lex-words/info.txt
deleted file mode 100644
index dd37016..0000000
--- a/amend/tests/006-lex-words/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test to make sure that argument words are tokenized properly.
diff --git a/amend/tests/006-lex-words/input b/amend/tests/006-lex-words/input
deleted file mode 100644
index a4de638..0000000
--- a/amend/tests/006-lex-words/input
+++ /dev/null
@@ -1,5 +0,0 @@
-test this has a bunch of BARE ALPHA WORDS
-test 12 this has(some ) ALPHANUMER1C and \\ whatever characters
-test this has mixed bare "and quoted" words
-test what about quotes"in the middle?"
-test \"\"\"shouldn't be a quoted string
diff --git a/amend/tests/006-lex-words/input2 b/amend/tests/006-lex-words/input2
deleted file mode 100644
index 09e6689..0000000
--- a/amend/tests/006-lex-words/input2
+++ /dev/null
@@ -1,2 +0,0 @@
-# This should fail
-test1 "unterminated string
diff --git a/amend/tests/006-lex-words/input3 b/amend/tests/006-lex-words/input3
deleted file mode 100644
index 02f3f85..0000000
--- a/amend/tests/006-lex-words/input3
+++ /dev/null
@@ -1,2 +0,0 @@
-# This should fail
-test1 "string with illegal escape \n in the middle"
diff --git a/amend/tests/006-lex-words/run b/amend/tests/006-lex-words/run
deleted file mode 100644
index 35c4a4f..0000000
--- a/amend/tests/006-lex-words/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-amend --debug-lex input
diff --git a/amend/tests/007-lex-real-script/expected.txt b/amend/tests/007-lex-real-script/expected.txt
deleted file mode 100644
index 012f62c..0000000
--- a/amend/tests/007-lex-real-script/expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
- IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<112345oldhashvalue1234123> EOL
- IDENTIFIER<mark> WORD<SYS:> WORD<dirty> EOL
- IDENTIFIER<copy_dir> WORD<PKG:android-files> WORD<SYS:> EOL
- IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<667890newhashvalue6678909> EOL
- IDENTIFIER<mark> WORD<SYS:> WORD<clean> EOL
- IDENTIFIER<done> EOL
- IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> , STRING<blah> ) == STRING<112345oldhashvalue1234123> EOL
- IDENTIFIER<assert> STRING<true> == STRING<false> EOL
- IDENTIFIER<assert> IDENTIFIER<one> ( STRING<abc> , IDENTIFIER<two> ( STRING<def> ) ) == STRING<five> EOL
- IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<667890newhashvalue6678909> || IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<667890newhashvalue6678909> EOL
- EOF
diff --git a/amend/tests/007-lex-real-script/info.txt b/amend/tests/007-lex-real-script/info.txt
deleted file mode 100644
index 5e321f5..0000000
--- a/amend/tests/007-lex-real-script/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-An input script similar to one that will actually be used in practice.
diff --git a/amend/tests/007-lex-real-script/input b/amend/tests/007-lex-real-script/input
deleted file mode 100644
index f3f1fd9..0000000
--- a/amend/tests/007-lex-real-script/input
+++ /dev/null
@@ -1,10 +0,0 @@
-assert hash_dir("SYS:") == "112345oldhashvalue1234123"
-mark SYS: dirty
-copy_dir "PKG:android-files" SYS:
-assert hash_dir("SYS:") == "667890newhashvalue6678909"
-mark SYS: clean
-done
-assert hash_dir("SYS:", "blah") == "112345oldhashvalue1234123"
-assert "true" == "false"
-assert one("abc", two("def")) == "five"
-assert hash_dir("SYS:") == "667890newhashvalue6678909" || hash_dir("SYS:") == "667890newhashvalue6678909"
diff --git a/amend/tests/007-lex-real-script/run b/amend/tests/007-lex-real-script/run
deleted file mode 100644
index 35c4a4f..0000000
--- a/amend/tests/007-lex-real-script/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-amend --debug-lex input
diff --git a/amend/tests/008-parse-real-script/expected.txt b/amend/tests/008-parse-real-script/expected.txt
deleted file mode 100644
index dabf6d4..0000000
--- a/amend/tests/008-parse-real-script/expected.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-command "assert" {
- STRING EQ {
- FUNCTION hash_dir (
- "SYS:"
- )
- "112345oldhashvalue1234123"
- }
-}
-command "mark" {
- "SYS:"
- "dirty"
-}
-command "copy_dir" {
- "PKG:android-files"
- "SYS:"
-}
-command "assert" {
- STRING EQ {
- FUNCTION hash_dir (
- "SYS:"
- )
- "667890newhashvalue6678909"
- }
-}
-command "mark" {
- "SYS:"
- "clean"
-}
-command "done" {
-}
-command "assert" {
- STRING EQ {
- FUNCTION hash_dir (
- "SYS:"
- "blah"
- )
- "112345oldhashvalue1234123"
- }
-}
-command "assert" {
- STRING EQ {
- "true"
- "false"
- }
-}
-command "assert" {
- STRING NE {
- FUNCTION matches (
- FUNCTION hash_dir (
- "SYS:"
- )
- "667890newhashvalue6678909"
- "999999newhashvalue6678909"
- )
- ""
- }
-}
-command "assert" {
- BOOLEAN OR {
- STRING EQ {
- FUNCTION hash_dir (
- "SYS:"
- )
- "667890newhashvalue6678909"
- }
- STRING EQ {
- FUNCTION hash_dir (
- "SYS:"
- )
- "999999newhashvalue6678909"
- }
- }
-}
-amend: Parse successful.
diff --git a/amend/tests/008-parse-real-script/info.txt b/amend/tests/008-parse-real-script/info.txt
deleted file mode 100644
index 5e321f5..0000000
--- a/amend/tests/008-parse-real-script/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-An input script similar to one that will actually be used in practice.
diff --git a/amend/tests/008-parse-real-script/input b/amend/tests/008-parse-real-script/input
deleted file mode 100644
index b073306..0000000
--- a/amend/tests/008-parse-real-script/input
+++ /dev/null
@@ -1,10 +0,0 @@
-assert hash_dir("SYS:") == "112345oldhashvalue1234123"
-mark SYS: dirty
-copy_dir "PKG:android-files" SYS:
-assert hash_dir("SYS:") == "667890newhashvalue6678909"
-mark SYS: clean
-done
-assert hash_dir("SYS:", "blah") == "112345oldhashvalue1234123"
-assert "true" == "false"
-assert matches(hash_dir("SYS:"), "667890newhashvalue6678909", "999999newhashvalue6678909") != ""
-assert hash_dir("SYS:") == "667890newhashvalue6678909" || hash_dir("SYS:") == "999999newhashvalue6678909"
diff --git a/amend/tests/008-parse-real-script/run b/amend/tests/008-parse-real-script/run
deleted file mode 100644
index 9544e1b..0000000
--- a/amend/tests/008-parse-real-script/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-amend --debug-ast input
diff --git a/amend/tests/XXX-long-token/SKIP b/amend/tests/XXX-long-token/SKIP
deleted file mode 100644
index e69de29..0000000
--- a/amend/tests/XXX-long-token/SKIP
+++ /dev/null
diff --git a/amend/tests/XXX-stack-overflow/SKIP b/amend/tests/XXX-stack-overflow/SKIP
deleted file mode 100644
index e69de29..0000000
--- a/amend/tests/XXX-stack-overflow/SKIP
+++ /dev/null
diff --git a/amend/tests/one-test b/amend/tests/one-test
deleted file mode 100755
index 9cebd3f..0000000
--- a/amend/tests/one-test
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-
-info="info.txt"
-run="run"
-expected="expected.txt"
-output="out.txt"
-skip="SKIP"
-
-dev_mode="no"
-if [ "x$1" = "x--dev" ]; then
- dev_mode="yes"
- shift
-fi
-
-update_mode="no"
-if [ "x$1" = "x--update" ]; then
- update_mode="yes"
- shift
-fi
-
-usage="no"
-if [ "x$1" = "x--help" ]; then
- usage="yes"
-else
- if [ "x$1" = "x" ]; then
- testdir=`basename "$oldwd"`
- else
- testdir="$1"
- fi
-
- if [ '!' -d "$testdir" ]; then
- td2=`echo ${testdir}-*`
- if [ '!' -d "$td2" ]; then
- echo "${testdir}: no such test directory" 1>&2
- usage="yes"
- fi
- testdir="$td2"
- fi
-fi
-
-if [ "$usage" = "yes" ]; then
- prog=`basename $prog`
- (
- echo "usage:"
- echo " $prog --help Print this message."
- echo " $prog testname Run test normally."
- echo " $prog --dev testname Development mode (dump to stdout)."
- echo " $prog --update testname Update mode (replace expected.txt)."
- echo " Omitting the test name uses the current directory as the test."
- ) 1>&2
- exit 1
-fi
-
-td_info="$testdir"/"$info"
-td_run="$testdir"/"$run"
-td_expected="$testdir"/"$expected"
-td_skip="$testdir"/"$skip"
-
-if [ -r "$td_skip" ]; then
- exit 2
-fi
-
-tmpdir=/tmp/test-$$
-
-if [ '!' '(' -r "$td_info" -a -r "$td_run" -a -r "$td_expected" ')' ]; then
- echo "${testdir}: missing files" 1>&2
- exit 1
-fi
-
-# copy the test to a temp dir and run it
-
-echo "${testdir}: running..." 1>&2
-
-rm -rf "$tmpdir"
-cp -Rp "$testdir" "$tmpdir"
-cd "$tmpdir"
-chmod 755 "$run"
-
-#PATH="${progdir}/../build/bin:${PATH}"
-
-good="no"
-if [ "$dev_mode" = "yes" ]; then
- "./$run" 2>&1
- echo "exit status: $?" 1>&2
- good="yes"
-elif [ "$update_mode" = "yes" ]; then
- "./$run" >"${progdir}/$td_expected" 2>&1
- good="yes"
-else
- "./$run" >"$output" 2>&1
- cmp -s "$expected" "$output"
- if [ "$?" = "0" ]; then
- # output == expected
- good="yes"
- echo "$testdir"': succeeded!' 1>&2
- fi
-fi
-
-if [ "$good" = "yes" ]; then
- cd "$oldwd"
- rm -rf "$tmpdir"
- exit 0
-fi
-
-(
- echo "${testdir}: FAILED!"
- echo ' '
- echo '#################### info'
- cat "$info" | sed 's/^/# /g'
- echo '#################### diffs'
- diff -u "$expected" "$output"
- echo '####################'
- echo ' '
- echo "files left in $tmpdir"
-) 1>&2
-
-exit 1
diff --git a/amend/tests/run-all-tests b/amend/tests/run-all-tests
deleted file mode 100755
index c696bbd..0000000
--- a/amend/tests/run-all-tests
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-
-passed=0
-skipped=0
-skipNames=""
-failed=0
-failNames=""
-
-for i in *; do
- if [ -d "$i" -a -r "$i" ]; then
- ./one-test "$i"
- status=$?
- if [ "$status" = "0" ]; then
- ((passed += 1))
- elif [ "$status" = "2" ]; then
- ((skipped += 1))
- skipNames="$skipNames $i"
- else
- ((failed += 1))
- failNames="$failNames $i"
- fi
- fi
-done
-
-echo "passed: $passed test(s)"
-echo "skipped: $skipped test(s)"
-
-for i in $skipNames; do
- echo "skipped: $i"
-done
-
-echo "failed: $failed test(s)"
-
-for i in $failNames; do
- echo "failed: $i"
-done
diff --git a/bootloader.c b/bootloader.c
deleted file mode 100644
index de441e1..0000000
--- a/bootloader.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "bootloader.h"
-#include "common.h"
-#include "mtdutils/mtdutils.h"
-#include "roots.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-
-static const char *CACHE_NAME = "CACHE:";
-static const char *MISC_NAME = "MISC:";
-static const int MISC_PAGES = 3; // number of pages to save
-static const int MISC_COMMAND_PAGE = 1; // bootloader command is this page
-
-#ifdef LOG_VERBOSE
-static void dump_data(const char *data, int len) {
- int pos;
- for (pos = 0; pos < len; ) {
- printf("%05x: %02x", pos, data[pos]);
- for (++pos; pos < len && (pos % 24) != 0; ++pos) {
- printf(" %02x", data[pos]);
- }
- printf("\n");
- }
-}
-#endif
-
-int get_bootloader_message(struct bootloader_message *out) {
- size_t write_size;
- const MtdPartition *part = get_root_mtd_partition(MISC_NAME);
- if (part == NULL || mtd_partition_info(part, NULL, NULL, &write_size)) {
- LOGE("Can't find %s\n", MISC_NAME);
- return -1;
- }
-
- MtdReadContext *read = mtd_read_partition(part);
- if (read == NULL) {
- LOGE("Can't open %s\n(%s)\n", MISC_NAME, strerror(errno));
- return -1;
- }
-
- const ssize_t size = write_size * MISC_PAGES;
- char data[size];
- ssize_t r = mtd_read_data(read, data, size);
- if (r != size) LOGE("Can't read %s\n(%s)\n", MISC_NAME, strerror(errno));
- mtd_read_close(read);
- if (r != size) return -1;
-
-#ifdef LOG_VERBOSE
- printf("\n--- get_bootloader_message ---\n");
- dump_data(data, size);
- printf("\n");
-#endif
-
- memcpy(out, &data[write_size * MISC_COMMAND_PAGE], sizeof(*out));
- return 0;
-}
-
-int set_bootloader_message(const struct bootloader_message *in) {
- size_t write_size;
- const MtdPartition *part = get_root_mtd_partition(MISC_NAME);
- if (part == NULL || mtd_partition_info(part, NULL, NULL, &write_size)) {
- LOGE("Can't find %s\n", MISC_NAME);
- return -1;
- }
-
- MtdReadContext *read = mtd_read_partition(part);
- if (read == NULL) {
- LOGE("Can't open %s\n(%s)\n", MISC_NAME, strerror(errno));
- return -1;
- }
-
- ssize_t size = write_size * MISC_PAGES;
- char data[size];
- ssize_t r = mtd_read_data(read, data, size);
- if (r != size) LOGE("Can't read %s\n(%s)\n", MISC_NAME, strerror(errno));
- mtd_read_close(read);
- if (r != size) return -1;
-
- memcpy(&data[write_size * MISC_COMMAND_PAGE], in, sizeof(*in));
-
-#ifdef LOG_VERBOSE
- printf("\n--- set_bootloader_message ---\n");
- dump_data(data, size);
- printf("\n");
-#endif
-
- MtdWriteContext *write = mtd_write_partition(part);
- if (write == NULL) {
- LOGE("Can't open %s\n(%s)\n", MISC_NAME, strerror(errno));
- return -1;
- }
- if (mtd_write_data(write, data, size) != size) {
- LOGE("Can't write %s\n(%s)\n", MISC_NAME, strerror(errno));
- mtd_write_close(write);
- return -1;
- }
- if (mtd_write_close(write)) {
- LOGE("Can't finish %s\n(%s)\n", MISC_NAME, strerror(errno));
- return -1;
- }
-
- LOGI("Set boot command \"%s\"\n", in->command[0] != 255 ? in->command : "");
- return 0;
-}
-
-/* Update Image
- *
- * - will be stored in the "cache" partition
- * - bad blocks will be ignored, like boot.img and recovery.img
- * - the first block will be the image header (described below)
- * - the size is in BYTES, inclusive of the header
- * - offsets are in BYTES from the start of the update header
- * - two raw bitmaps will be included, the "busy" and "fail" bitmaps
- * - for dream, the bitmaps will be 320x480x16bpp RGB565
- */
-
-#define UPDATE_MAGIC "MSM-RADIO-UPDATE"
-#define UPDATE_MAGIC_SIZE 16
-#define UPDATE_VERSION 0x00010000
-
-struct update_header {
- unsigned char MAGIC[UPDATE_MAGIC_SIZE];
-
- unsigned version;
- unsigned size;
-
- unsigned image_offset;
- unsigned image_length;
-
- unsigned bitmap_width;
- unsigned bitmap_height;
- unsigned bitmap_bpp;
-
- unsigned busy_bitmap_offset;
- unsigned busy_bitmap_length;
-
- unsigned fail_bitmap_offset;
- unsigned fail_bitmap_length;
-};
-
-int write_update_for_bootloader(
- const char *update, int update_length,
- int bitmap_width, int bitmap_height, int bitmap_bpp,
- const char *busy_bitmap, const char *fail_bitmap) {
- if (ensure_root_path_unmounted(CACHE_NAME)) {
- LOGE("Can't unmount %s\n", CACHE_NAME);
- return -1;
- }
-
- const MtdPartition *part = get_root_mtd_partition(CACHE_NAME);
- if (part == NULL) {
- LOGE("Can't find %s\n", CACHE_NAME);
- return -1;
- }
-
- MtdWriteContext *write = mtd_write_partition(part);
- if (write == NULL) {
- LOGE("Can't open %s\n(%s)\n", CACHE_NAME, strerror(errno));
- return -1;
- }
-
- /* Write an invalid (zero) header first, to disable any previous
- * update and any other structured contents (like a filesystem),
- * and as a placeholder for the amount of space required.
- */
-
- struct update_header header;
- memset(&header, 0, sizeof(header));
- const ssize_t header_size = sizeof(header);
- if (mtd_write_data(write, (char*) &header, header_size) != header_size) {
- LOGE("Can't write header to %s\n(%s)\n", CACHE_NAME, strerror(errno));
- mtd_write_close(write);
- return -1;
- }
-
- /* Write each section individually block-aligned, so we can write
- * each block independently without complicated buffering.
- */
-
- memcpy(&header.MAGIC, UPDATE_MAGIC, UPDATE_MAGIC_SIZE);
- header.version = UPDATE_VERSION;
- header.size = header_size;
-
- header.image_offset = mtd_erase_blocks(write, 0);
- header.image_length = update_length;
- if ((int) header.image_offset == -1 ||
- mtd_write_data(write, update, update_length) != update_length) {
- LOGE("Can't write update to %s\n(%s)\n", CACHE_NAME, strerror(errno));
- mtd_write_close(write);
- return -1;
- }
-
- header.bitmap_width = bitmap_width;
- header.bitmap_height = bitmap_height;
- header.bitmap_bpp = bitmap_bpp;
-
- int bitmap_length = (bitmap_bpp + 7) / 8 * bitmap_width * bitmap_height;
-
- header.busy_bitmap_offset = mtd_erase_blocks(write, 0);
- header.busy_bitmap_length = busy_bitmap != NULL ? bitmap_length : 0;
- if ((int) header.busy_bitmap_offset == -1 ||
- mtd_write_data(write, busy_bitmap, bitmap_length) != bitmap_length) {
- LOGE("Can't write bitmap to %s\n(%s)\n", CACHE_NAME, strerror(errno));
- mtd_write_close(write);
- return -1;
- }
-
- header.fail_bitmap_offset = mtd_erase_blocks(write, 0);
- header.fail_bitmap_length = fail_bitmap != NULL ? bitmap_length : 0;
- if ((int) header.fail_bitmap_offset == -1 ||
- mtd_write_data(write, fail_bitmap, bitmap_length) != bitmap_length) {
- LOGE("Can't write bitmap to %s\n(%s)\n", CACHE_NAME, strerror(errno));
- mtd_write_close(write);
- return -1;
- }
-
- /* Write the header last, after all the blocks it refers to, so that
- * when the magic number is installed everything is valid.
- */
-
- if (mtd_write_close(write)) {
- LOGE("Can't finish writing %s\n(%s)\n", CACHE_NAME, strerror(errno));
- return -1;
- }
-
- write = mtd_write_partition(part);
- if (write == NULL) {
- LOGE("Can't reopen %s\n(%s)\n", CACHE_NAME, strerror(errno));
- return -1;
- }
-
- if (mtd_write_data(write, (char*) &header, header_size) != header_size) {
- LOGE("Can't rewrite header to %s\n(%s)\n", CACHE_NAME, strerror(errno));
- mtd_write_close(write);
- return -1;
- }
-
- if (mtd_erase_blocks(write, 0) != (off_t) header.image_offset) {
- LOGE("Misalignment rewriting %s\n(%s)\n", CACHE_NAME, strerror(errno));
- mtd_write_close(write);
- return -1;
- }
-
- if (mtd_write_close(write)) {
- LOGE("Can't finish header of %s\n(%s)\n", CACHE_NAME, strerror(errno));
- return -1;
- }
-
- return 0;
-}
diff --git a/bootloader.h b/bootloader.h
deleted file mode 100644
index 3d4302f..0000000
--- a/bootloader.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _RECOVERY_BOOTLOADER_H
-#define _RECOVERY_BOOTLOADER_H
-
-/* Bootloader Message
- *
- * This structure describes the content of a block in flash
- * that is used for recovery and the bootloader to talk to
- * each other.
- *
- * The command field is updated by linux when it wants to
- * reboot into recovery or to update radio or bootloader firmware.
- * It is also updated by the bootloader when firmware update
- * is complete (to boot into recovery for any final cleanup)
- *
- * The status field is written by the bootloader after the
- * completion of an "update-radio" or "update-hboot" command.
- *
- * The recovery field is only written by linux and used
- * for the system to send a message to recovery or the
- * other way around.
- */
-struct bootloader_message {
- char command[32];
- char status[32];
- char recovery[1024];
-};
-
-/* Read and write the bootloader command from the "misc" partition.
- * These return zero on success.
- */
-int get_bootloader_message(struct bootloader_message *out);
-int set_bootloader_message(const struct bootloader_message *in);
-
-/* Write an update to the cache partition for update-radio or update-hboot.
- * Note, this destroys any filesystem on the cache partition!
- * The expected bitmap format is 240x320, 16bpp (2Bpp), RGB 5:6:5.
- */
-int write_update_for_bootloader(
- const char *update, int update_len,
- int bitmap_width, int bitmap_height, int bitmap_bpp,
- const char *busy_bitmap, const char *error_bitmap);
-
-#endif
diff --git a/commands.c b/commands.c
deleted file mode 100644
index 23ad91c..0000000
--- a/commands.c
+++ /dev/null
@@ -1,1148 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#undef NDEBUG
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <unistd.h>
-
-#include "amend/commands.h"
-#include "commands.h"
-#include "common.h"
-#include "cutils/misc.h"
-#include "cutils/properties.h"
-#include "firmware.h"
-#include "minzip/DirUtil.h"
-#include "minzip/Zip.h"
-#include "roots.h"
-
-static int gDidShowProgress = 0;
-
-#define UNUSED(p) ((void)(p))
-
-#define CHECK_BOOL() \
- do { \
- assert(argv == NULL); \
- if (argv != NULL) return -1; \
- assert(argc == true || argc == false); \
- if (argc != true && argc != false) return -1; \
- } while (false)
-
-#define CHECK_WORDS() \
- do { \
- assert(argc >= 0); \
- if (argc < 0) return -1; \
- assert(argc == 0 || argv != NULL); \
- if (argc != 0 && argv == NULL) return -1; \
- if (permissions != NULL) { \
- int CW_I_; \
- for (CW_I_ = 0; CW_I_ < argc; CW_I_++) { \
- assert(argv[CW_I_] != NULL); \
- if (argv[CW_I_] == NULL) return -1; \
- } \
- } \
- } while (false)
-
-#define CHECK_FN() \
- do { \
- CHECK_WORDS(); \
- if (permissions != NULL) { \
- assert(result == NULL); \
- if (result != NULL) return -1; \
- } else { \
- assert(result != NULL); \
- if (result == NULL) return -1; \
- } \
- } while (false)
-
-#define NO_PERMS(perms) \
- do { \
- PermissionRequestList *NP_PRL_ = (perms); \
- if (NP_PRL_ != NULL) { \
- int NP_RET_ = addPermissionRequestToList(NP_PRL_, \
- "", false, PERM_NONE); \
- if (NP_RET_ < 0) { \
- /* Returns from the calling function. \
- */ \
- return NP_RET_; \
- } \
- } \
- } while (false)
-
-/*
- * Command definitions
- */
-
-/* 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;
- }
-}
-
-/* format <root>
- */
-static int
-cmd_format(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc != 1) {
- LOGE("Command %s requires exactly one argument\n", name);
- return 1;
- }
- const char *root = argv[0];
- ui_print("Formatting %s...\n", root);
-
- int ret = format_root_device(root);
- if (ret != 0) {
- LOGE("Can't format %s\n", root);
- return 1;
- }
-
- return 0;
-}
-
-/* delete <file1> [<fileN> ...]
- * delete_recursive <file-or-dir1> [<file-or-dirN> ...]
- *
- * Like "rm -f", will try to delete every named file/dir, even if
- * earlier ones fail. Recursive deletes that fail halfway through
- * give up early.
- */
-static int
-cmd_delete(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(cookie);
- CHECK_WORDS();
- int nerr = 0;
- bool recurse;
-
- if (argc < 1) {
- LOGE("Command %s requires at least one argument\n", name);
- return 1;
- }
-
- recurse = (strcmp(name, "delete_recursive") == 0);
- ui_print("Deleting files...\n");
-//xxx permissions
-
- int i;
- for (i = 0; i < argc; i++) {
- const char *root_path = argv[i];
- char pathbuf[PATH_MAX];
- const char *path;
-
- /* This guarantees that all paths use "SYSTEM:"-style roots;
- * plain paths won't make it through translate_root_path().
- */
- path = translate_root_path(root_path, pathbuf, sizeof(pathbuf));
- if (path != NULL) {
- int ret = ensure_root_path_mounted(root_path);
- if (ret < 0) {
- LOGW("Can't mount volume to delete \"%s\"\n", root_path);
- nerr++;
- continue;
- }
- if (recurse) {
- ret = dirUnlinkHierarchy(path);
- } else {
- ret = unlink(path);
- }
- if (ret != 0 && errno != ENOENT) {
- LOGW("Can't delete %s\n(%s)\n", path, strerror(errno));
- nerr++;
- }
- } else {
- nerr++;
- }
- }
-//TODO: add a way to fail if a delete didn't work
-
- return 0;
-}
-
-typedef struct {
- int num_done;
- int num_total;
-} ExtractContext;
-
-static void extract_count_cb(const char *fn, void *cookie)
-{
- ++((ExtractContext*) cookie)->num_total;
-}
-
-static void extract_cb(const char *fn, void *cookie)
-{
- // minzip writes the filename to the log, so we don't need to
- ExtractContext *ctx = (ExtractContext*) cookie;
- ui_set_progress((float) ++ctx->num_done / ctx->num_total);
-}
-
-/* copy_dir <src-dir> <dst-dir> [<timestamp>]
- *
- * The contents of <src-dir> will become the contents of <dst-dir>.
- * The original contents of <dst-dir> are preserved unless something
- * in <src-dir> overwrote them.
- *
- * e.g., for "copy_dir PKG:system SYSTEM:", the file "PKG:system/a"
- * would be copied to "SYSTEM:a".
- *
- * The specified timestamp (in decimal seconds since 1970) will be used,
- * or a fixed default timestamp will be supplied otherwise.
- */
-static int
-cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx permissions
-
- // To create a consistent system image, never use the clock for timestamps.
- struct utimbuf timestamp = { 1217592000, 1217592000 }; // 8/1/2008 default
- if (argc == 3) {
- char *end;
- time_t value = strtoul(argv[2], &end, 0);
- if (value == 0 || end[0] != '\0') {
- LOGE("Command %s: invalid timestamp \"%s\"\n", name, argv[2]);
- return 1;
- } else if (value < timestamp.modtime) {
- LOGE("Command %s: timestamp \"%s\" too early\n", name, argv[2]);
- return 1;
- }
- timestamp.modtime = timestamp.actime = value;
- } else if (argc != 2) {
- LOGE("Command %s requires exactly two arguments\n", name);
- return 1;
- }
-
- // Use 40% of the progress bar (80% post-verification) by default
- ui_print("Copying files...\n");
- if (!gDidShowProgress) ui_show_progress(DEFAULT_FILES_PROGRESS_FRACTION, 0);
-
- /* Mount the destination volume if it isn't already.
- */
- const char *dst_root_path = argv[1];
- int ret = ensure_root_path_mounted(dst_root_path);
- if (ret < 0) {
- LOGE("Can't mount %s\n", dst_root_path);
- return 1;
- }
-
- /* Get the real target path.
- */
- char dstpathbuf[PATH_MAX];
- const char *dst_path;
- dst_path = translate_root_path(dst_root_path,
- dstpathbuf, sizeof(dstpathbuf));
- if (dst_path == NULL) {
- LOGE("Command %s: bad destination path \"%s\"\n", name, dst_root_path);
- return 1;
- }
-
- /* Try to copy the directory. The source may be inside a package.
- */
- const char *src_root_path = argv[0];
- char srcpathbuf[PATH_MAX];
- const char *src_path;
- if (is_package_root_path(src_root_path)) {
- const ZipArchive *package;
- src_path = translate_package_root_path(src_root_path,
- srcpathbuf, sizeof(srcpathbuf), &package);
- if (src_path == NULL) {
- LOGE("Command %s: bad source path \"%s\"\n", name, src_root_path);
- return 1;
- }
-
- /* Extract the files. Set MZ_EXTRACT_FILES_ONLY, because only files
- * are validated by the signature. Do a dry run first to count how
- * many there are (and find some errors early).
- */
- ExtractContext ctx;
- ctx.num_done = 0;
- ctx.num_total = 0;
-
- if (!mzExtractRecursive(package, src_path, dst_path,
- MZ_EXTRACT_FILES_ONLY | MZ_EXTRACT_DRY_RUN,
- ×tamp, extract_count_cb, (void *) &ctx) ||
- !mzExtractRecursive(package, src_path, dst_path,
- MZ_EXTRACT_FILES_ONLY,
- ×tamp, extract_cb, (void *) &ctx)) {
- LOGW("Command %s: couldn't extract \"%s\" to \"%s\"\n",
- name, src_root_path, dst_root_path);
- return 1;
- }
- } else {
- LOGE("Command %s: non-package source path \"%s\" not yet supported\n",
- name, src_root_path);
-//xxx mount the src volume
-//xxx
- return 255;
- }
-
- return 0;
-}
-
-/* run_program <program-file> [<args> ...]
- *
- * Run an external program included in the update package.
- */
-static int
-cmd_run_program(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc < 1) {
- LOGE("Command %s requires at least one argument\n", name);
- return 1;
- }
-
- // Copy the program file to temporary storage.
- if (!is_package_root_path(argv[0])) {
- LOGE("Command %s: non-package program file \"%s\" not supported\n",
- name, argv[0]);
- return 1;
- }
-
- char path[PATH_MAX];
- const ZipArchive *package;
- if (!translate_package_root_path(argv[0], path, sizeof(path), &package)) {
- LOGE("Command %s: bad source path \"%s\"\n", name, argv[0]);
- return 1;
- }
-
- const ZipEntry *entry = mzFindZipEntry(package, path);
- if (entry == NULL) {
- LOGE("Can't find %s\n", path);
- return 1;
- }
-
- static const char *binary = "/tmp/run_program_binary";
- unlink(binary); // just to be sure
- int fd = creat(binary, 0755);
- if (fd < 0) {
- LOGE("Can't make %s\n", binary);
- return 1;
- }
- bool ok = mzExtractZipEntryToFile(package, entry, fd);
- close(fd);
-
- if (!ok) {
- LOGE("Can't copy %s\n", path);
- return 1;
- }
-
- // Create a copy of argv to NULL-terminate it, as execv requires
- char **args = (char **) malloc(sizeof(char*) * (argc + 1));
- memcpy(args, argv, sizeof(char*) * argc);
- args[argc] = NULL;
-
- pid_t pid = fork();
- if (pid == 0) {
- execv(binary, args);
- fprintf(stderr, "E:Can't run %s\n(%s)\n", binary, strerror(errno));
- _exit(-1);
- }
-
- int status;
- waitpid(pid, &status, 0);
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- return 0;
- } else {
- LOGE("Error in %s\n(Status %d)\n", path, status);
- return 1;
- }
-}
-
-/* set_perm <uid> <gid> <mode> <path> [... <pathN>]
- * set_perm_recursive <uid> <gid> <dir-mode> <file-mode> <path> [... <pathN>]
- *
- * Like "chmod", "chown" and "chgrp" all in one, set ownership and permissions
- * of single files or entire directory trees. Any error causes failure.
- * User, group, and modes must all be integer values (hex or octal OK).
- */
-static int
-cmd_set_perm(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(cookie);
- CHECK_WORDS();
- bool recurse = !strcmp(name, "set_perm_recursive");
-
- int min_args = 4 + (recurse ? 1 : 0);
- if (argc < min_args) {
- LOGE("Command %s requires at least %d args\n", name, min_args);
- return 1;
- }
-
- // All the arguments except the path(s) are numeric.
- int i, n[min_args - 1];
- for (i = 0; i < min_args - 1; ++i) {
- char *end;
- n[i] = strtoul(argv[i], &end, 0);
- if (end[0] != '\0' || argv[i][0] == '\0') {
- LOGE("Command %s: invalid argument \"%s\"\n", name, argv[i]);
- return 1;
- }
- }
-
- for (i = min_args - 1; i < min_args; ++i) {
- char path[PATH_MAX];
- if (translate_root_path(argv[i], path, sizeof(path)) == NULL) {
- LOGE("Command %s: bad path \"%s\"\n", name, argv[i]);
- return 1;
- }
-
- if (ensure_root_path_mounted(argv[i])) {
- LOGE("Can't mount %s\n", argv[i]);
- return 1;
- }
-
- if (recurse
- ? dirSetHierarchyPermissions(path, n[0], n[1], n[2], n[3])
- : (chown(path, n[0], n[1]) || chmod(path, n[2]))) {
- LOGE("Can't chown/mod %s\n(%s)\n", path, strerror(errno));
- return 1;
- }
- }
-
- return 0;
-}
-
-/* show_progress <fraction> <duration>
- *
- * Use <fraction> of the on-screen progress meter for the next operation,
- * automatically advancing the meter over <duration> seconds (or more rapidly
- * if the actual rate of progress can be determined).
- */
-static int
-cmd_show_progress(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc != 2) {
- LOGE("Command %s requires exactly two arguments\n", name);
- return 1;
- }
-
- char *end;
- double fraction = strtod(argv[0], &end);
- if (end[0] != '\0' || argv[0][0] == '\0' || fraction < 0 || fraction > 1) {
- LOGE("Command %s: invalid fraction \"%s\"\n", name, argv[0]);
- return 1;
- }
-
- int duration = strtoul(argv[1], &end, 0);
- if (end[0] != '\0' || argv[0][0] == '\0') {
- LOGE("Command %s: invalid duration \"%s\"\n", name, argv[1]);
- return 1;
- }
-
- // Half of the progress bar is taken by verification,
- // so everything that happens during installation is scaled.
- ui_show_progress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), duration);
- gDidShowProgress = 1;
- return 0;
-}
-
-/* symlink <link-target> <link-path>
- *
- * Create a symlink, like "ln -s". The link path must not exist already.
- * Note that <link-path> is in root:path format, but <link-target> is
- * for the target filesystem (and may be relative).
- */
-static int
-cmd_symlink(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc != 2) {
- LOGE("Command %s requires exactly two arguments\n", name);
- return 1;
- }
-
- char path[PATH_MAX];
- if (translate_root_path(argv[1], path, sizeof(path)) == NULL) {
- LOGE("Command %s: bad path \"%s\"\n", name, argv[1]);
- return 1;
- }
-
- if (ensure_root_path_mounted(argv[1])) {
- LOGE("Can't mount %s\n", argv[1]);
- return 1;
- }
-
- if (symlink(argv[0], path)) {
- LOGE("Can't symlink %s\n", path);
- return 1;
- }
-
- return 0;
-}
-
-struct FirmwareContext {
- size_t total_bytes, done_bytes;
- char *data;
-};
-
-static bool firmware_fn(const unsigned char *data, int data_len, void *cookie)
-{
- struct FirmwareContext *context = (struct FirmwareContext*) cookie;
- if (context->done_bytes + data_len > context->total_bytes) {
- LOGE("Data overrun in firmware\n");
- return false; // Should not happen, but let's be safe.
- }
-
- memcpy(context->data + context->done_bytes, data, data_len);
- context->done_bytes += data_len;
- ui_set_progress(context->done_bytes * 1.0 / context->total_bytes);
- return true;
-}
-
-/* write_radio_image <src-image>
- * write_hboot_image <src-image>
- * Doesn't actually take effect until the rest of installation finishes.
- */
-static int
-cmd_write_firmware_image(const char *name, void *cookie,
- int argc, const char *argv[], PermissionRequestList *permissions)
-{
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc != 1) {
- LOGE("Command %s requires exactly one argument\n", name);
- return 1;
- }
-
- const char *type;
- if (!strcmp(name, "write_radio_image")) {
- type = "radio";
- } else if (!strcmp(name, "write_hboot_image")) {
- type = "hboot";
- } else {
- LOGE("Unknown firmware update command %s\n", name);
- return 1;
- }
-
- if (!is_package_root_path(argv[0])) {
- LOGE("Command %s: non-package image file \"%s\" not supported\n",
- name, argv[0]);
- return 1;
- }
-
- ui_print("Extracting %s image...\n", type);
- char path[PATH_MAX];
- const ZipArchive *package;
- if (!translate_package_root_path(argv[0], path, sizeof(path), &package)) {
- LOGE("Command %s: bad source path \"%s\"\n", name, argv[0]);
- return 1;
- }
-
- const ZipEntry *entry = mzFindZipEntry(package, path);
- if (entry == NULL) {
- LOGE("Can't find %s\n", path);
- return 1;
- }
-
- // Load the update image into RAM.
- struct FirmwareContext context;
- context.total_bytes = mzGetZipEntryUncompLen(entry);
- context.done_bytes = 0;
- context.data = malloc(context.total_bytes);
- if (context.data == NULL) {
- LOGE("Can't allocate %d bytes for %s\n", context.total_bytes, argv[0]);
- return 1;
- }
-
- if (!mzProcessZipEntryContents(package, entry, firmware_fn, &context) ||
- context.done_bytes != context.total_bytes) {
- LOGE("Can't read %s\n", argv[0]);
- free(context.data);
- return 1;
- }
-
- if (remember_firmware_update(type, context.data, context.total_bytes)) {
- LOGE("Can't store %s image\n", type);
- free(context.data);
- return 1;
- }
-
- return 0;
-}
-
-static bool write_raw_image_process_fn(
- const unsigned char *data,
- int data_len, void *ctx)
-{
- int r = mtd_write_data((MtdWriteContext*)ctx, (const char *)data, data_len);
- if (r == data_len) return true;
- LOGE("%s\n", strerror(errno));
- return false;
-}
-
-/* write_raw_image <src-image> <dest-root>
- */
-static int
-cmd_write_raw_image(const char *name, void *cookie,
- int argc, const char *argv[], PermissionRequestList *permissions)
-{
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx permissions
-
- if (argc != 2) {
- LOGE("Command %s requires exactly two arguments\n", name);
- return 1;
- }
-
- // Use 10% of the progress bar (20% post-verification) by default
- const char *src_root_path = argv[0];
- const char *dst_root_path = argv[1];
- ui_print("Writing %s...\n", dst_root_path);
- if (!gDidShowProgress) ui_show_progress(DEFAULT_IMAGE_PROGRESS_FRACTION, 0);
-
- /* Find the source image, which is probably in a package.
- */
- if (!is_package_root_path(src_root_path)) {
- LOGE("Command %s: non-package source path \"%s\" not yet supported\n",
- name, src_root_path);
- return 255;
- }
-
- /* Get the package.
- */
- char srcpathbuf[PATH_MAX];
- const char *src_path;
- const ZipArchive *package;
- src_path = translate_package_root_path(src_root_path,
- srcpathbuf, sizeof(srcpathbuf), &package);
- if (src_path == NULL) {
- LOGE("Command %s: bad source path \"%s\"\n", name, src_root_path);
- return 1;
- }
-
- /* Get the entry.
- */
- const ZipEntry *entry = mzFindZipEntry(package, src_path);
- if (entry == NULL) {
- LOGE("Missing file %s\n", src_path);
- return 1;
- }
-
- /* Unmount the destination root if it isn't already.
- */
- int ret = ensure_root_path_unmounted(dst_root_path);
- if (ret < 0) {
- LOGE("Can't unmount %s\n", dst_root_path);
- return 1;
- }
-
- /* Open the partition for writing.
- */
- const MtdPartition *partition = get_root_mtd_partition(dst_root_path);
- if (partition == NULL) {
- LOGE("Can't find %s\n", dst_root_path);
- return 1;
- }
- MtdWriteContext *context = mtd_write_partition(partition);
- if (context == NULL) {
- LOGE("Can't open %s\n", dst_root_path);
- return 1;
- }
-
- /* Extract and write the image.
- */
- bool ok = mzProcessZipEntryContents(package, entry,
- write_raw_image_process_fn, context);
- if (!ok) {
- LOGE("Error writing %s\n", dst_root_path);
- mtd_write_close(context);
- return 1;
- }
-
- if (mtd_erase_blocks(context, -1) == (off_t) -1) {
- LOGE("Error finishing %s\n", dst_root_path);
- mtd_write_close(context);
- return -1;
- }
-
- if (mtd_write_close(context)) {
- LOGE("Error closing %s\n", dst_root_path);
- return -1;
- }
- return 0;
-}
-
-/* mark <resource> dirty|clean
- */
-static int
-cmd_mark(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx when marking, save the top-level hash at the mark point
-// so we can retry on failure. Otherwise the hashes won't match,
-// or someone could intentionally dirty the FS to force a downgrade
-//xxx
- return -1;
-}
-
-/* done
- */
-static int
-cmd_done(const char *name, void *cookie, int argc, const char *argv[],
- PermissionRequestList *permissions)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx
- return -1;
-}
-
-
-/*
- * Function definitions
- */
-
-/* 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;
-}
-
-/* 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;
-}
-
-/* hash_dir(<path-to-directory>)
- */
-static int
-fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen,
- PermissionRequestList *permissions)
-{
- int ret = -1;
-
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- const char *dir;
- if (argc != 1) {
- fprintf(stderr, "%s: wrong number of arguments (%d)\n",
- name, argc);
- return 1;
- } else {
- dir = argv[0];
- }
-
- if (permissions != NULL) {
- if (dir == NULL) {
- /* The argument is the result of another function.
- * Assume the worst case, where the function returns
- * the root.
- */
- dir = "/";
- }
- ret = addPermissionRequestToList(permissions, dir, true, PERM_READ);
- } else {
-//xxx build and return the string
- *result = strdup("hashvalue");
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
- ret = 0;
- }
-
- return ret;
-}
-
-/* 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;
-}
-
-/* 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;
-}
-
-/* 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;
-}
-
-/* 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;
-}
-
-int
-register_update_commands(RecoveryCommandContext *ctx)
-{
- int ret;
-
- ret = commandInit();
- if (ret < 0) return ret;
-
- /*
- * Commands
- */
-
- ret = registerCommand("assert", CMD_ARGS_BOOLEAN, cmd_assert, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("delete", CMD_ARGS_WORDS, cmd_delete, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("delete_recursive", CMD_ARGS_WORDS, cmd_delete,
- (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("copy_dir", CMD_ARGS_WORDS,
- cmd_copy_dir, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("run_program", CMD_ARGS_WORDS,
- cmd_run_program, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("set_perm", CMD_ARGS_WORDS,
- cmd_set_perm, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("set_perm_recursive", CMD_ARGS_WORDS,
- cmd_set_perm, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("show_progress", CMD_ARGS_WORDS,
- cmd_show_progress, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("symlink", CMD_ARGS_WORDS, cmd_symlink, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("format", CMD_ARGS_WORDS, cmd_format, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("write_radio_image", CMD_ARGS_WORDS,
- cmd_write_firmware_image, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("write_hboot_image", CMD_ARGS_WORDS,
- cmd_write_firmware_image, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("write_raw_image", CMD_ARGS_WORDS,
- cmd_write_raw_image, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("mark", CMD_ARGS_WORDS, cmd_mark, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("done", CMD_ARGS_WORDS, cmd_done, (void *)ctx);
- if (ret < 0) return ret;
-
- /*
- * Functions
- */
-
- ret = registerFunction("compatible_with", fn_compatible_with, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("update_forced", fn_update_forced, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("get_mark", fn_get_mark, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("hash_dir", fn_hash_dir, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("matches", fn_matches, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("concat", fn_concat, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("getprop", fn_getprop, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("file_contains", fn_file_contains, (void *)ctx);
- if (ret < 0) return ret;
-
- return 0;
-}
diff --git a/commands.h b/commands.h
deleted file mode 100644
index e9acea2..0000000
--- a/commands.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef RECOVERY_COMMANDS_H_
-#define RECOVERY_COMMANDS_H_
-
-#include "minzip/Zip.h"
-
-typedef struct {
- ZipArchive *package;
-} RecoveryCommandContext;
-
-int register_update_commands(RecoveryCommandContext *ctx);
-
-#endif // RECOVERY_COMMANDS_H_
diff --git a/common.h b/common.h
deleted file mode 100644
index e17f76a..0000000
--- a/common.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef RECOVERY_COMMON_H
-#define RECOVERY_COMMON_H
-
-#include <stdio.h>
-
-// Initialize the graphics system.
-void ui_init();
-
-// Use KEY_* codes from <linux/input.h> or KEY_DREAM_* from "minui/minui.h".
-int ui_wait_key(); // waits for a key/button press, returns the code
-int ui_key_pressed(int key); // returns >0 if the code is currently pressed
-int ui_text_visible(); // returns >0 if text log is currently visible
-void ui_clear_key_queue();
-
-// Write a message to the on-screen log shown with Alt-L (also to stderr).
-// The screen is small, and users may need to report these messages to support,
-// so keep the output short and not too cryptic.
-void ui_print(const char *fmt, ...);
-
-// Display some header text followed by a menu of items, which appears
-// at the top of the screen (in place of any scrolling ui_print()
-// output, if necessary).
-void ui_start_menu(char** headers, char** items);
-// Set the menu highlight to the given index, and return it (capped to
-// the range [0..numitems).
-int ui_menu_select(int sel);
-// End menu mode, resetting the text overlay so that ui_print()
-// statements will be displayed.
-void ui_end_menu();
-
-// Set the icon (normally the only thing visible besides the progress bar).
-enum {
- BACKGROUND_ICON_NONE,
- BACKGROUND_ICON_UNPACKING,
- BACKGROUND_ICON_INSTALLING,
- BACKGROUND_ICON_ERROR,
- BACKGROUND_ICON_FIRMWARE_INSTALLING,
- BACKGROUND_ICON_FIRMWARE_ERROR,
- NUM_BACKGROUND_ICONS
-};
-void ui_set_background(int icon);
-
-// Get a malloc'd copy of the screen image showing (only) the specified icon.
-// Also returns the width, height, and bits per pixel of the returned image.
-// TODO: Use some sort of "struct Bitmap" here instead of all these variables?
-char *ui_copy_image(int icon, int *width, int *height, int *bpp);
-
-// Show a progress bar and define the scope of the next operation:
-// portion - fraction of the progress bar the next operation will use
-// seconds - expected time interval (progress bar moves at this minimum rate)
-void ui_show_progress(float portion, int seconds);
-void ui_set_progress(float fraction); // 0.0 - 1.0 within the defined scope
-
-// Default allocation of progress bar segments to operations
-static const int VERIFICATION_PROGRESS_TIME = 60;
-static const float VERIFICATION_PROGRESS_FRACTION = 0.5;
-static const float DEFAULT_FILES_PROGRESS_FRACTION = 0.4;
-static const float DEFAULT_IMAGE_PROGRESS_FRACTION = 0.1;
-
-// Show a rotating "barberpole" for ongoing operations. Updates automatically.
-void ui_show_indeterminate_progress();
-
-// Hide and reset the progress bar.
-void ui_reset_progress();
-
-#define LOGE(...) ui_print("E:" __VA_ARGS__)
-#define LOGW(...) fprintf(stderr, "W:" __VA_ARGS__)
-#define LOGI(...) fprintf(stderr, "I:" __VA_ARGS__)
-
-#if 0
-#define LOGV(...) fprintf(stderr, "V:" __VA_ARGS__)
-#define LOGD(...) fprintf(stderr, "D:" __VA_ARGS__)
-#else
-#define LOGV(...) do {} while (0)
-#define LOGD(...) do {} while (0)
-#endif
-
-#endif // RECOVERY_COMMON_H
diff --git a/etc/META-INF/com/google/android/update-script b/etc/META-INF/com/google/android/update-script
deleted file mode 100644
index b091b19..0000000
--- a/etc/META-INF/com/google/android/update-script
+++ /dev/null
@@ -1,8 +0,0 @@
-assert compatible_with("0.1") == "true"
-assert file_contains("SYSTEM:build.prop", "ro.product.device=dream") == "true" || file_contains("SYSTEM:build.prop", "ro.build.product=dream") == "true"
-assert file_contains("RECOVERY:default.prop", "ro.product.device=dream") == "true" || file_contains("RECOVERY:default.prop", "ro.build.product=dream") == "true"
-assert getprop("ro.product.device") == "dream"
-format BOOT:
-format SYSTEM:
-copy_dir PACKAGE:system SYSTEM:
-write_raw_image PACKAGE:boot.img BOOT:
diff --git a/etc/init.rc b/etc/init.rc
deleted file mode 100644
index d9e86d7..0000000
--- a/etc/init.rc
+++ /dev/null
@@ -1,33 +0,0 @@
-
-on init
- export PATH /sbin
- export ANDROID_ROOT /system
- export ANDROID_DATA /data
- export EXTERNAL_STORAGE /sdcard
-
- symlink /system/etc /etc
-
- mkdir /sdcard
- mkdir /system
- mkdir /data
- mkdir /cache
- mount /tmp /tmp tmpfs
-
-on boot
-
- ifup lo
- hostname localhost
- domainname localdomain
-
- class_start default
-
-
-service recovery /sbin/recovery
-
-service adbd /sbin/adbd recovery
-
-on property:persist.service.adb.enable=1
- start adbd
-
-on property:persist.service.adb.enable=0
- stop adbd
diff --git a/firmware.c b/firmware.c
deleted file mode 100644
index 34b2918..0000000
--- a/firmware.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "bootloader.h"
-#include "common.h"
-#include "firmware.h"
-#include "roots.h"
-
-#include <errno.h>
-#include <string.h>
-#include <sys/reboot.h>
-
-static const char *update_type = NULL;
-static const char *update_data = NULL;
-static int update_length = 0;
-
-int remember_firmware_update(const char *type, const char *data, int length) {
- if (update_type != NULL || update_data != NULL) {
- LOGE("Multiple firmware images\n");
- return -1;
- }
-
- update_type = type;
- update_data = data;
- update_length = length;
- return 0;
-}
-
-
-/* Bootloader / Recovery Flow
- *
- * On every boot, the bootloader will read the bootloader_message
- * from flash and check the command field. The bootloader should
- * deal with the command field not having a 0 terminator correctly
- * (so as to not crash if the block is invalid or corrupt).
- *
- * The bootloader will have to publish the partition that contains
- * the bootloader_message to the linux kernel so it can update it.
- *
- * if command == "boot-recovery" -> boot recovery.img
- * else if command == "update-radio" -> update radio image (below)
- * else if command == "update-hboot" -> update hboot image (below)
- * else -> boot boot.img (normal boot)
- *
- * Radio/Hboot Update Flow
- * 1. the bootloader will attempt to load and validate the header
- * 2. if the header is invalid, status="invalid-update", goto #8
- * 3. display the busy image on-screen
- * 4. if the update image is invalid, status="invalid-radio-image", goto #8
- * 5. attempt to update the firmware (depending on the command)
- * 6. if successful, status="okay", goto #8
- * 7. if failed, and the old image can still boot, status="failed-update"
- * 8. write the bootloader_message, leaving the recovery field
- * unchanged, updating status, and setting command to
- * "boot-recovery"
- * 9. reboot
- *
- * The bootloader will not modify or erase the cache partition.
- * It is recovery's responsibility to clean up the mess afterwards.
- */
-
-int maybe_install_firmware_update(const char *send_intent) {
- if (update_data == NULL || update_length == 0) return 0;
-
- /* We destroy the cache partition to pass the update image to the
- * bootloader, so all we can really do afterwards is wipe cache and reboot.
- * Set up this instruction now, in case we're interrupted while writing.
- */
-
- struct bootloader_message boot;
- memset(&boot, 0, sizeof(boot));
- strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
- strlcpy(boot.recovery, "recovery\n--wipe_cache\n", sizeof(boot.command));
- if (send_intent != NULL) {
- strlcat(boot.recovery, "--send_intent=", sizeof(boot.recovery));
- strlcat(boot.recovery, send_intent, sizeof(boot.recovery));
- strlcat(boot.recovery, "\n", sizeof(boot.recovery));
- }
- if (set_bootloader_message(&boot)) return -1;
-
- int width = 0, height = 0, bpp = 0;
- char *busy_image = ui_copy_image(
- BACKGROUND_ICON_FIRMWARE_INSTALLING, &width, &height, &bpp);
- char *fail_image = ui_copy_image(
- BACKGROUND_ICON_FIRMWARE_ERROR, &width, &height, &bpp);
-
- ui_print("Writing %s image...\n", update_type);
- if (write_update_for_bootloader(
- update_data, update_length,
- width, height, bpp, busy_image, fail_image)) {
- LOGE("Can't write %s image\n(%s)\n", update_type, strerror(errno));
- format_root_device("CACHE:"); // Attempt to clean cache up, at least.
- return -1;
- }
-
- free(busy_image);
- free(fail_image);
-
- /* The update image is fully written, so now we can instruct the bootloader
- * to install it. (After doing so, it will come back here, and we will
- * wipe the cache and reboot into the system.)
- */
- snprintf(boot.command, sizeof(boot.command), "update-%s", update_type);
- if (set_bootloader_message(&boot)) {
- format_root_device("CACHE:");
- return -1;
- }
-
- reboot(RB_AUTOBOOT);
-
- // Can't reboot? WTF?
- LOGE("Can't reboot\n");
- return -1;
-}
diff --git a/firmware.h b/firmware.h
deleted file mode 100644
index f3f7aab..0000000
--- a/firmware.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _RECOVERY_FIRMWARE_H
-#define _RECOVERY_FIRMWARE_H
-
-/* Save a radio or bootloader update image for later installation.
- * The type should be one of "hboot" or "radio".
- * Takes ownership of type and data. Returns nonzero on error.
- */
-int remember_firmware_update(const char *type, const char *data, int length);
-
-/* If an update was saved, reboot into the bootloader now to install it.
- * Returns 0 if no radio image was defined, nonzero on error,
- * doesn't return at all on success...
- */
-int maybe_install_firmware_update(const char *send_intent);
-
-#endif
diff --git a/install.c b/install.c
deleted file mode 100644
index 0691120..0000000
--- a/install.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <sys/stat.h>
-
-#include "amend/amend.h"
-#include "common.h"
-#include "install.h"
-#include "mincrypt/rsa.h"
-#include "minui/minui.h"
-#include "minzip/SysUtil.h"
-#include "minzip/Zip.h"
-#include "mtdutils/mounts.h"
-#include "mtdutils/mtdutils.h"
-#include "roots.h"
-#include "verifier.h"
-
-/* List of public keys */
-static const RSAPublicKey keys[] = {
-#include "keys.inc"
-};
-
-#define ASSUMED_UPDATE_SCRIPT_NAME "META-INF/com/google/android/update-script"
-
-static const ZipEntry *
-find_update_script(ZipArchive *zip)
-{
-//TODO: Get the location of this script from the MANIFEST.MF file
- return mzFindZipEntry(zip, ASSUMED_UPDATE_SCRIPT_NAME);
-}
-
-static int read_data(ZipArchive *zip, const ZipEntry *entry,
- char** ppData, int* pLength) {
- int len = (int)mzGetZipEntryUncompLen(entry);
- if (len <= 0) {
- LOGE("Bad data length %d\n", len);
- return -1;
- }
- char *data = malloc(len + 1);
- if (data == NULL) {
- LOGE("Can't allocate %d bytes for data\n", len + 1);
- return -2;
- }
- bool ok = mzReadZipEntry(zip, entry, data, len);
- if (!ok) {
- LOGE("Error while reading data\n");
- free(data);
- return -3;
- }
- data[len] = '\0'; // not necessary, but just to be safe
- *ppData = data;
- if (pLength) {
- *pLength = len;
- }
- return 0;
-}
-
-static int
-handle_update_script(ZipArchive *zip, const ZipEntry *update_script_entry)
-{
- /* Read the entire script into a buffer.
- */
- int script_len;
- char* script_data;
- if (read_data(zip, update_script_entry, &script_data, &script_len) < 0) {
- LOGE("Can't read update script\n");
- return INSTALL_ERROR;
- }
-
- /* Parse the script. Note that the script and parse tree are never freed.
- */
- const AmCommandList *commands = parseAmendScript(script_data, script_len);
- if (commands == NULL) {
- LOGE("Syntax error in update script\n");
- return INSTALL_ERROR;
- } else {
- UnterminatedString name = mzGetZipEntryFileName(update_script_entry);
- LOGI("Parsed %.*s\n", name.len, name.str);
- }
-
- /* Execute the script.
- */
- int ret = execCommandList((ExecContext *)1, commands);
- if (ret != 0) {
- int num = ret;
- char *line, *next = script_data;
- while (next != NULL && ret-- > 0) {
- line = next;
- next = memchr(line, '\n', script_data + script_len - line);
- if (next != NULL) *next++ = '\0';
- }
- LOGE("Failure at line %d:\n%s\n", num, next ? line : "(not found)");
- return INSTALL_ERROR;
- }
-
- ui_print("Installation complete.\n");
- return INSTALL_SUCCESS;
-}
-
-static int
-handle_update_package(const char *path, ZipArchive *zip)
-{
- // Give verification half the progress bar...
- ui_print("Verifying update package...\n");
- ui_show_progress(
- VERIFICATION_PROGRESS_FRACTION,
- VERIFICATION_PROGRESS_TIME);
-
- if (!verify_jar_signature(zip, keys, sizeof(keys) / sizeof(keys[0]))) {
- LOGE("Verification failed\n");
- return INSTALL_CORRUPT;
- }
-
- // Update should take the rest of the progress bar.
- ui_print("Installing update...\n");
-
- const ZipEntry *script_entry;
- script_entry = find_update_script(zip);
- if (script_entry == NULL) {
- LOGE("Can't find update script\n");
- return INSTALL_CORRUPT;
- }
-
- if (register_package_root(zip, path) < 0) {
- LOGE("Can't register package root\n");
- return INSTALL_ERROR;
- }
-
- int ret = handle_update_script(zip, script_entry);
- register_package_root(NULL, NULL); // Unregister package root
- return ret;
-}
-
-int
-install_package(const char *root_path)
-{
- ui_set_background(BACKGROUND_ICON_INSTALLING);
- ui_print("Finding update package...\n");
- ui_show_indeterminate_progress();
- LOGI("Update location: %s\n", root_path);
-
- if (ensure_root_path_mounted(root_path) != 0) {
- LOGE("Can't mount %s\n", root_path);
- return INSTALL_CORRUPT;
- }
-
- char path[PATH_MAX] = "";
- if (translate_root_path(root_path, path, sizeof(path)) == NULL) {
- LOGE("Bad path %s\n", root_path);
- return INSTALL_CORRUPT;
- }
-
- ui_print("Opening update package...\n");
- LOGI("Update file path: %s\n", path);
-
- /* Try to open the package.
- */
- ZipArchive zip;
- int err = mzOpenZipArchive(path, &zip);
- if (err != 0) {
- LOGE("Can't open %s\n(%s)\n", path, err != -1 ? strerror(err) : "bad");
- return INSTALL_CORRUPT;
- }
-
- /* Verify and install the contents of the package.
- */
- int status = handle_update_package(path, &zip);
- mzCloseZipArchive(&zip);
- return status;
-}
diff --git a/install.h b/install.h
deleted file mode 100644
index a7ebc09..0000000
--- a/install.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef RECOVERY_INSTALL_H_
-#define RECOVERY_INSTALL_H_
-
-#include "common.h"
-
-enum { INSTALL_SUCCESS, INSTALL_ERROR, INSTALL_CORRUPT };
-int install_package(const char *root_path);
-
-#endif // RECOVERY_INSTALL_H_
diff --git a/minui/Android.mk b/minui/Android.mk
deleted file mode 100644
index 91dd939..0000000
--- a/minui/Android.mk
+++ /dev/null
@@ -1,12 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := graphics.c events.c resources.c
-
-LOCAL_C_INCLUDES +=\
- external/libpng\
- external/zlib
-
-LOCAL_MODULE := libminui
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/minui/events.c b/minui/events.c
deleted file mode 100644
index 3aed2a8..0000000
--- a/minui/events.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <sys/poll.h>
-
-#include <linux/input.h>
-
-#include "minui.h"
-
-#define MAX_DEVICES 16
-
-static struct pollfd ev_fds[MAX_DEVICES];
-static unsigned ev_count = 0;
-
-int ev_init(void)
-{
- DIR *dir;
- struct dirent *de;
- int fd;
-
- dir = opendir("/dev/input");
- if(dir != 0) {
- while((de = readdir(dir))) {
-// fprintf(stderr,"/dev/input/%s\n", de->d_name);
- if(strncmp(de->d_name,"event",5)) continue;
- fd = openat(dirfd(dir), de->d_name, O_RDONLY);
- if(fd < 0) continue;
-
- ev_fds[ev_count].fd = fd;
- ev_fds[ev_count].events = POLLIN;
- ev_count++;
- if(ev_count == MAX_DEVICES) break;
- }
- }
-
- return 0;
-}
-
-void ev_exit(void)
-{
- while (ev_count > 0) {
- close(ev_fds[--ev_count].fd);
- }
-}
-
-int ev_get(struct input_event *ev, unsigned dont_wait)
-{
- int r;
- unsigned n;
-
- do {
- r = poll(ev_fds, ev_count, dont_wait ? 0 : -1);
-
- if(r > 0) {
- for(n = 0; n < ev_count; n++) {
- if(ev_fds[n].revents & POLLIN) {
- r = read(ev_fds[n].fd, ev, sizeof(*ev));
- if(r == sizeof(*ev)) return 0;
- }
- }
- }
- } while(dont_wait == 0);
-
- return -1;
-}
diff --git a/minui/font_10x18.h b/minui/font_10x18.h
deleted file mode 100644
index 7f96465..0000000
--- a/minui/font_10x18.h
+++ /dev/null
@@ -1,214 +0,0 @@
-struct {
- unsigned width;
- unsigned height;
- unsigned cwidth;
- unsigned cheight;
- unsigned char rundata[];
-} font = {
- .width = 960,
- .height = 18,
- .cwidth = 10,
- .cheight = 18,
- .rundata = {
-0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x55,0x82,0x06,0x82,0x02,0x82,0x10,0x82,
-0x11,0x83,0x08,0x82,0x0a,0x82,0x04,0x82,0x46,0x82,0x08,0x82,0x07,0x84,0x06,
-0x84,0x0a,0x81,0x03,0x88,0x04,0x84,0x04,0x88,0x04,0x84,0x06,0x84,0x1e,0x81,
-0x0e,0x81,0x0a,0x84,0x06,0x84,0x07,0x82,0x05,0x85,0x07,0x84,0x04,0x86,0x04,
-0x88,0x02,0x88,0x04,0x84,0x04,0x82,0x04,0x82,0x02,0x88,0x05,0x86,0x01,0x82,
-0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x04,0x84,0x04,
-0x86,0x06,0x84,0x04,0x86,0x06,0x84,0x04,0x88,0x02,0x82,0x04,0x82,0x02,0x82,
-0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,
-0x88,0x03,0x86,0x0e,0x86,0x06,0x82,0x11,0x82,0x10,0x82,0x18,0x82,0x0f,0x84,
-0x0d,0x82,0x1c,0x82,0x09,0x84,0x7f,0x16,0x84,0x05,0x82,0x05,0x84,0x07,0x83,
-0x02,0x82,0x19,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x01,0x82,0x03,0x86,0x04,
-0x83,0x02,0x82,0x03,0x82,0x01,0x82,0x07,0x82,0x09,0x82,0x06,0x82,0x3e,0x82,
-0x04,0x84,0x06,0x83,0x06,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x03,
-0x82,0x09,0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,
-0x1c,0x82,0x0e,0x82,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x05,0x84,0x04,
-0x82,0x02,0x82,0x05,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,
-0x09,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x04,
-0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x03,0x82,0x02,0x82,
-0x03,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x02,
-0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
-0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x03,0x82,0x08,0x82,0x0c,
-0x82,0x05,0x84,0x11,0x82,0x0f,0x82,0x18,0x82,0x0e,0x82,0x02,0x82,0x0c,0x82,
-0x1c,0x82,0x0b,0x82,0x7f,0x15,0x82,0x08,0x82,0x08,0x82,0x05,0x82,0x01,0x82,
-0x01,0x82,0x19,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x01,0x82,0x02,0x82,0x01,
-0x82,0x01,0x82,0x02,0x82,0x01,0x82,0x01,0x82,0x03,0x82,0x01,0x82,0x07,0x82,
-0x08,0x82,0x08,0x82,0x3d,0x82,0x03,0x82,0x02,0x82,0x04,0x84,0x05,0x82,0x04,
-0x82,0x02,0x82,0x04,0x82,0x06,0x83,0x03,0x82,0x08,0x82,0x04,0x81,0x09,0x82,
-0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x1a,0x82,0x10,0x82,0x06,0x82,0x04,
-0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,
-0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,
-0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x83,
-0x02,0x83,0x02,0x83,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,
-0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,
-0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x04,
-0x82,0x02,0x82,0x09,0x82,0x03,0x82,0x08,0x82,0x0c,0x82,0x04,0x82,0x02,0x82,
-0x11,0x82,0x0e,0x82,0x18,0x82,0x0e,0x82,0x02,0x82,0x0c,0x82,0x0b,0x82,0x0b,
-0x82,0x02,0x82,0x0b,0x82,0x4d,0x82,0x45,0x82,0x08,0x82,0x08,0x82,0x05,0x82,
-0x02,0x83,0x1a,0x82,0x07,0x81,0x02,0x81,0x07,0x82,0x01,0x82,0x02,0x82,0x01,
-0x82,0x05,0x82,0x01,0x84,0x04,0x82,0x01,0x82,0x07,0x82,0x08,0x82,0x08,0x82,
-0x06,0x82,0x02,0x82,0x06,0x82,0x28,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x01,
-0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x84,0x03,0x82,0x08,0x82,
-0x0d,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x19,0x82,0x12,0x82,0x05,
-0x82,0x04,0x82,0x02,0x82,0x02,0x84,0x03,0x82,0x02,0x82,0x03,0x82,0x03,0x82,
-0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x04,
-0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x83,0x02,0x83,
-0x02,0x84,0x02,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
-0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x0b,0x82,0x05,0x82,0x04,0x82,0x02,0x82,
-0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,
-0x82,0x04,0x82,0x09,0x82,0x0b,0x82,0x03,0x82,0x04,0x82,0x20,0x82,0x18,0x82,
-0x0e,0x82,0x10,0x82,0x0b,0x82,0x0b,0x82,0x02,0x82,0x0b,0x82,0x4d,0x82,0x45,
-0x82,0x08,0x82,0x08,0x82,0x26,0x82,0x10,0x88,0x01,0x82,0x01,0x82,0x06,0x83,
-0x01,0x82,0x04,0x84,0x08,0x81,0x08,0x82,0x0a,0x82,0x05,0x82,0x02,0x82,0x06,
-0x82,0x28,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x08,0x82,0x04,0x82,
-0x01,0x82,0x03,0x82,0x08,0x82,0x0d,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,
-0x82,0x18,0x82,0x06,0x88,0x06,0x82,0x04,0x82,0x04,0x82,0x02,0x82,0x01,0x85,
-0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x04,0x82,0x02,
-0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,
-0x02,0x82,0x04,0x82,0x08,0x88,0x02,0x84,0x02,0x82,0x02,0x82,0x04,0x82,0x02,
-0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x0b,0x82,
-0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x04,0x84,0x06,
-0x84,0x08,0x82,0x05,0x82,0x09,0x82,0x0b,0x82,0x2b,0x82,0x18,0x82,0x0e,0x82,
-0x10,0x82,0x1c,0x82,0x0b,0x82,0x4d,0x82,0x45,0x82,0x08,0x82,0x08,0x82,0x26,
-0x82,0x11,0x82,0x01,0x82,0x03,0x82,0x01,0x82,0x09,0x82,0x06,0x82,0x12,0x82,
-0x0a,0x82,0x06,0x84,0x07,0x82,0x27,0x82,0x04,0x82,0x04,0x82,0x05,0x82,0x0b,
-0x82,0x07,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x01,0x83,0x04,0x82,0x01,0x83,
-0x08,0x82,0x05,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x05,0x83,0x07,0x83,0x05,
-0x82,0x16,0x82,0x08,0x82,0x03,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,
-0x02,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,
-0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,
-0x08,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,
-0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,
-0x0a,0x82,0x05,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,
-0x82,0x04,0x84,0x06,0x84,0x08,0x82,0x05,0x82,0x0a,0x82,0x0a,0x82,0x23,0x85,
-0x03,0x82,0x01,0x83,0x06,0x85,0x05,0x83,0x01,0x82,0x04,0x84,0x04,0x86,0x05,
-0x85,0x01,0x81,0x02,0x82,0x01,0x83,0x05,0x84,0x09,0x84,0x02,0x82,0x03,0x82,
-0x06,0x82,0x05,0x81,0x01,0x82,0x01,0x82,0x03,0x82,0x01,0x83,0x06,0x84,0x04,
-0x82,0x01,0x83,0x06,0x83,0x01,0x82,0x02,0x82,0x01,0x84,0x04,0x86,0x03,0x86,
-0x04,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
-0x82,0x02,0x82,0x04,0x82,0x03,0x87,0x05,0x82,0x08,0x82,0x08,0x82,0x26,0x82,
-0x11,0x82,0x01,0x82,0x04,0x86,0x07,0x82,0x05,0x83,0x12,0x82,0x0a,0x82,0x04,
-0x88,0x02,0x88,0x0c,0x88,0x10,0x82,0x04,0x82,0x04,0x82,0x05,0x82,0x0a,0x82,
-0x06,0x83,0x04,0x82,0x03,0x82,0x03,0x83,0x02,0x82,0x03,0x83,0x02,0x82,0x07,
-0x82,0x06,0x84,0x05,0x82,0x02,0x83,0x05,0x83,0x07,0x83,0x04,0x82,0x18,0x82,
-0x06,0x82,0x04,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x86,0x04,
-0x82,0x08,0x82,0x04,0x82,0x02,0x86,0x04,0x86,0x04,0x82,0x02,0x84,0x02,0x88,
-0x05,0x82,0x0a,0x82,0x03,0x85,0x05,0x82,0x08,0x82,0x01,0x82,0x01,0x82,0x02,
-0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,
-0x04,0x82,0x02,0x82,0x03,0x82,0x05,0x84,0x07,0x82,0x05,0x82,0x04,0x82,0x03,
-0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,0x82,0x05,0x82,0x08,0x82,0x08,0x82,
-0x06,0x82,0x0a,0x82,0x0a,0x82,0x22,0x82,0x03,0x82,0x02,0x83,0x02,0x82,0x04,
-0x82,0x03,0x82,0x03,0x82,0x02,0x83,0x03,0x82,0x02,0x82,0x05,0x82,0x06,0x82,
-0x03,0x83,0x02,0x83,0x02,0x82,0x06,0x82,0x0b,0x82,0x02,0x82,0x02,0x82,0x07,
-0x82,0x05,0x88,0x02,0x83,0x02,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,0x82,
-0x04,0x82,0x02,0x83,0x03,0x83,0x02,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x06,
-0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,
-0x03,0x82,0x04,0x82,0x08,0x82,0x02,0x84,0x09,0x82,0x09,0x84,0x23,0x82,0x11,
-0x82,0x01,0x82,0x06,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x01,0x82,0x11,0x82,
-0x0a,0x82,0x06,0x84,0x07,0x82,0x26,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x08,
-0x83,0x09,0x82,0x03,0x82,0x03,0x82,0x09,0x82,0x02,0x82,0x04,0x82,0x05,0x82,
-0x06,0x82,0x02,0x82,0x05,0x83,0x01,0x82,0x17,0x82,0x16,0x82,0x06,0x82,0x05,
-0x82,0x01,0x82,0x01,0x82,0x02,0x88,0x02,0x82,0x03,0x82,0x03,0x82,0x08,0x82,
-0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,
-0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x01,0x82,0x01,0x82,
-0x02,0x82,0x02,0x84,0x02,0x82,0x04,0x82,0x02,0x86,0x04,0x82,0x04,0x82,0x02,
-0x86,0x09,0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x82,
-0x01,0x82,0x04,0x84,0x07,0x82,0x07,0x82,0x07,0x82,0x0b,0x82,0x09,0x82,0x27,
-0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
-0x04,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,
-0x82,0x01,0x82,0x08,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,
-0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x07,
-0x82,0x0a,0x82,0x06,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x04,0x82,
-0x04,0x84,0x04,0x82,0x04,0x82,0x07,0x82,0x06,0x82,0x08,0x82,0x08,0x82,0x26,
-0x82,0x0f,0x88,0x05,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x02,0x82,0x01,0x82,
-0x0d,0x82,0x0a,0x82,0x05,0x82,0x02,0x82,0x06,0x82,0x26,0x82,0x05,0x82,0x04,
-0x82,0x05,0x82,0x07,0x82,0x0c,0x82,0x02,0x88,0x08,0x82,0x02,0x82,0x04,0x82,
-0x05,0x82,0x05,0x82,0x04,0x82,0x08,0x82,0x18,0x82,0x14,0x82,0x07,0x82,0x05,
-0x82,0x01,0x84,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,
-0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,
-0x82,0x0a,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x08,0x82,0x01,0x82,0x01,0x82,
-0x02,0x82,0x02,0x84,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,
-0x82,0x02,0x82,0x0a,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x82,
-0x01,0x82,0x01,0x82,0x04,0x84,0x07,0x82,0x07,0x82,0x07,0x82,0x0b,0x82,0x09,
-0x82,0x22,0x87,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x88,
-0x04,0x82,0x06,0x82,0x03,0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,
-0x84,0x09,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,
-0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x08,0x86,0x05,
-0x82,0x06,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x03,0x82,0x01,0x82,0x01,0x82,
-0x05,0x82,0x05,0x82,0x04,0x82,0x06,0x82,0x07,0x82,0x08,0x82,0x08,0x82,0x26,
-0x82,0x10,0x82,0x01,0x82,0x07,0x82,0x01,0x82,0x04,0x82,0x01,0x83,0x02,0x82,
-0x03,0x83,0x0f,0x82,0x08,0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x25,0x82,0x07,
-0x82,0x02,0x82,0x06,0x82,0x06,0x82,0x07,0x82,0x04,0x82,0x07,0x82,0x09,0x82,
-0x02,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x04,0x82,0x08,0x82,0x19,0x82,0x05,
-0x88,0x05,0x82,0x08,0x82,0x05,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x02,0x82,
-0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x08,0x82,0x04,
-0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x03,0x82,0x03,0x82,0x03,0x82,
-0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,0x82,0x04,0x82,0x02,
-0x82,0x08,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x03,0x82,0x09,0x82,0x05,0x82,
-0x05,0x82,0x04,0x82,0x04,0x84,0x04,0x83,0x02,0x83,0x03,0x82,0x02,0x82,0x06,
-0x82,0x06,0x82,0x08,0x82,0x0c,0x82,0x08,0x82,0x21,0x82,0x04,0x82,0x02,0x82,
-0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x0a,0x82,0x06,0x82,0x03,
-0x82,0x03,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x85,0x08,0x82,0x05,0x82,
-0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
-0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x0d,0x82,0x04,0x82,0x06,0x82,0x04,0x82,
-0x04,0x84,0x04,0x82,0x01,0x82,0x01,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x05,
-0x82,0x08,0x82,0x08,0x82,0x08,0x82,0x38,0x82,0x01,0x82,0x04,0x82,0x01,0x82,
-0x01,0x82,0x04,0x84,0x01,0x82,0x01,0x82,0x03,0x82,0x10,0x82,0x08,0x82,0x30,
-0x83,0x06,0x82,0x07,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x08,0x82,0x04,0x82,
-0x07,0x82,0x03,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x04,0x82,0x06,0x82,0x04,
-0x82,0x03,0x81,0x04,0x82,0x1a,0x82,0x10,0x82,0x10,0x82,0x08,0x82,0x04,0x82,
-0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,
-0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,0x82,0x05,0x82,0x03,0x82,
-0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x03,0x83,0x02,
-0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x02,0x84,0x02,0x82,0x03,0x82,0x03,0x82,
-0x04,0x82,0x05,0x82,0x05,0x82,0x04,0x82,0x05,0x82,0x05,0x83,0x02,0x83,0x03,
-0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x09,0x82,0x0c,0x82,0x08,0x82,0x21,0x82,
-0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x0a,
-0x82,0x07,0x85,0x04,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x82,0x02,0x82,
-0x07,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
-0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x0d,0x82,0x04,0x82,
-0x06,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x82,0x01,0x82,0x04,0x84,0x04,
-0x82,0x04,0x82,0x04,0x82,0x09,0x82,0x08,0x82,0x08,0x82,0x26,0x82,0x10,0x82,
-0x01,0x82,0x05,0x86,0x04,0x82,0x01,0x82,0x01,0x82,0x01,0x83,0x01,0x84,0x10,
-0x82,0x06,0x82,0x1d,0x83,0x11,0x83,0x05,0x82,0x09,0x84,0x07,0x82,0x05,0x82,
-0x09,0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x04,
-0x82,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x06,0x83,0x07,0x83,0x09,0x82,
-0x0e,0x82,0x0a,0x82,0x06,0x82,0x03,0x82,0x02,0x82,0x04,0x82,0x02,0x82,0x03,
-0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x03,0x82,0x03,0x82,0x08,0x82,0x09,0x82,
-0x02,0x83,0x02,0x82,0x04,0x82,0x05,0x82,0x06,0x82,0x01,0x82,0x04,0x82,0x04,
-0x82,0x02,0x82,0x08,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x03,0x82,0x02,0x82,
-0x03,0x82,0x09,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x03,0x82,0x02,0x82,0x06,
-0x82,0x06,0x82,0x02,0x82,0x06,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,
-0x05,0x82,0x05,0x82,0x09,0x82,0x0d,0x82,0x07,0x82,0x21,0x82,0x04,0x82,0x02,
-0x83,0x02,0x82,0x04,0x82,0x03,0x82,0x03,0x82,0x02,0x83,0x03,0x82,0x03,0x82,
-0x04,0x82,0x06,0x82,0x08,0x82,0x04,0x82,0x05,0x82,0x0b,0x82,0x02,0x82,0x03,
-0x82,0x06,0x82,0x05,0x82,0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x03,0x82,
-0x02,0x82,0x03,0x83,0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x07,0x82,0x04,
-0x82,0x04,0x82,0x02,0x82,0x03,0x82,0x02,0x83,0x05,0x82,0x05,0x88,0x03,0x82,
-0x02,0x82,0x04,0x82,0x02,0x83,0x03,0x82,0x0a,0x82,0x08,0x82,0x08,0x82,0x26,
-0x82,0x1c,0x82,0x06,0x82,0x02,0x83,0x03,0x84,0x02,0x82,0x10,0x82,0x04,0x82,
-0x1e,0x83,0x11,0x83,0x05,0x82,0x0a,0x82,0x05,0x88,0x02,0x88,0x04,0x84,0x09,
-0x82,0x05,0x84,0x06,0x84,0x05,0x82,0x09,0x84,0x06,0x84,0x07,0x83,0x07,0x83,
-0x0a,0x81,0x0e,0x81,0x0b,0x82,0x07,0x85,0x03,0x82,0x04,0x82,0x02,0x86,0x06,
-0x84,0x04,0x86,0x04,0x88,0x02,0x82,0x0a,0x84,0x01,0x81,0x02,0x82,0x04,0x82,
-0x02,0x88,0x04,0x83,0x05,0x82,0x04,0x82,0x02,0x88,0x02,0x82,0x04,0x82,0x02,
-0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x0a,0x85,0x03,0x82,0x04,0x82,0x04,0x84,
-0x07,0x82,0x07,0x84,0x07,0x82,0x05,0x82,0x04,0x82,0x02,0x82,0x04,0x82,0x05,
-0x82,0x05,0x88,0x03,0x86,0x09,0x82,0x03,0x86,0x22,0x85,0x01,0x81,0x02,0x82,
-0x01,0x83,0x06,0x85,0x05,0x83,0x01,0x82,0x04,0x85,0x05,0x82,0x07,0x86,0x03,
-0x82,0x04,0x82,0x02,0x88,0x08,0x82,0x02,0x82,0x04,0x82,0x02,0x88,0x02,0x82,
-0x01,0x82,0x01,0x82,0x02,0x82,0x04,0x82,0x04,0x84,0x04,0x82,0x01,0x83,0x06,
-0x83,0x01,0x82,0x03,0x82,0x08,0x86,0x06,0x84,0x05,0x83,0x01,0x82,0x05,0x82,
-0x06,0x82,0x02,0x82,0x03,0x82,0x04,0x82,0x04,0x83,0x01,0x82,0x03,0x87,0x06,
-0x84,0x05,0x82,0x05,0x84,0x7f,0x15,0x83,0x7f,0x14,0x83,0x7f,0x5e,0x82,0x7f,
-0x05,0x89,0x47,0x82,0x04,0x82,0x17,0x82,0x03,0x82,0x34,0x82,0x0e,0x82,0x4e,
-0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0a,0x82,0x04,0x82,0x17,0x82,0x03,0x82,
-0x34,0x82,0x0e,0x82,0x48,0x82,0x04,0x82,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0a,
-0x82,0x04,0x82,0x17,0x82,0x03,0x82,0x34,0x82,0x0e,0x82,0x49,0x82,0x02,0x82,
-0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0c,0x86,0x19,0x85,0x35,0x82,0x0e,0x82,0x4a,
-0x84,0x3f,
-0x00,
- }
-};
diff --git a/minui/graphics.c b/minui/graphics.c
deleted file mode 100644
index 06c5fdf..0000000
--- a/minui/graphics.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-
-#include <linux/fb.h>
-#include <linux/kd.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "font_10x18.h"
-#include "minui.h"
-
-typedef struct {
- GGLSurface texture;
- unsigned cwidth;
- unsigned cheight;
- unsigned ascent;
-} GRFont;
-
-static GRFont *gr_font = 0;
-static GGLContext *gr_context = 0;
-static GGLSurface gr_font_texture;
-static GGLSurface gr_framebuffer[2];
-static GGLSurface gr_mem_surface;
-static unsigned gr_active_fb = 0;
-
-static int gr_fb_fd = -1;
-static int gr_vt_fd = -1;
-
-static struct fb_var_screeninfo vi;
-
-static int get_framebuffer(GGLSurface *fb)
-{
- int fd;
- struct fb_fix_screeninfo fi;
- void *bits;
-
- fd = open("/dev/graphics/fb0", O_RDWR);
- if (fd < 0) {
- perror("cannot open fb0");
- return -1;
- }
-
- if (ioctl(fd, FBIOGET_FSCREENINFO, &fi) < 0) {
- perror("failed to get fb0 info");
- close(fd);
- return -1;
- }
-
- if (ioctl(fd, FBIOGET_VSCREENINFO, &vi) < 0) {
- perror("failed to get fb0 info");
- close(fd);
- return -1;
- }
-
- bits = mmap(0, fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (bits == MAP_FAILED) {
- perror("failed to mmap framebuffer");
- close(fd);
- return -1;
- }
-
- fb->version = sizeof(*fb);
- fb->width = vi.xres;
- fb->height = vi.yres;
- fb->stride = vi.xres;
- fb->data = bits;
- fb->format = GGL_PIXEL_FORMAT_RGB_565;
-
- fb++;
-
- fb->version = sizeof(*fb);
- fb->width = vi.xres;
- fb->height = vi.yres;
- fb->stride = vi.xres;
- fb->data = (void*) (((unsigned) bits) + vi.yres * vi.xres * 2);
- fb->format = GGL_PIXEL_FORMAT_RGB_565;
-
- return fd;
-}
-
-static void get_memory_surface(GGLSurface* ms) {
- ms->version = sizeof(*ms);
- ms->width = vi.xres;
- ms->height = vi.yres;
- ms->stride = vi.xres;
- ms->data = malloc(vi.xres * vi.yres * 2);
- ms->format = GGL_PIXEL_FORMAT_RGB_565;
-}
-
-static void set_active_framebuffer(unsigned n)
-{
- if (n > 1) return;
- vi.yres_virtual = vi.yres * 2;
- vi.yoffset = n * vi.yres;
- if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
- perror("active fb swap failed");
- }
-}
-
-void gr_flip(void)
-{
- GGLContext *gl = gr_context;
-
- /* swap front and back buffers */
- gr_active_fb = (gr_active_fb + 1) & 1;
-
- /* copy data from the in-memory surface to the buffer we're about
- * to make active. */
- memcpy(gr_framebuffer[gr_active_fb].data, gr_mem_surface.data,
- vi.xres * vi.yres * 2);
-
- /* inform the display driver */
- set_active_framebuffer(gr_active_fb);
-}
-
-void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
-{
- GGLContext *gl = gr_context;
- GGLint color[4];
- color[0] = ((r << 8) | r) + 1;
- color[1] = ((g << 8) | g) + 1;
- color[2] = ((b << 8) | b) + 1;
- color[3] = ((a << 8) | a) + 1;
- gl->color4xv(gl, color);
-}
-
-int gr_measure(const char *s)
-{
- return gr_font->cwidth * strlen(s);
-}
-
-int gr_text(int x, int y, const char *s)
-{
- GGLContext *gl = gr_context;
- GRFont *font = gr_font;
- unsigned off;
-
- y -= font->ascent;
-
- gl->bindTexture(gl, &font->texture);
- gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
- gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
- gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
- gl->enable(gl, GGL_TEXTURE_2D);
-
- while((off = *s++)) {
- off -= 32;
- if (off < 96) {
- gl->texCoord2i(gl, (off * font->cwidth) - x, 0 - y);
- gl->recti(gl, x, y, x + font->cwidth, y + font->cheight);
- }
- x += font->cwidth;
- }
-
- return x;
-}
-
-void gr_fill(int x, int y, int w, int h)
-{
- GGLContext *gl = gr_context;
- gl->disable(gl, GGL_TEXTURE_2D);
- gl->recti(gl, x, y, w, h);
-}
-
-void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy) {
- if (gr_context == NULL) {
- return;
- }
- GGLContext *gl = gr_context;
-
- gl->bindTexture(gl, (GGLSurface*) source);
- gl->texEnvi(gl, GGL_TEXTURE_ENV, GGL_TEXTURE_ENV_MODE, GGL_REPLACE);
- gl->texGeni(gl, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
- gl->texGeni(gl, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE);
- gl->enable(gl, GGL_TEXTURE_2D);
- gl->texCoord2i(gl, sx - dx, sy - dy);
- gl->recti(gl, dx, dy, dx + w, dy + h);
-}
-
-unsigned int gr_get_width(gr_surface surface) {
- if (surface == NULL) {
- return 0;
- }
- return ((GGLSurface*) surface)->width;
-}
-
-unsigned int gr_get_height(gr_surface surface) {
- if (surface == NULL) {
- return 0;
- }
- return ((GGLSurface*) surface)->height;
-}
-
-static void gr_init_font(void)
-{
- GGLSurface *ftex;
- unsigned char *bits, *rle;
- unsigned char *in, data;
-
- gr_font = calloc(sizeof(*gr_font), 1);
- ftex = &gr_font->texture;
-
- bits = malloc(font.width * font.height);
-
- ftex->version = sizeof(*ftex);
- ftex->width = font.width;
- ftex->height = font.height;
- ftex->stride = font.width;
- ftex->data = (void*) bits;
- ftex->format = GGL_PIXEL_FORMAT_A_8;
-
- in = font.rundata;
- while((data = *in++)) {
- memset(bits, (data & 0x80) ? 255 : 0, data & 0x7f);
- bits += (data & 0x7f);
- }
-
- gr_font->cwidth = font.cwidth;
- gr_font->cheight = font.cheight;
- gr_font->ascent = font.cheight - 2;
-}
-
-int gr_init(void)
-{
- gglInit(&gr_context);
- GGLContext *gl = gr_context;
-
- gr_init_font();
- gr_vt_fd = open("/dev/tty0", O_RDWR | O_SYNC);
- if (gr_vt_fd < 0) {
- // This is non-fatal; post-Cupcake kernels don't have tty0.
- perror("can't open /dev/tty0");
- } else if (ioctl(gr_vt_fd, KDSETMODE, (void*) KD_GRAPHICS)) {
- // However, if we do open tty0, we expect the ioctl to work.
- perror("failed KDSETMODE to KD_GRAPHICS on tty0");
- gr_exit();
- return -1;
- }
-
- gr_fb_fd = get_framebuffer(gr_framebuffer);
- if (gr_fb_fd < 0) {
- gr_exit();
- return -1;
- }
-
- get_memory_surface(&gr_mem_surface);
-
- fprintf(stderr, "framebuffer: fd %d (%d x %d)\n",
- gr_fb_fd, gr_framebuffer[0].width, gr_framebuffer[0].height);
-
- /* start with 0 as front (displayed) and 1 as back (drawing) */
- gr_active_fb = 0;
- set_active_framebuffer(0);
- gl->colorBuffer(gl, &gr_mem_surface);
-
-
- gl->activeTexture(gl, 0);
- gl->enable(gl, GGL_BLEND);
- gl->blendFunc(gl, GGL_SRC_ALPHA, GGL_ONE_MINUS_SRC_ALPHA);
-
- return 0;
-}
-
-void gr_exit(void)
-{
- close(gr_fb_fd);
- gr_fb_fd = -1;
-
- free(gr_mem_surface.data);
-
- ioctl(gr_vt_fd, KDSETMODE, (void*) KD_TEXT);
- close(gr_vt_fd);
- gr_vt_fd = -1;
-}
-
-int gr_fb_width(void)
-{
- return gr_framebuffer[0].width;
-}
-
-int gr_fb_height(void)
-{
- return gr_framebuffer[0].height;
-}
-
-gr_pixel *gr_fb_data(void)
-{
- return (unsigned short *) gr_mem_surface.data;
-}
diff --git a/minui/minui.h b/minui/minui.h
deleted file mode 100644
index 80b47a4..0000000
--- a/minui/minui.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _MINUI_H_
-#define _MINUI_H_
-
-typedef void* gr_surface;
-typedef unsigned short gr_pixel;
-
-int gr_init(void);
-void gr_exit(void);
-
-int gr_fb_width(void);
-int gr_fb_height(void);
-gr_pixel *gr_fb_data(void);
-void gr_flip(void);
-
-void gr_color(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
-void gr_fill(int x, int y, int w, int h);
-int gr_text(int x, int y, const char *s);
-int gr_measure(const char *s);
-
-void gr_blit(gr_surface source, int sx, int sy, int w, int h, int dx, int dy);
-unsigned int gr_get_width(gr_surface surface);
-unsigned int gr_get_height(gr_surface surface);
-
-// input event structure, include <linux/input.h> for the definition.
-// see http://www.mjmwired.net/kernel/Documentation/input/ for info.
-struct input_event;
-
-// Dream-specific key codes
-#define KEY_DREAM_HOME 102 // = KEY_HOME
-#define KEY_DREAM_RED 107 // = KEY_END
-#define KEY_DREAM_VOLUMEDOWN 114 // = KEY_VOLUMEDOWN
-#define KEY_DREAM_VOLUMEUP 115 // = KEY_VOLUMEUP
-#define KEY_DREAM_SYM 127 // = KEY_COMPOSE
-#define KEY_DREAM_MENU 139 // = KEY_MENU
-#define KEY_DREAM_BACK 158 // = KEY_BACK
-#define KEY_DREAM_FOCUS 211 // = KEY_HP (light touch on camera)
-#define KEY_DREAM_CAMERA 212 // = KEY_CAMERA
-#define KEY_DREAM_AT 215 // = KEY_EMAIL
-#define KEY_DREAM_GREEN 231
-#define KEY_DREAM_FATTOUCH 258 // = BTN_2 ???
-#define KEY_DREAM_BALL 272 // = BTN_MOUSE
-#define KEY_DREAM_TOUCH 330 // = BTN_TOUCH
-
-int ev_init(void);
-void ev_exit(void);
-int ev_get(struct input_event *ev, unsigned dont_wait);
-
-// Resources
-
-// Returns 0 if no error, else negative.
-int res_create_surface(const char* name, gr_surface* pSurface);
-void res_free_surface(gr_surface surface);
-
-#endif
diff --git a/minui/mkfont.c b/minui/mkfont.c
deleted file mode 100644
index 61a5ede..0000000
--- a/minui/mkfont.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-
-int main(int argc, char *argv)
-{
- unsigned n;
- unsigned char *x;
- unsigned m;
- unsigned run_val;
- unsigned run_count;
-
- n = gimp_image.width * gimp_image.height;
- m = 0;
- x = gimp_image.pixel_data;
-
- printf("struct {\n");
- printf(" unsigned width;\n");
- printf(" unsigned height;\n");
- printf(" unsigned cwidth;\n");
- printf(" unsigned cheight;\n");
- printf(" unsigned char rundata[];\n");
- printf("} font = {\n");
- printf(" .width = %d,\n .height = %d,\n .cwidth = %d,\n .cheight = %d,\n", gimp_image.width, gimp_image.height,
- gimp_image.width / 96, gimp_image.height);
- printf(" .rundata = {\n");
-
- run_val = (*x ? 0 : 255);
- run_count = 1;
- n--;
- x+=3;
-
- while(n-- > 0) {
- unsigned val = (*x ? 0 : 255);
- x+=3;
- if((val == run_val) && (run_count < 127)) {
- run_count++;
- } else {
-eject:
- printf("0x%02x,",run_count | (run_val ? 0x80 : 0x00));
- run_val = val;
- run_count = 1;
- m += 5;
- if(m >= 75) {
- printf("\n");
- m = 0;
- }
- }
- }
- printf("0x%02x,",run_count | (run_val ? 0x80 : 0x00));
- printf("\n0x00,");
- printf("\n");
- printf(" }\n};\n");
- return 0;
-}
diff --git a/minui/resources.c b/minui/resources.c
deleted file mode 100644
index 5beb6a6..0000000
--- a/minui/resources.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-
-#include <linux/fb.h>
-#include <linux/kd.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "minui.h"
-
-// File signature for BMP files.
-// The letters 'BM' as a little-endian unsigned short.
-
-#define BMP_SIGNATURE 0x4d42
-
-typedef struct {
- // constant, value should equal BMP_SIGNATURE
- unsigned short bfType;
- // size of the file in bytes.
- unsigned long bfSize;
- // must always be set to zero.
- unsigned short bfReserved1;
- // must always be set to zero.
- unsigned short bfReserved2;
- // offset from the beginning of the file to the bitmap data.
- unsigned long bfOffBits;
-
- // The BITMAPINFOHEADER:
- // size of the BITMAPINFOHEADER structure, in bytes.
- unsigned long biSize;
- // width of the image, in pixels.
- unsigned long biWidth;
- // height of the image, in pixels.
- unsigned long biHeight;
- // number of planes of the target device, must be set to 1.
- unsigned short biPlanes;
- // number of bits per pixel.
- unsigned short biBitCount;
- // type of compression, zero means no compression.
- unsigned long biCompression;
- // size of the image data, in bytes. If there is no compression,
- // it is valid to set this member to zero.
- unsigned long biSizeImage;
- // horizontal pixels per meter on the designated targer device,
- // usually set to zero.
- unsigned long biXPelsPerMeter;
- // vertical pixels per meter on the designated targer device,
- // usually set to zero.
- unsigned long biYPelsPerMeter;
- // number of colors used in the bitmap, if set to zero the
- // number of colors is calculated using the biBitCount member.
- unsigned long biClrUsed;
- // number of color that are 'important' for the bitmap,
- // if set to zero, all colors are important.
- unsigned long biClrImportant;
-} __attribute__((packed)) BitMapFileHeader;
-
-int res_create_surface(const char* name, gr_surface* pSurface) {
- char resPath[256];
- BitMapFileHeader header;
- GGLSurface* surface = NULL;
- int result = 0;
-
- snprintf(resPath, sizeof(resPath)-1, "/res/images/%s.bmp", name);
- resPath[sizeof(resPath)-1] = '\0';
- int fd = open(resPath, O_RDONLY);
- if (fd == -1) {
- result = -1;
- goto exit;
- }
- size_t bytesRead = read(fd, &header, sizeof(header));
- if (bytesRead != sizeof(header)) {
- result = -2;
- goto exit;
- }
- if (header.bfType != BMP_SIGNATURE) {
- result = -3; // Not a legal header
- goto exit;
- }
- if (header.biPlanes != 1) {
- result = -4;
- goto exit;
- }
- if (!(header.biBitCount == 24 || header.biBitCount == 32)) {
- result = -5;
- goto exit;
- }
- if (header.biCompression != 0) {
- result = -6;
- goto exit;
- }
- size_t width = header.biWidth;
- size_t height = header.biHeight;
- size_t stride = 4 * width;
- size_t pixelSize = stride * height;
-
- surface = malloc(sizeof(GGLSurface) + pixelSize);
- if (surface == NULL) {
- result = -7;
- goto exit;
- }
- unsigned char* pData = (unsigned char*) (surface + 1);
- surface->version = sizeof(GGLSurface);
- surface->width = width;
- surface->height = height;
- surface->stride = width; /* Yes, pixels, not bytes */
- surface->data = pData;
- surface->format = (header.biBitCount == 24) ?
- GGL_PIXEL_FORMAT_RGBX_8888 : GGL_PIXEL_FORMAT_RGBA_8888;
-
- // Source pixel bytes are stored B G R {A}
-
- lseek(fd, header.bfOffBits, SEEK_SET);
- size_t y;
- if (header.biBitCount == 24) { // RGB
- size_t inputStride = (((3 * width + 3) >> 2) << 2);
- for (y = 0; y < height; y++) {
- unsigned char* pRow = pData + (height - (y + 1)) * stride;
- bytesRead = read(fd, pRow, inputStride);
- if (bytesRead != inputStride) {
- result = -8;
- goto exit;
- }
- int x;
- for(x = width - 1; x >= 0; x--) {
- int sx = x * 3;
- int dx = x * 4;
- unsigned char b = pRow[sx];
- unsigned char g = pRow[sx + 1];
- unsigned char r = pRow[sx + 2];
- unsigned char a = 0xff;
- pRow[dx ] = r; // r
- pRow[dx + 1] = g; // g
- pRow[dx + 2] = b; // b;
- pRow[dx + 3] = a;
- }
- }
- } else { // RGBA
- for (y = 0; y < height; y++) {
- unsigned char* pRow = pData + (height - (y + 1)) * stride;
- bytesRead = read(fd, pRow, stride);
- if (bytesRead != stride) {
- result = -9;
- goto exit;
- }
- size_t x;
- for(x = 0; x < width; x++) {
- size_t xx = x * 4;
- unsigned char b = pRow[xx];
- unsigned char g = pRow[xx + 1];
- unsigned char r = pRow[xx + 2];
- unsigned char a = pRow[xx + 3];
- pRow[xx ] = r;
- pRow[xx + 1] = g;
- pRow[xx + 2] = b;
- pRow[xx + 3] = a;
- }
- }
- }
- *pSurface = (gr_surface) surface;
-
-exit:
- if (fd >= 0) {
- close(fd);
- }
- if (result < 0) {
- if (surface) {
- free(surface);
- }
- }
- return result;
-}
-
-void res_free_surface(gr_surface surface) {
- GGLSurface* pSurface = (GGLSurface*) surface;
- if (pSurface) {
- free(pSurface);
- }
-}
diff --git a/minzip/Android.mk b/minzip/Android.mk
deleted file mode 100644
index b1ee674..0000000
--- a/minzip/Android.mk
+++ /dev/null
@@ -1,19 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- Hash.c \
- SysUtil.c \
- DirUtil.c \
- Inlines.c \
- Zip.c
-
-LOCAL_C_INCLUDES += \
- external/zlib \
- external/safe-iop/include
-
-LOCAL_MODULE := libminzip
-
-LOCAL_CFLAGS += -Wall
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/minzip/Bits.h b/minzip/Bits.h
deleted file mode 100644
index f96e6c4..0000000
--- a/minzip/Bits.h
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Some handy functions for manipulating bits and bytes.
- */
-#ifndef _MINZIP_BITS
-#define _MINZIP_BITS
-
-#include "inline_magic.h"
-
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * Get 1 byte. (Included to make the code more legible.)
- */
-INLINE unsigned char get1(unsigned const char* pSrc)
-{
- return *pSrc;
-}
-
-/*
- * Get 2 big-endian bytes.
- */
-INLINE unsigned short get2BE(unsigned char const* pSrc)
-{
- unsigned short result;
-
- result = *pSrc++ << 8;
- result |= *pSrc++;
-
- return result;
-}
-
-/*
- * Get 4 big-endian bytes.
- */
-INLINE unsigned int get4BE(unsigned char const* pSrc)
-{
- unsigned int result;
-
- result = *pSrc++ << 24;
- result |= *pSrc++ << 16;
- result |= *pSrc++ << 8;
- result |= *pSrc++;
-
- return result;
-}
-
-/*
- * Get 8 big-endian bytes.
- */
-INLINE unsigned long long get8BE(unsigned char const* pSrc)
-{
- unsigned long long result;
-
- result = (unsigned long long) *pSrc++ << 56;
- result |= (unsigned long long) *pSrc++ << 48;
- result |= (unsigned long long) *pSrc++ << 40;
- result |= (unsigned long long) *pSrc++ << 32;
- result |= (unsigned long long) *pSrc++ << 24;
- result |= (unsigned long long) *pSrc++ << 16;
- result |= (unsigned long long) *pSrc++ << 8;
- result |= (unsigned long long) *pSrc++;
-
- return result;
-}
-
-/*
- * Get 2 little-endian bytes.
- */
-INLINE unsigned short get2LE(unsigned char const* pSrc)
-{
- unsigned short result;
-
- result = *pSrc++;
- result |= *pSrc++ << 8;
-
- return result;
-}
-
-/*
- * Get 4 little-endian bytes.
- */
-INLINE unsigned int get4LE(unsigned char const* pSrc)
-{
- unsigned int result;
-
- result = *pSrc++;
- result |= *pSrc++ << 8;
- result |= *pSrc++ << 16;
- result |= *pSrc++ << 24;
-
- return result;
-}
-
-/*
- * Get 8 little-endian bytes.
- */
-INLINE unsigned long long get8LE(unsigned char const* pSrc)
-{
- unsigned long long result;
-
- result = (unsigned long long) *pSrc++;
- result |= (unsigned long long) *pSrc++ << 8;
- result |= (unsigned long long) *pSrc++ << 16;
- result |= (unsigned long long) *pSrc++ << 24;
- result |= (unsigned long long) *pSrc++ << 32;
- result |= (unsigned long long) *pSrc++ << 40;
- result |= (unsigned long long) *pSrc++ << 48;
- result |= (unsigned long long) *pSrc++ << 56;
-
- return result;
-}
-
-/*
- * Grab 1 byte and advance the data pointer.
- */
-INLINE unsigned char read1(unsigned const char** ppSrc)
-{
- return *(*ppSrc)++;
-}
-
-/*
- * Grab 2 big-endian bytes and advance the data pointer.
- */
-INLINE unsigned short read2BE(unsigned char const** ppSrc)
-{
- unsigned short result;
-
- result = *(*ppSrc)++ << 8;
- result |= *(*ppSrc)++;
-
- return result;
-}
-
-/*
- * Grab 4 big-endian bytes and advance the data pointer.
- */
-INLINE unsigned int read4BE(unsigned char const** ppSrc)
-{
- unsigned int result;
-
- result = *(*ppSrc)++ << 24;
- result |= *(*ppSrc)++ << 16;
- result |= *(*ppSrc)++ << 8;
- result |= *(*ppSrc)++;
-
- return result;
-}
-
-/*
- * Get 8 big-endian bytes.
- */
-INLINE unsigned long long read8BE(unsigned char const** ppSrc)
-{
- unsigned long long result;
-
- result = (unsigned long long) *(*ppSrc)++ << 56;
- result |= (unsigned long long) *(*ppSrc)++ << 48;
- result |= (unsigned long long) *(*ppSrc)++ << 40;
- result |= (unsigned long long) *(*ppSrc)++ << 32;
- result |= (unsigned long long) *(*ppSrc)++ << 24;
- result |= (unsigned long long) *(*ppSrc)++ << 16;
- result |= (unsigned long long) *(*ppSrc)++ << 8;
- result |= (unsigned long long) *(*ppSrc)++;
-
- return result;
-}
-
-/*
- * Grab 2 little-endian bytes and advance the data pointer.
- */
-INLINE unsigned short read2LE(unsigned char const** ppSrc)
-{
- unsigned short result;
-
- result = *(*ppSrc)++;
- result |= *(*ppSrc)++ << 8;
-
- return result;
-}
-
-/*
- * Grab 4 little-endian bytes and advance the data pointer.
- */
-INLINE unsigned int read4LE(unsigned char const** ppSrc)
-{
- unsigned int result;
-
- result = *(*ppSrc)++;
- result |= *(*ppSrc)++ << 8;
- result |= *(*ppSrc)++ << 16;
- result |= *(*ppSrc)++ << 24;
-
- return result;
-}
-
-/*
- * Get 8 little-endian bytes.
- */
-INLINE unsigned long long read8LE(unsigned char const** ppSrc)
-{
- unsigned long long result;
-
- result = (unsigned long long) *(*ppSrc)++;
- result |= (unsigned long long) *(*ppSrc)++ << 8;
- result |= (unsigned long long) *(*ppSrc)++ << 16;
- result |= (unsigned long long) *(*ppSrc)++ << 24;
- result |= (unsigned long long) *(*ppSrc)++ << 32;
- result |= (unsigned long long) *(*ppSrc)++ << 40;
- result |= (unsigned long long) *(*ppSrc)++ << 48;
- result |= (unsigned long long) *(*ppSrc)++ << 56;
-
- return result;
-}
-
-/*
- * Skip over a UTF-8 string.
- */
-INLINE void skipUtf8String(unsigned char const** ppSrc)
-{
- unsigned int length = read4BE(ppSrc);
-
- (*ppSrc) += length;
-}
-
-/*
- * Read a UTF-8 string into a fixed-size buffer, and null-terminate it.
- *
- * Returns the length of the original string.
- */
-INLINE int readUtf8String(unsigned char const** ppSrc, char* buf, size_t bufLen)
-{
- unsigned int length = read4BE(ppSrc);
- size_t copyLen = (length < bufLen) ? length : bufLen-1;
-
- memcpy(buf, *ppSrc, copyLen);
- buf[copyLen] = '\0';
-
- (*ppSrc) += length;
- return length;
-}
-
-/*
- * Read a UTF-8 string into newly-allocated storage, and null-terminate it.
- *
- * Returns the string and its length. (The latter is probably unnecessary
- * for the way we're using UTF8.)
- */
-INLINE char* readNewUtf8String(unsigned char const** ppSrc, size_t* pLength)
-{
- unsigned int length = read4BE(ppSrc);
- char* buf;
-
- buf = (char*) malloc(length+1);
-
- memcpy(buf, *ppSrc, length);
- buf[length] = '\0';
-
- (*ppSrc) += length;
-
- *pLength = length;
- return buf;
-}
-
-
-/*
- * Set 1 byte. (Included to make the code more legible.)
- */
-INLINE void set1(unsigned char* buf, unsigned char val)
-{
- *buf = (unsigned char)(val);
-}
-
-/*
- * Set 2 big-endian bytes.
- */
-INLINE void set2BE(unsigned char* buf, unsigned short val)
-{
- *buf++ = (unsigned char)(val >> 8);
- *buf = (unsigned char)(val);
-}
-
-/*
- * Set 4 big-endian bytes.
- */
-INLINE void set4BE(unsigned char* buf, unsigned int val)
-{
- *buf++ = (unsigned char)(val >> 24);
- *buf++ = (unsigned char)(val >> 16);
- *buf++ = (unsigned char)(val >> 8);
- *buf = (unsigned char)(val);
-}
-
-/*
- * Set 8 big-endian bytes.
- */
-INLINE void set8BE(unsigned char* buf, unsigned long long val)
-{
- *buf++ = (unsigned char)(val >> 56);
- *buf++ = (unsigned char)(val >> 48);
- *buf++ = (unsigned char)(val >> 40);
- *buf++ = (unsigned char)(val >> 32);
- *buf++ = (unsigned char)(val >> 24);
- *buf++ = (unsigned char)(val >> 16);
- *buf++ = (unsigned char)(val >> 8);
- *buf = (unsigned char)(val);
-}
-
-/*
- * Set 2 little-endian bytes.
- */
-INLINE void set2LE(unsigned char* buf, unsigned short val)
-{
- *buf++ = (unsigned char)(val);
- *buf = (unsigned char)(val >> 8);
-}
-
-/*
- * Set 4 little-endian bytes.
- */
-INLINE void set4LE(unsigned char* buf, unsigned int val)
-{
- *buf++ = (unsigned char)(val);
- *buf++ = (unsigned char)(val >> 8);
- *buf++ = (unsigned char)(val >> 16);
- *buf = (unsigned char)(val >> 24);
-}
-
-/*
- * Set 8 little-endian bytes.
- */
-INLINE void set8LE(unsigned char* buf, unsigned long long val)
-{
- *buf++ = (unsigned char)(val);
- *buf++ = (unsigned char)(val >> 8);
- *buf++ = (unsigned char)(val >> 16);
- *buf++ = (unsigned char)(val >> 24);
- *buf++ = (unsigned char)(val >> 32);
- *buf++ = (unsigned char)(val >> 40);
- *buf++ = (unsigned char)(val >> 48);
- *buf = (unsigned char)(val >> 56);
-}
-
-/*
- * Stuff a UTF-8 string into the buffer.
- */
-INLINE void setUtf8String(unsigned char* buf, const unsigned char* str)
-{
- unsigned int strLen = strlen((const char*)str);
-
- set4BE(buf, strLen);
- memcpy(buf + sizeof(unsigned int), str, strLen);
-}
-
-#endif /*_MINZIP_BITS*/
diff --git a/minzip/DirUtil.c b/minzip/DirUtil.c
deleted file mode 100644
index 20c89cd..0000000
--- a/minzip/DirUtil.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <dirent.h>
-#include <limits.h>
-
-#include "DirUtil.h"
-
-typedef enum { DMISSING, DDIR, DILLEGAL } DirStatus;
-
-static DirStatus
-getPathDirStatus(const char *path)
-{
- struct stat st;
- int err;
-
- err = stat(path, &st);
- if (err == 0) {
- /* Something's there; make sure it's a directory.
- */
- if (S_ISDIR(st.st_mode)) {
- return DDIR;
- }
- errno = ENOTDIR;
- return DILLEGAL;
- } else if (errno != ENOENT) {
- /* Something went wrong, or something in the path
- * is bad. Can't do anything in this situation.
- */
- return DILLEGAL;
- }
- return DMISSING;
-}
-
-int
-dirCreateHierarchy(const char *path, int mode,
- const struct utimbuf *timestamp, bool stripFileName)
-{
- DirStatus ds;
-
- /* Check for an empty string before we bother
- * making any syscalls.
- */
- if (path[0] == '\0') {
- errno = ENOENT;
- return -1;
- }
-
- /* Allocate a path that we can modify; stick a slash on
- * the end to make things easier.
- */
- size_t pathLen = strlen(path);
- char *cpath = (char *)malloc(pathLen + 2);
- if (cpath == NULL) {
- errno = ENOMEM;
- return -1;
- }
- memcpy(cpath, path, pathLen);
- if (stripFileName) {
- /* Strip everything after the last slash.
- */
- char *c = cpath + pathLen - 1;
- while (c != cpath && *c != '/') {
- c--;
- }
- if (c == cpath) {
-//xxx test this path
- /* No directory component. Act like the path was empty.
- */
- errno = ENOENT;
- free(cpath);
- return -1;
- }
- c[1] = '\0'; // Terminate after the slash we found.
- } else {
- /* Make sure that the path ends in a slash.
- */
- cpath[pathLen] = '/';
- cpath[pathLen + 1] = '\0';
- }
-
- /* See if it already exists.
- */
- ds = getPathDirStatus(cpath);
- if (ds == DDIR) {
- return 0;
- } else if (ds == DILLEGAL) {
- return -1;
- }
-
- /* Walk up the path from the root and make each level.
- * If a directory already exists, no big deal.
- */
- char *p = cpath;
- while (*p != '\0') {
- /* Skip any slashes, watching out for the end of the string.
- */
- while (*p != '\0' && *p == '/') {
- p++;
- }
- if (*p == '\0') {
- break;
- }
-
- /* Find the end of the next path component.
- * We know that we'll see a slash before the NUL,
- * because we added it, above.
- */
- while (*p != '/') {
- p++;
- }
- *p = '\0';
-
- /* Check this part of the path and make a new directory
- * if necessary.
- */
- ds = getPathDirStatus(cpath);
- if (ds == DILLEGAL) {
- /* Could happen if some other process/thread is
- * messing with the filesystem.
- */
- free(cpath);
- return -1;
- } else if (ds == DMISSING) {
- int err;
-
- err = mkdir(cpath, mode);
- if (err != 0) {
- free(cpath);
- return -1;
- }
- if (timestamp != NULL && utime(cpath, timestamp)) {
- free(cpath);
- return -1;
- }
- }
- // else, this directory already exists.
-
- /* Repair the path and continue.
- */
- *p = '/';
- }
- free(cpath);
-
- return 0;
-}
-
-int
-dirUnlinkHierarchy(const char *path)
-{
- struct stat st;
- DIR *dir;
- struct dirent *de;
- int fail = 0;
-
- /* is it a file or directory? */
- if (lstat(path, &st) < 0) {
- return -1;
- }
-
- /* a file, so unlink it */
- if (!S_ISDIR(st.st_mode)) {
- return unlink(path);
- }
-
- /* a directory, so open handle */
- dir = opendir(path);
- if (dir == NULL) {
- return -1;
- }
-
- /* recurse over components */
- errno = 0;
- while ((de = readdir(dir)) != NULL) {
-//TODO: don't blow the stack
- char dn[PATH_MAX];
- if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) {
- continue;
- }
- snprintf(dn, sizeof(dn), "%s/%s", path, de->d_name);
- if (dirUnlinkHierarchy(dn) < 0) {
- fail = 1;
- break;
- }
- errno = 0;
- }
- /* in case readdir or unlink_recursive failed */
- if (fail || errno < 0) {
- int save = errno;
- closedir(dir);
- errno = save;
- return -1;
- }
-
- /* close directory handle */
- if (closedir(dir) < 0) {
- return -1;
- }
-
- /* delete target directory */
- return rmdir(path);
-}
-
-int
-dirSetHierarchyPermissions(const char *path,
- int uid, int gid, int dirMode, int fileMode)
-{
- struct stat st;
- if (lstat(path, &st)) {
- return -1;
- }
-
- /* ignore symlinks */
- if (S_ISLNK(st.st_mode)) {
- return 0;
- }
-
- /* directories and files get different permissions */
- if (chown(path, uid, gid) ||
- chmod(path, S_ISDIR(st.st_mode) ? dirMode : fileMode)) {
- return -1;
- }
-
- /* recurse over directory components */
- if (S_ISDIR(st.st_mode)) {
- DIR *dir = opendir(path);
- if (dir == NULL) {
- return -1;
- }
-
- errno = 0;
- const struct dirent *de;
- while (errno == 0 && (de = readdir(dir)) != NULL) {
- if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) {
- continue;
- }
-
- char dn[PATH_MAX];
- snprintf(dn, sizeof(dn), "%s/%s", path, de->d_name);
- if (!dirSetHierarchyPermissions(dn, uid, gid, dirMode, fileMode)) {
- errno = 0;
- } else if (errno == 0) {
- errno = -1;
- }
- }
-
- if (errno != 0) {
- int save = errno;
- closedir(dir);
- errno = save;
- return -1;
- }
-
- if (closedir(dir)) {
- return -1;
- }
- }
-
- return 0;
-}
diff --git a/minzip/DirUtil.h b/minzip/DirUtil.h
deleted file mode 100644
index 5d881f5..0000000
--- a/minzip/DirUtil.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MINZIP_DIRUTIL_H_
-#define MINZIP_DIRUTIL_H_
-
-#include <stdbool.h>
-#include <utime.h>
-
-/* Like "mkdir -p", try to guarantee that all directories
- * specified in path are present, creating as many directories
- * as necessary. The specified mode is passed to all mkdir
- * calls; no modifications are made to umask.
- *
- * If stripFileName is set, everything after the final '/'
- * is stripped before creating the directory hierarchy.
- *
- * If timestamp is non-NULL, new directories will be timestamped accordingly.
- *
- * Returns 0 on success; returns -1 (and sets errno) on failure
- * (usually if some element of path is not a directory).
- */
-int dirCreateHierarchy(const char *path, int mode,
- const struct utimbuf *timestamp, bool stripFileName);
-
-/* rm -rf <path>
- */
-int dirUnlinkHierarchy(const char *path);
-
-/* chown -R <uid>:<gid> <path>
- * chmod -R <mode> <path>
- *
- * Sets directories to <dirMode> and files to <fileMode>. Skips symlinks.
- */
-int dirSetHierarchyPermissions(const char *path,
- int uid, int gid, int dirMode, int fileMode);
-
-#endif // MINZIP_DIRUTIL_H_
diff --git a/minzip/Hash.c b/minzip/Hash.c
deleted file mode 100644
index 8c6ca9b..0000000
--- a/minzip/Hash.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Hash table. The dominant calls are add and lookup, with removals
- * happening very infrequently. We use probing, and don't worry much
- * about tombstone removal.
- */
-#include <stdlib.h>
-#include <assert.h>
-
-#define LOG_TAG "minzip"
-#include "Log.h"
-#include "Hash.h"
-
-/* table load factor, i.e. how full can it get before we resize */
-//#define LOAD_NUMER 3 // 75%
-//#define LOAD_DENOM 4
-#define LOAD_NUMER 5 // 62.5%
-#define LOAD_DENOM 8
-//#define LOAD_NUMER 1 // 50%
-//#define LOAD_DENOM 2
-
-/*
- * Compute the capacity needed for a table to hold "size" elements.
- */
-size_t mzHashSize(size_t size) {
- return (size * LOAD_DENOM) / LOAD_NUMER +1;
-}
-
-/*
- * Round up to the next highest power of 2.
- *
- * Found on http://graphics.stanford.edu/~seander/bithacks.html.
- */
-unsigned int roundUpPower2(unsigned int val)
-{
- val--;
- val |= val >> 1;
- val |= val >> 2;
- val |= val >> 4;
- val |= val >> 8;
- val |= val >> 16;
- val++;
-
- return val;
-}
-
-/*
- * Create and initialize a hash table.
- */
-HashTable* mzHashTableCreate(size_t initialSize, HashFreeFunc freeFunc)
-{
- HashTable* pHashTable;
-
- assert(initialSize > 0);
-
- pHashTable = (HashTable*) malloc(sizeof(*pHashTable));
- if (pHashTable == NULL)
- return NULL;
-
- pHashTable->tableSize = roundUpPower2(initialSize);
- pHashTable->numEntries = pHashTable->numDeadEntries = 0;
- pHashTable->freeFunc = freeFunc;
- pHashTable->pEntries =
- (HashEntry*) calloc((size_t)pHashTable->tableSize, sizeof(HashTable));
- if (pHashTable->pEntries == NULL) {
- free(pHashTable);
- return NULL;
- }
-
- return pHashTable;
-}
-
-/*
- * Clear out all entries.
- */
-void mzHashTableClear(HashTable* pHashTable)
-{
- HashEntry* pEnt;
- int i;
-
- pEnt = pHashTable->pEntries;
- for (i = 0; i < pHashTable->tableSize; i++, pEnt++) {
- if (pEnt->data == HASH_TOMBSTONE) {
- // nuke entry
- pEnt->data = NULL;
- } else if (pEnt->data != NULL) {
- // call free func then nuke entry
- if (pHashTable->freeFunc != NULL)
- (*pHashTable->freeFunc)(pEnt->data);
- pEnt->data = NULL;
- }
- }
-
- pHashTable->numEntries = 0;
- pHashTable->numDeadEntries = 0;
-}
-
-/*
- * Free the table.
- */
-void mzHashTableFree(HashTable* pHashTable)
-{
- if (pHashTable == NULL)
- return;
- mzHashTableClear(pHashTable);
- free(pHashTable->pEntries);
- free(pHashTable);
-}
-
-#ifndef NDEBUG
-/*
- * Count up the number of tombstone entries in the hash table.
- */
-static int countTombStones(HashTable* pHashTable)
-{
- int i, count;
-
- for (count = i = 0; i < pHashTable->tableSize; i++) {
- if (pHashTable->pEntries[i].data == HASH_TOMBSTONE)
- count++;
- }
- return count;
-}
-#endif
-
-/*
- * Resize a hash table. We do this when adding an entry increased the
- * size of the table beyond its comfy limit.
- *
- * This essentially requires re-inserting all elements into the new storage.
- *
- * If multiple threads can access the hash table, the table's lock should
- * have been grabbed before issuing the "lookup+add" call that led to the
- * resize, so we don't have a synchronization problem here.
- */
-static bool resizeHash(HashTable* pHashTable, int newSize)
-{
- HashEntry* pNewEntries;
- int i;
-
- assert(countTombStones(pHashTable) == pHashTable->numDeadEntries);
- //LOGI("before: dead=%d\n", pHashTable->numDeadEntries);
-
- pNewEntries = (HashEntry*) calloc(newSize, sizeof(HashTable));
- if (pNewEntries == NULL)
- return false;
-
- for (i = 0; i < pHashTable->tableSize; i++) {
- void* data = pHashTable->pEntries[i].data;
- if (data != NULL && data != HASH_TOMBSTONE) {
- int hashValue = pHashTable->pEntries[i].hashValue;
- int newIdx;
-
- /* probe for new spot, wrapping around */
- newIdx = hashValue & (newSize-1);
- while (pNewEntries[newIdx].data != NULL)
- newIdx = (newIdx + 1) & (newSize-1);
-
- pNewEntries[newIdx].hashValue = hashValue;
- pNewEntries[newIdx].data = data;
- }
- }
-
- free(pHashTable->pEntries);
- pHashTable->pEntries = pNewEntries;
- pHashTable->tableSize = newSize;
- pHashTable->numDeadEntries = 0;
-
- assert(countTombStones(pHashTable) == 0);
- return true;
-}
-
-/*
- * Look up an entry.
- *
- * We probe on collisions, wrapping around the table.
- */
-void* mzHashTableLookup(HashTable* pHashTable, unsigned int itemHash, void* item,
- HashCompareFunc cmpFunc, bool doAdd)
-{
- HashEntry* pEntry;
- HashEntry* pEnd;
- void* result = NULL;
-
- assert(pHashTable->tableSize > 0);
- assert(item != HASH_TOMBSTONE);
- assert(item != NULL);
-
- /* jump to the first entry and probe for a match */
- pEntry = &pHashTable->pEntries[itemHash & (pHashTable->tableSize-1)];
- pEnd = &pHashTable->pEntries[pHashTable->tableSize];
- while (pEntry->data != NULL) {
- if (pEntry->data != HASH_TOMBSTONE &&
- pEntry->hashValue == itemHash &&
- (*cmpFunc)(pEntry->data, item) == 0)
- {
- /* match */
- //LOGD("+++ match on entry %d\n", pEntry - pHashTable->pEntries);
- break;
- }
-
- pEntry++;
- if (pEntry == pEnd) { /* wrap around to start */
- if (pHashTable->tableSize == 1)
- break; /* edge case - single-entry table */
- pEntry = pHashTable->pEntries;
- }
-
- //LOGI("+++ look probing %d...\n", pEntry - pHashTable->pEntries);
- }
-
- if (pEntry->data == NULL) {
- if (doAdd) {
- pEntry->hashValue = itemHash;
- pEntry->data = item;
- pHashTable->numEntries++;
-
- /*
- * We've added an entry. See if this brings us too close to full.
- */
- if ((pHashTable->numEntries+pHashTable->numDeadEntries) * LOAD_DENOM
- > pHashTable->tableSize * LOAD_NUMER)
- {
- if (!resizeHash(pHashTable, pHashTable->tableSize * 2)) {
- /* don't really have a way to indicate failure */
- LOGE("Dalvik hash resize failure\n");
- abort();
- }
- /* note "pEntry" is now invalid */
- } else {
- //LOGW("okay %d/%d/%d\n",
- // pHashTable->numEntries, pHashTable->tableSize,
- // (pHashTable->tableSize * LOAD_NUMER) / LOAD_DENOM);
- }
-
- /* full table is bad -- search for nonexistent never halts */
- assert(pHashTable->numEntries < pHashTable->tableSize);
- result = item;
- } else {
- assert(result == NULL);
- }
- } else {
- result = pEntry->data;
- }
-
- return result;
-}
-
-/*
- * Remove an entry from the table.
- *
- * Does NOT invoke the "free" function on the item.
- */
-bool mzHashTableRemove(HashTable* pHashTable, unsigned int itemHash, void* item)
-{
- HashEntry* pEntry;
- HashEntry* pEnd;
-
- assert(pHashTable->tableSize > 0);
-
- /* jump to the first entry and probe for a match */
- pEntry = &pHashTable->pEntries[itemHash & (pHashTable->tableSize-1)];
- pEnd = &pHashTable->pEntries[pHashTable->tableSize];
- while (pEntry->data != NULL) {
- if (pEntry->data == item) {
- //LOGI("+++ stepping on entry %d\n", pEntry - pHashTable->pEntries);
- pEntry->data = HASH_TOMBSTONE;
- pHashTable->numEntries--;
- pHashTable->numDeadEntries++;
- return true;
- }
-
- pEntry++;
- if (pEntry == pEnd) { /* wrap around to start */
- if (pHashTable->tableSize == 1)
- break; /* edge case - single-entry table */
- pEntry = pHashTable->pEntries;
- }
-
- //LOGI("+++ del probing %d...\n", pEntry - pHashTable->pEntries);
- }
-
- return false;
-}
-
-/*
- * Execute a function on every entry in the hash table.
- *
- * If "func" returns a nonzero value, terminate early and return the value.
- */
-int mzHashForeach(HashTable* pHashTable, HashForeachFunc func, void* arg)
-{
- int i, val;
-
- for (i = 0; i < pHashTable->tableSize; i++) {
- HashEntry* pEnt = &pHashTable->pEntries[i];
-
- if (pEnt->data != NULL && pEnt->data != HASH_TOMBSTONE) {
- val = (*func)(pEnt->data, arg);
- if (val != 0)
- return val;
- }
- }
-
- return 0;
-}
-
-
-/*
- * Look up an entry, counting the number of times we have to probe.
- *
- * Returns -1 if the entry wasn't found.
- */
-int countProbes(HashTable* pHashTable, unsigned int itemHash, const void* item,
- HashCompareFunc cmpFunc)
-{
- HashEntry* pEntry;
- HashEntry* pEnd;
- int count = 0;
-
- assert(pHashTable->tableSize > 0);
- assert(item != HASH_TOMBSTONE);
- assert(item != NULL);
-
- /* jump to the first entry and probe for a match */
- pEntry = &pHashTable->pEntries[itemHash & (pHashTable->tableSize-1)];
- pEnd = &pHashTable->pEntries[pHashTable->tableSize];
- while (pEntry->data != NULL) {
- if (pEntry->data != HASH_TOMBSTONE &&
- pEntry->hashValue == itemHash &&
- (*cmpFunc)(pEntry->data, item) == 0)
- {
- /* match */
- break;
- }
-
- pEntry++;
- if (pEntry == pEnd) { /* wrap around to start */
- if (pHashTable->tableSize == 1)
- break; /* edge case - single-entry table */
- pEntry = pHashTable->pEntries;
- }
-
- count++;
- }
- if (pEntry->data == NULL)
- return -1;
-
- return count;
-}
-
-/*
- * Evaluate the amount of probing required for the specified hash table.
- *
- * We do this by running through all entries in the hash table, computing
- * the hash value and then doing a lookup.
- *
- * The caller should lock the table before calling here.
- */
-void mzHashTableProbeCount(HashTable* pHashTable, HashCalcFunc calcFunc,
- HashCompareFunc cmpFunc)
-{
- int numEntries, minProbe, maxProbe, totalProbe;
- HashIter iter;
-
- numEntries = maxProbe = totalProbe = 0;
- minProbe = 65536*32767;
-
- for (mzHashIterBegin(pHashTable, &iter); !mzHashIterDone(&iter);
- mzHashIterNext(&iter))
- {
- const void* data = (const void*)mzHashIterData(&iter);
- int count;
-
- count = countProbes(pHashTable, (*calcFunc)(data), data, cmpFunc);
-
- numEntries++;
-
- if (count < minProbe)
- minProbe = count;
- if (count > maxProbe)
- maxProbe = count;
- totalProbe += count;
- }
-
- LOGI("Probe: min=%d max=%d, total=%d in %d (%d), avg=%.3f\n",
- minProbe, maxProbe, totalProbe, numEntries, pHashTable->tableSize,
- (float) totalProbe / (float) numEntries);
-}
diff --git a/minzip/Hash.h b/minzip/Hash.h
deleted file mode 100644
index 8194537..0000000
--- a/minzip/Hash.h
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright 2007 The Android Open Source Project
- *
- * General purpose hash table, used for finding classes, methods, etc.
- *
- * When the number of elements reaches 3/4 of the table's capacity, the
- * table will be resized.
- */
-#ifndef _MINZIP_HASH
-#define _MINZIP_HASH
-
-#include "inline_magic.h"
-
-#include <stdlib.h>
-#include <stdbool.h>
-#include <assert.h>
-
-/* compute the hash of an item with a specific type */
-typedef unsigned int (*HashCompute)(const void* item);
-
-/*
- * Compare a hash entry with a "loose" item after their hash values match.
- * Returns { <0, 0, >0 } depending on ordering of items (same semantics
- * as strcmp()).
- */
-typedef int (*HashCompareFunc)(const void* tableItem, const void* looseItem);
-
-/*
- * This function will be used to free entries in the table. This can be
- * NULL if no free is required, free(), or a custom function.
- */
-typedef void (*HashFreeFunc)(void* ptr);
-
-/*
- * Used by mzHashForeach().
- */
-typedef int (*HashForeachFunc)(void* data, void* arg);
-
-/*
- * One entry in the hash table. "data" values are expected to be (or have
- * the same characteristics as) valid pointers. In particular, a NULL
- * value for "data" indicates an empty slot, and HASH_TOMBSTONE indicates
- * a no-longer-used slot that must be stepped over during probing.
- *
- * Attempting to add a NULL or tombstone value is an error.
- *
- * When an entry is released, we will call (HashFreeFunc)(entry->data).
- */
-typedef struct HashEntry {
- unsigned int hashValue;
- void* data;
-} HashEntry;
-
-#define HASH_TOMBSTONE ((void*) 0xcbcacccd) // invalid ptr value
-
-/*
- * Expandable hash table.
- *
- * This structure should be considered opaque.
- */
-typedef struct HashTable {
- int tableSize; /* must be power of 2 */
- int numEntries; /* current #of "live" entries */
- int numDeadEntries; /* current #of tombstone entries */
- HashEntry* pEntries; /* array on heap */
- HashFreeFunc freeFunc;
-} HashTable;
-
-/*
- * Create and initialize a HashTable structure, using "initialSize" as
- * a basis for the initial capacity of the table. (The actual initial
- * table size may be adjusted upward.) If you know exactly how many
- * elements the table will hold, pass the result from mzHashSize() in.)
- *
- * Returns "false" if unable to allocate the table.
- */
-HashTable* mzHashTableCreate(size_t initialSize, HashFreeFunc freeFunc);
-
-/*
- * Compute the capacity needed for a table to hold "size" elements. Use
- * this when you know ahead of time how many elements the table will hold.
- * Pass this value into mzHashTableCreate() to ensure that you can add
- * all elements without needing to reallocate the table.
- */
-size_t mzHashSize(size_t size);
-
-/*
- * Clear out a hash table, freeing the contents of any used entries.
- */
-void mzHashTableClear(HashTable* pHashTable);
-
-/*
- * Free a hash table.
- */
-void mzHashTableFree(HashTable* pHashTable);
-
-/*
- * Get #of entries in hash table.
- */
-INLINE int mzHashTableNumEntries(HashTable* pHashTable) {
- return pHashTable->numEntries;
-}
-
-/*
- * Get total size of hash table (for memory usage calculations).
- */
-INLINE int mzHashTableMemUsage(HashTable* pHashTable) {
- return sizeof(HashTable) + pHashTable->tableSize * sizeof(HashEntry);
-}
-
-/*
- * Look up an entry in the table, possibly adding it if it's not there.
- *
- * If "item" is not found, and "doAdd" is false, NULL is returned.
- * Otherwise, a pointer to the found or added item is returned. (You can
- * tell the difference by seeing if return value == item.)
- *
- * An "add" operation may cause the entire table to be reallocated.
- */
-void* mzHashTableLookup(HashTable* pHashTable, unsigned int itemHash, void* item,
- HashCompareFunc cmpFunc, bool doAdd);
-
-/*
- * Remove an item from the hash table, given its "data" pointer. Does not
- * invoke the "free" function; just detaches it from the table.
- */
-bool mzHashTableRemove(HashTable* pHashTable, unsigned int hash, void* item);
-
-/*
- * Execute "func" on every entry in the hash table.
- *
- * If "func" returns a nonzero value, terminate early and return the value.
- */
-int mzHashForeach(HashTable* pHashTable, HashForeachFunc func, void* arg);
-
-/*
- * An alternative to mzHashForeach(), using an iterator.
- *
- * Use like this:
- * HashIter iter;
- * for (mzHashIterBegin(hashTable, &iter); !mzHashIterDone(&iter);
- * mzHashIterNext(&iter))
- * {
- * MyData* data = (MyData*)mzHashIterData(&iter);
- * }
- */
-typedef struct HashIter {
- void* data;
- HashTable* pHashTable;
- int idx;
-} HashIter;
-INLINE void mzHashIterNext(HashIter* pIter) {
- int i = pIter->idx +1;
- int lim = pIter->pHashTable->tableSize;
- for ( ; i < lim; i++) {
- void* data = pIter->pHashTable->pEntries[i].data;
- if (data != NULL && data != HASH_TOMBSTONE)
- break;
- }
- pIter->idx = i;
-}
-INLINE void mzHashIterBegin(HashTable* pHashTable, HashIter* pIter) {
- pIter->pHashTable = pHashTable;
- pIter->idx = -1;
- mzHashIterNext(pIter);
-}
-INLINE bool mzHashIterDone(HashIter* pIter) {
- return (pIter->idx >= pIter->pHashTable->tableSize);
-}
-INLINE void* mzHashIterData(HashIter* pIter) {
- assert(pIter->idx >= 0 && pIter->idx < pIter->pHashTable->tableSize);
- return pIter->pHashTable->pEntries[pIter->idx].data;
-}
-
-
-/*
- * Evaluate hash table performance by examining the number of times we
- * have to probe for an entry.
- *
- * The caller should lock the table beforehand.
- */
-typedef unsigned int (*HashCalcFunc)(const void* item);
-void mzHashTableProbeCount(HashTable* pHashTable, HashCalcFunc calcFunc,
- HashCompareFunc cmpFunc);
-
-#endif /*_MINZIP_HASH*/
diff --git a/minzip/Inlines.c b/minzip/Inlines.c
deleted file mode 100644
index 91f8775..0000000
--- a/minzip/Inlines.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Make sure that non-inlined versions of INLINED-marked functions
- * exist so that debug builds (which don't generally do inlining)
- * don't break.
- */
-#define MINZIP_GENERATE_INLINES 1
-#include "Bits.h"
-#include "Hash.h"
-#include "SysUtil.h"
-#include "Zip.h"
diff --git a/minzip/Log.h b/minzip/Log.h
deleted file mode 100644
index 36e62f5..0000000
--- a/minzip/Log.h
+++ /dev/null
@@ -1,207 +0,0 @@
-//
-// Copyright 2005 The Android Open Source Project
-//
-// C/C++ logging functions. See the logging documentation for API details.
-//
-// We'd like these to be available from C code (in case we import some from
-// somewhere), so this has a C interface.
-//
-// The output will be correct when the log file is shared between multiple
-// threads and/or multiple processes so long as the operating system
-// supports O_APPEND. These calls have mutex-protected data structures
-// and so are NOT reentrant. Do not use LOG in a signal handler.
-//
-#ifndef _MINZIP_LOG_H
-#define _MINZIP_LOG_H
-
-#include <stdio.h>
-
-// ---------------------------------------------------------------------
-
-/*
- * Normally we strip LOGV (VERBOSE messages) from release builds.
- * You can modify this (for example with "#define LOG_NDEBUG 0"
- * at the top of your source file) to change that behavior.
- */
-#ifndef LOG_NDEBUG
-#ifdef NDEBUG
-#define LOG_NDEBUG 1
-#else
-#define LOG_NDEBUG 0
-#endif
-#endif
-
-/*
- * This is the local tag used for the following simplified
- * logging macros. You can change this preprocessor definition
- * before using the other macros to change the tag.
- */
-#ifndef LOG_TAG
-#define LOG_TAG NULL
-#endif
-
-// ---------------------------------------------------------------------
-
-/*
- * Simplified macro to send a verbose log message using the current LOG_TAG.
- */
-#ifndef LOGV
-#if LOG_NDEBUG
-#define LOGV(...) ((void)0)
-#else
-#define LOGV(...) ((void)LOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
-#endif
-#endif
-
-#define CONDITION(cond) (__builtin_expect((cond)!=0, 0))
-
-#ifndef LOGV_IF
-#if LOG_NDEBUG
-#define LOGV_IF(cond, ...) ((void)0)
-#else
-#define LOGV_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)LOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-#endif
-
-#define LOGVV LOGV
-#define LOGVV_IF LOGV_IF
-
-/*
- * Simplified macro to send a debug log message using the current LOG_TAG.
- */
-#ifndef LOGD
-#define LOGD(...) ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef LOGD_IF
-#define LOGD_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send an info log message using the current LOG_TAG.
- */
-#ifndef LOGI
-#define LOGI(...) ((void)LOG(LOG_INFO, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef LOGI_IF
-#define LOGI_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)LOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send a warning log message using the current LOG_TAG.
- */
-#ifndef LOGW
-#define LOGW(...) ((void)LOG(LOG_WARN, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef LOGW_IF
-#define LOGW_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)LOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-/*
- * Simplified macro to send an error log message using the current LOG_TAG.
- */
-#ifndef LOGE
-#define LOGE(...) ((void)LOG(LOG_ERROR, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef LOGE_IF
-#define LOGE_IF(cond, ...) \
- ( (CONDITION(cond)) \
- ? ((void)LOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \
- : (void)0 )
-#endif
-
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * verbose priority.
- */
-#ifndef IF_LOGV
-#if LOG_NDEBUG
-#define IF_LOGV() if (false)
-#else
-#define IF_LOGV() IF_LOG(LOG_VERBOSE, LOG_TAG)
-#endif
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * debug priority.
- */
-#ifndef IF_LOGD
-#define IF_LOGD() IF_LOG(LOG_DEBUG, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * info priority.
- */
-#ifndef IF_LOGI
-#define IF_LOGI() IF_LOG(LOG_INFO, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * warn priority.
- */
-#ifndef IF_LOGW
-#define IF_LOGW() IF_LOG(LOG_WARN, LOG_TAG)
-#endif
-
-/*
- * Conditional based on whether the current LOG_TAG is enabled at
- * error priority.
- */
-#ifndef IF_LOGE
-#define IF_LOGE() IF_LOG(LOG_ERROR, LOG_TAG)
-#endif
-
-// ---------------------------------------------------------------------
-
-/*
- * Basic log message macro.
- *
- * Example:
- * LOG(LOG_WARN, NULL, "Failed with error %d", errno);
- *
- * The second argument may be NULL or "" to indicate the "global" tag.
- *
- * Non-gcc probably won't have __FUNCTION__. It's not vital. gcc also
- * offers __PRETTY_FUNCTION__, which is rather more than we need.
- */
-#ifndef LOG
-#define LOG(priority, tag, ...) \
- LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
-#endif
-
-/*
- * Log macro that allows you to specify a number for the priority.
- */
-#ifndef LOG_PRI
-#define LOG_PRI(priority, tag, ...) \
- printf(tag ": " __VA_ARGS__)
-#endif
-
-/*
- * Conditional given a desired logging priority and tag.
- */
-#ifndef IF_LOG
-#define IF_LOG(priority, tag) \
- if (1)
-#endif
-
-#endif // _MINZIP_LOG_H
diff --git a/minzip/SysUtil.c b/minzip/SysUtil.c
deleted file mode 100644
index 49a2522..0000000
--- a/minzip/SysUtil.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * System utilities.
- */
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <limits.h>
-#include <errno.h>
-#include <assert.h>
-
-#define LOG_TAG "minzip"
-#include "Log.h"
-#include "SysUtil.h"
-
-/*
- * Having trouble finding a portable way to get this. sysconf(_SC_PAGE_SIZE)
- * seems appropriate, but we don't have that on the device. Some systems
- * have getpagesize(2), though the linux man page has some odd cautions.
- */
-#define DEFAULT_PAGE_SIZE 4096
-
-
-/*
- * Create an anonymous shared memory segment large enough to hold "length"
- * bytes. The actual segment may be larger because mmap() operates on
- * page boundaries (usually 4K).
- */
-static void* sysCreateAnonShmem(size_t length)
-{
- void* ptr;
-
- ptr = mmap(NULL, length, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANON, -1, 0);
- if (ptr == MAP_FAILED) {
- LOGW("mmap(%d, RW, SHARED|ANON) failed: %s\n", (int) length,
- strerror(errno));
- return NULL;
- }
-
- return ptr;
-}
-
-static int getFileStartAndLength(int fd, off_t *start_, size_t *length_)
-{
- off_t start, end;
- size_t length;
-
- assert(start_ != NULL);
- assert(length_ != NULL);
-
- start = lseek(fd, 0L, SEEK_CUR);
- end = lseek(fd, 0L, SEEK_END);
- (void) lseek(fd, start, SEEK_SET);
-
- if (start == (off_t) -1 || end == (off_t) -1) {
- LOGE("could not determine length of file\n");
- return -1;
- }
-
- length = end - start;
- if (length == 0) {
- LOGE("file is empty\n");
- return -1;
- }
-
- *start_ = start;
- *length_ = length;
-
- return 0;
-}
-
-/*
- * Pull the contents of a file into an new shared memory segment. We grab
- * everything from fd's current offset on.
- *
- * We need to know the length ahead of time so we can allocate a segment
- * of sufficient size.
- */
-int sysLoadFileInShmem(int fd, MemMapping* pMap)
-{
- off_t start;
- size_t length, actual;
- void* memPtr;
-
- assert(pMap != NULL);
-
- if (getFileStartAndLength(fd, &start, &length) < 0)
- return -1;
-
- memPtr = sysCreateAnonShmem(length);
- if (memPtr == NULL)
- return -1;
-
- actual = read(fd, memPtr, length);
- if (actual != length) {
- LOGE("only read %d of %d bytes\n", (int) actual, (int) length);
- sysReleaseShmem(pMap);
- return -1;
- }
-
- pMap->baseAddr = pMap->addr = memPtr;
- pMap->baseLength = pMap->length = length;
-
- return 0;
-}
-
-/*
- * Map a file (from fd's current offset) into a shared, read-only memory
- * segment. The file offset must be a multiple of the page size.
- *
- * On success, returns 0 and fills out "pMap". On failure, returns a nonzero
- * value and does not disturb "pMap".
- */
-int sysMapFileInShmem(int fd, MemMapping* pMap)
-{
- off_t start;
- size_t length;
- void* memPtr;
-
- assert(pMap != NULL);
-
- if (getFileStartAndLength(fd, &start, &length) < 0)
- return -1;
-
- memPtr = mmap(NULL, length, PROT_READ, MAP_FILE | MAP_SHARED, fd, start);
- if (memPtr == MAP_FAILED) {
- LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n", (int) length,
- fd, (int) start, strerror(errno));
- return -1;
- }
-
- pMap->baseAddr = pMap->addr = memPtr;
- pMap->baseLength = pMap->length = length;
-
- return 0;
-}
-
-/*
- * Map part of a file (from fd's current offset) into a shared, read-only
- * memory segment.
- *
- * On success, returns 0 and fills out "pMap". On failure, returns a nonzero
- * value and does not disturb "pMap".
- */
-int sysMapFileSegmentInShmem(int fd, off_t start, long length,
- MemMapping* pMap)
-{
- off_t dummy;
- size_t fileLength, actualLength;
- off_t actualStart;
- int adjust;
- void* memPtr;
-
- assert(pMap != NULL);
-
- if (getFileStartAndLength(fd, &dummy, &fileLength) < 0)
- return -1;
-
- if (start + length > (long)fileLength) {
- LOGW("bad segment: st=%d len=%ld flen=%d\n",
- (int) start, length, (int) fileLength);
- return -1;
- }
-
- /* adjust to be page-aligned */
- adjust = start % DEFAULT_PAGE_SIZE;
- actualStart = start - adjust;
- actualLength = length + adjust;
-
- memPtr = mmap(NULL, actualLength, PROT_READ, MAP_FILE | MAP_SHARED,
- fd, actualStart);
- if (memPtr == MAP_FAILED) {
- LOGW("mmap(%d, R, FILE|SHARED, %d, %d) failed: %s\n",
- (int) actualLength, fd, (int) actualStart, strerror(errno));
- return -1;
- }
-
- pMap->baseAddr = memPtr;
- pMap->baseLength = actualLength;
- pMap->addr = (char*)memPtr + adjust;
- pMap->length = length;
-
- LOGVV("mmap seg (st=%d ln=%d): bp=%p bl=%d ad=%p ln=%d\n",
- (int) start, (int) length,
- pMap->baseAddr, (int) pMap->baseLength,
- pMap->addr, (int) pMap->length);
-
- return 0;
-}
-
-/*
- * Release a memory mapping.
- */
-void sysReleaseShmem(MemMapping* pMap)
-{
- if (pMap->baseAddr == NULL && pMap->baseLength == 0)
- return;
-
- if (munmap(pMap->baseAddr, pMap->baseLength) < 0) {
- LOGW("munmap(%p, %d) failed: %s\n",
- pMap->baseAddr, (int)pMap->baseLength, strerror(errno));
- } else {
- LOGV("munmap(%p, %d) succeeded\n", pMap->baseAddr, pMap->baseLength);
- pMap->baseAddr = NULL;
- pMap->baseLength = 0;
- }
-}
-
diff --git a/minzip/SysUtil.h b/minzip/SysUtil.h
deleted file mode 100644
index ec3a4bc..0000000
--- a/minzip/SysUtil.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * System utilities.
- */
-#ifndef _MINZIP_SYSUTIL
-#define _MINZIP_SYSUTIL
-
-#include "inline_magic.h"
-
-#include <sys/types.h>
-
-/*
- * Use this to keep track of mapped segments.
- */
-typedef struct MemMapping {
- void* addr; /* start of data */
- size_t length; /* length of data */
-
- void* baseAddr; /* page-aligned base address */
- size_t baseLength; /* length of mapping */
-} MemMapping;
-
-/* copy a map */
-INLINE void sysCopyMap(MemMapping* dst, const MemMapping* src) {
- *dst = *src;
-}
-
-/*
- * Load a file into a new shared memory segment. All data from the current
- * offset to the end of the file is pulled in.
- *
- * The segment is read-write, allowing VM fixups. (It should be modified
- * to support .gz/.zip compressed data.)
- *
- * On success, "pMap" is filled in, and zero is returned.
- */
-int sysLoadFileInShmem(int fd, MemMapping* pMap);
-
-/*
- * Map a file (from fd's current offset) into a shared,
- * read-only memory segment.
- *
- * On success, "pMap" is filled in, and zero is returned.
- */
-int sysMapFileInShmem(int fd, MemMapping* pMap);
-
-/*
- * Like sysMapFileInShmem, but on only part of a file.
- */
-int sysMapFileSegmentInShmem(int fd, off_t start, long length,
- MemMapping* pMap);
-
-/*
- * Release the pages associated with a shared memory segment.
- *
- * This does not free "pMap"; it just releases the memory.
- */
-void sysReleaseShmem(MemMapping* pMap);
-
-#endif /*_MINZIP_SYSUTIL*/
diff --git a/minzip/Zip.c b/minzip/Zip.c
deleted file mode 100644
index 100c833..0000000
--- a/minzip/Zip.c
+++ /dev/null
@@ -1,1098 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Simple Zip file support.
- */
-#include "safe_iop.h"
-#include "zlib.h"
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdint.h> // for uintptr_t
-#include <stdlib.h>
-#include <sys/stat.h> // for S_ISLNK()
-#include <unistd.h>
-
-#define LOG_TAG "minzip"
-#include "Zip.h"
-#include "Bits.h"
-#include "Log.h"
-#include "DirUtil.h"
-
-#undef NDEBUG // do this after including Log.h
-#include <assert.h>
-
-#define SORT_ENTRIES 1
-
-/*
- * Offset and length constants (java.util.zip naming convention).
- */
-enum {
- CENSIG = 0x02014b50, // PK12
- CENHDR = 46,
-
- CENVEM = 4,
- CENVER = 6,
- CENFLG = 8,
- CENHOW = 10,
- CENTIM = 12,
- CENCRC = 16,
- CENSIZ = 20,
- CENLEN = 24,
- CENNAM = 28,
- CENEXT = 30,
- CENCOM = 32,
- CENDSK = 34,
- CENATT = 36,
- CENATX = 38,
- CENOFF = 42,
-
- ENDSIG = 0x06054b50, // PK56
- ENDHDR = 22,
-
- ENDSUB = 8,
- ENDTOT = 10,
- ENDSIZ = 12,
- ENDOFF = 16,
- ENDCOM = 20,
-
- EXTSIG = 0x08074b50, // PK78
- EXTHDR = 16,
-
- EXTCRC = 4,
- EXTSIZ = 8,
- EXTLEN = 12,
-
- LOCSIG = 0x04034b50, // PK34
- LOCHDR = 30,
-
- LOCVER = 4,
- LOCFLG = 6,
- LOCHOW = 8,
- LOCTIM = 10,
- LOCCRC = 14,
- LOCSIZ = 18,
- LOCLEN = 22,
- LOCNAM = 26,
- LOCEXT = 28,
-
- STORED = 0,
- DEFLATED = 8,
-
- CENVEM_UNIX = 3 << 8, // the high byte of CENVEM
-};
-
-
-/*
- * For debugging, dump the contents of a ZipEntry.
- */
-#if 0
-static void dumpEntry(const ZipEntry* pEntry)
-{
- LOGI(" %p '%.*s'\n", pEntry->fileName,pEntry->fileNameLen,pEntry->fileName);
- LOGI(" off=%ld comp=%ld uncomp=%ld how=%d\n", pEntry->offset,
- pEntry->compLen, pEntry->uncompLen, pEntry->compression);
-}
-#endif
-
-/*
- * (This is a mzHashTableLookup callback.)
- *
- * Compare two ZipEntry structs, by name.
- */
-static int hashcmpZipEntry(const void* ventry1, const void* ventry2)
-{
- const ZipEntry* entry1 = (const ZipEntry*) ventry1;
- const ZipEntry* entry2 = (const ZipEntry*) ventry2;
-
- if (entry1->fileNameLen != entry2->fileNameLen)
- return entry1->fileNameLen - entry2->fileNameLen;
- return memcmp(entry1->fileName, entry2->fileName, entry1->fileNameLen);
-}
-
-/*
- * (This is a mzHashTableLookup callback.)
- *
- * find a ZipEntry struct by name.
- */
-static int hashcmpZipName(const void* ventry, const void* vname)
-{
- const ZipEntry* entry = (const ZipEntry*) ventry;
- const char* name = (const char*) vname;
- unsigned int nameLen = strlen(name);
-
- if (entry->fileNameLen != nameLen)
- return entry->fileNameLen - nameLen;
- return memcmp(entry->fileName, name, nameLen);
-}
-
-/*
- * Compute the hash code for a ZipEntry filename.
- *
- * Not expected to be compatible with any other hash function, so we init
- * to 2 to ensure it doesn't happen to match.
- */
-static unsigned int computeHash(const char* name, int nameLen)
-{
- unsigned int hash = 2;
-
- while (nameLen--)
- hash = hash * 31 + *name++;
-
- return hash;
-}
-
-static void addEntryToHashTable(HashTable* pHash, ZipEntry* pEntry)
-{
- unsigned int itemHash = computeHash(pEntry->fileName, pEntry->fileNameLen);
- const ZipEntry* found;
-
- found = (const ZipEntry*)mzHashTableLookup(pHash,
- itemHash, pEntry, hashcmpZipEntry, true);
- if (found != pEntry) {
- LOGW("WARNING: duplicate entry '%.*s' in Zip\n",
- found->fileNameLen, found->fileName);
- /* keep going */
- }
-}
-
-static int validFilename(const char *fileName, unsigned int fileNameLen)
-{
- // Forbid super long filenames.
- if (fileNameLen >= PATH_MAX) {
- LOGW("Filename too long (%d chatacters)\n", fileNameLen);
- return 0;
- }
-
- // Require all characters to be printable ASCII (no NUL, no UTF-8, etc).
- unsigned int i;
- for (i = 0; i < fileNameLen; ++i) {
- if (fileName[i] < 32 || fileName[i] >= 127) {
- LOGW("Filename contains invalid character '\%03o'\n", fileName[i]);
- return 0;
- }
- }
-
- return 1;
-}
-
-/*
- * Parse the contents of a Zip archive. After confirming that the file
- * is in fact a Zip, we scan out the contents of the central directory and
- * store it in a hash table.
- *
- * Returns "true" on success.
- */
-static bool parseZipArchive(ZipArchive* pArchive, const MemMapping* pMap)
-{
- bool result = false;
- const unsigned char* ptr;
- unsigned int i, numEntries, cdOffset;
- unsigned int val;
-
- /*
- * The first 4 bytes of the file will either be the local header
- * signature for the first file (LOCSIG) or, if the archive doesn't
- * have any files in it, the end-of-central-directory signature (ENDSIG).
- */
- val = get4LE(pMap->addr);
- if (val == ENDSIG) {
- LOGI("Found Zip archive, but it looks empty\n");
- goto bail;
- } else if (val != LOCSIG) {
- LOGV("Not a Zip archive (found 0x%08x)\n", val);
- goto bail;
- }
-
- /*
- * Find the EOCD. We'll find it immediately unless they have a file
- * comment.
- */
- ptr = pMap->addr + pMap->length - ENDHDR;
-
- while (ptr >= (const unsigned char*) pMap->addr) {
- if (*ptr == (ENDSIG & 0xff) && get4LE(ptr) == ENDSIG)
- break;
- ptr--;
- }
- if (ptr < (const unsigned char*) pMap->addr) {
- LOGI("Could not find end-of-central-directory in Zip\n");
- goto bail;
- }
-
- /*
- * There are two interesting items in the EOCD block: the number of
- * entries in the file, and the file offset of the start of the
- * central directory.
- */
- numEntries = get2LE(ptr + ENDSUB);
- cdOffset = get4LE(ptr + ENDOFF);
-
- LOGVV("numEntries=%d cdOffset=%d\n", numEntries, cdOffset);
- if (numEntries == 0 || cdOffset >= pMap->length) {
- LOGW("Invalid entries=%d offset=%d (len=%zd)\n",
- numEntries, cdOffset, pMap->length);
- goto bail;
- }
-
- /*
- * Create data structures to hold entries.
- */
- pArchive->numEntries = numEntries;
- pArchive->pEntries = (ZipEntry*) calloc(numEntries, sizeof(ZipEntry));
- pArchive->pHash = mzHashTableCreate(mzHashSize(numEntries), NULL);
- if (pArchive->pEntries == NULL || pArchive->pHash == NULL)
- goto bail;
-
- ptr = pMap->addr + cdOffset;
- for (i = 0; i < numEntries; i++) {
- ZipEntry* pEntry;
- unsigned int fileNameLen, extraLen, commentLen, localHdrOffset;
- const unsigned char* localHdr;
- const char *fileName;
-
- if (ptr + CENHDR > (const unsigned char*)pMap->addr + pMap->length) {
- LOGW("Ran off the end (at %d)\n", i);
- goto bail;
- }
- if (get4LE(ptr) != CENSIG) {
- LOGW("Missed a central dir sig (at %d)\n", i);
- goto bail;
- }
-
- localHdrOffset = get4LE(ptr + CENOFF);
- fileNameLen = get2LE(ptr + CENNAM);
- extraLen = get2LE(ptr + CENEXT);
- commentLen = get2LE(ptr + CENCOM);
- fileName = (const char*)ptr + CENHDR;
- if (fileName + fileNameLen > (const char*)pMap->addr + pMap->length) {
- LOGW("Filename ran off the end (at %d)\n", i);
- goto bail;
- }
- if (!validFilename(fileName, fileNameLen)) {
- LOGW("Invalid filename (at %d)\n", i);
- goto bail;
- }
-
-#if SORT_ENTRIES
- /* Figure out where this entry should go (binary search).
- */
- if (i > 0) {
- int low, high;
-
- low = 0;
- high = i - 1;
- while (low <= high) {
- int mid;
- int diff;
- int diffLen;
-
- mid = low + ((high - low) / 2); // avoid overflow
-
- if (pArchive->pEntries[mid].fileNameLen < fileNameLen) {
- diffLen = pArchive->pEntries[mid].fileNameLen;
- } else {
- diffLen = fileNameLen;
- }
- diff = strncmp(pArchive->pEntries[mid].fileName, fileName,
- diffLen);
- if (diff == 0) {
- diff = pArchive->pEntries[mid].fileNameLen - fileNameLen;
- }
- if (diff < 0) {
- low = mid + 1;
- } else if (diff > 0) {
- high = mid - 1;
- } else {
- high = mid;
- break;
- }
- }
-
- unsigned int target = high + 1;
- assert(target <= i);
- if (target != i) {
- /* It belongs somewhere other than at the end of
- * the list. Make some room at [target].
- */
- memmove(pArchive->pEntries + target + 1,
- pArchive->pEntries + target,
- (i - target) * sizeof(ZipEntry));
- }
- pEntry = &pArchive->pEntries[target];
- } else {
- pEntry = &pArchive->pEntries[0];
- }
-#else
- pEntry = &pArchive->pEntries[i];
-#endif
-
- //LOGI("%d: localHdr=%d fnl=%d el=%d cl=%d\n",
- // i, localHdrOffset, fileNameLen, extraLen, commentLen);
-
- pEntry->fileNameLen = fileNameLen;
- pEntry->fileName = fileName;
-
- pEntry->compLen = get4LE(ptr + CENSIZ);
- pEntry->uncompLen = get4LE(ptr + CENLEN);
- pEntry->compression = get2LE(ptr + CENHOW);
- pEntry->modTime = get4LE(ptr + CENTIM);
- pEntry->crc32 = get4LE(ptr + CENCRC);
-
- /* These two are necessary for finding the mode of the file.
- */
- pEntry->versionMadeBy = get2LE(ptr + CENVEM);
- if ((pEntry->versionMadeBy & 0xff00) != 0 &&
- (pEntry->versionMadeBy & 0xff00) != CENVEM_UNIX)
- {
- LOGW("Incompatible \"version made by\": 0x%02x (at %d)\n",
- pEntry->versionMadeBy >> 8, i);
- goto bail;
- }
- pEntry->externalFileAttributes = get4LE(ptr + CENATX);
-
- // Perform pMap->addr + localHdrOffset, ensuring that it won't
- // overflow. This is needed because localHdrOffset is untrusted.
- if (!safe_add((uintptr_t *)&localHdr, (uintptr_t)pMap->addr,
- (uintptr_t)localHdrOffset)) {
- LOGW("Integer overflow adding in parseZipArchive\n");
- goto bail;
- }
- if ((uintptr_t)localHdr + LOCHDR >
- (uintptr_t)pMap->addr + pMap->length) {
- LOGW("Bad offset to local header: %d (at %d)\n", localHdrOffset, i);
- goto bail;
- }
- if (get4LE(localHdr) != LOCSIG) {
- LOGW("Missed a local header sig (at %d)\n", i);
- goto bail;
- }
- pEntry->offset = localHdrOffset + LOCHDR
- + get2LE(localHdr + LOCNAM) + get2LE(localHdr + LOCEXT);
- if (!safe_add(NULL, pEntry->offset, pEntry->compLen)) {
- LOGW("Integer overflow adding in parseZipArchive\n");
- goto bail;
- }
- if ((size_t)pEntry->offset + pEntry->compLen > pMap->length) {
- LOGW("Data ran off the end (at %d)\n", i);
- goto bail;
- }
-
-#if !SORT_ENTRIES
- /* Add to hash table; no need to lock here.
- * Can't do this now if we're sorting, because entries
- * will move around.
- */
- addEntryToHashTable(pArchive->pHash, pEntry);
-#endif
-
- //dumpEntry(pEntry);
- ptr += CENHDR + fileNameLen + extraLen + commentLen;
- }
-
-#if SORT_ENTRIES
- /* If we're sorting, we have to wait until all entries
- * are in their final places, otherwise the pointers will
- * probably point to the wrong things.
- */
- for (i = 0; i < numEntries; i++) {
- /* Add to hash table; no need to lock here.
- */
- addEntryToHashTable(pArchive->pHash, &pArchive->pEntries[i]);
- }
-#endif
-
- result = true;
-
-bail:
- if (!result) {
- mzHashTableFree(pArchive->pHash);
- pArchive->pHash = NULL;
- }
- return result;
-}
-
-/*
- * Open a Zip archive and scan out the contents.
- *
- * The easiest way to do this is to mmap() the whole thing and do the
- * traditional backward scan for central directory. Since the EOCD is
- * a relatively small bit at the end, we should end up only touching a
- * small set of pages.
- *
- * This will be called on non-Zip files, especially during startup, so
- * we don't want to be too noisy about failures. (Do we want a "quiet"
- * flag?)
- *
- * On success, we fill out the contents of "pArchive".
- */
-int mzOpenZipArchive(const char* fileName, ZipArchive* pArchive)
-{
- MemMapping map;
- int err;
-
- LOGV("Opening archive '%s' %p\n", fileName, pArchive);
-
- map.addr = NULL;
- memset(pArchive, 0, sizeof(*pArchive));
-
- pArchive->fd = open(fileName, O_RDONLY, 0);
- if (pArchive->fd < 0) {
- err = errno ? errno : -1;
- LOGV("Unable to open '%s': %s\n", fileName, strerror(err));
- goto bail;
- }
-
- if (sysMapFileInShmem(pArchive->fd, &map) != 0) {
- err = -1;
- LOGW("Map of '%s' failed\n", fileName);
- goto bail;
- }
-
- if (map.length < ENDHDR) {
- err = -1;
- LOGV("File '%s' too small to be zip (%zd)\n", fileName, map.length);
- goto bail;
- }
-
- if (!parseZipArchive(pArchive, &map)) {
- err = -1;
- LOGV("Parsing '%s' failed\n", fileName);
- goto bail;
- }
-
- err = 0;
- sysCopyMap(&pArchive->map, &map);
- map.addr = NULL;
-
-bail:
- if (err != 0)
- mzCloseZipArchive(pArchive);
- if (map.addr != NULL)
- sysReleaseShmem(&map);
- return err;
-}
-
-/*
- * Close a ZipArchive, closing the file and freeing the contents.
- *
- * NOTE: the ZipArchive may not have been fully created.
- */
-void mzCloseZipArchive(ZipArchive* pArchive)
-{
- LOGV("Closing archive %p\n", pArchive);
-
- if (pArchive->fd >= 0)
- close(pArchive->fd);
- if (pArchive->map.addr != NULL)
- sysReleaseShmem(&pArchive->map);
-
- free(pArchive->pEntries);
-
- mzHashTableFree(pArchive->pHash);
-
- pArchive->fd = -1;
- pArchive->pHash = NULL;
- pArchive->pEntries = NULL;
-}
-
-/*
- * Find a matching entry.
- *
- * Returns NULL if no matching entry found.
- */
-const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
- const char* entryName)
-{
- unsigned int itemHash = computeHash(entryName, strlen(entryName));
-
- return (const ZipEntry*)mzHashTableLookup(pArchive->pHash,
- itemHash, (char*) entryName, hashcmpZipName, false);
-}
-
-/*
- * Return true if the entry is a symbolic link.
- */
-bool mzIsZipEntrySymlink(const ZipEntry* pEntry)
-{
- if ((pEntry->versionMadeBy & 0xff00) == CENVEM_UNIX) {
- return S_ISLNK(pEntry->externalFileAttributes >> 16);
- }
- return false;
-}
-
-/* Call processFunction on the uncompressed data of a STORED entry.
- */
-static bool processStoredEntry(const ZipArchive *pArchive,
- const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
- void *cookie)
-{
- size_t bytesLeft = pEntry->compLen;
- while (bytesLeft > 0) {
- unsigned char buf[32 * 1024];
- ssize_t n;
- size_t count;
- bool ret;
-
- count = bytesLeft;
- if (count > sizeof(buf)) {
- count = sizeof(buf);
- }
- n = read(pArchive->fd, buf, count);
- if (n < 0 || (size_t)n != count) {
- LOGE("Can't read %zu bytes from zip file: %ld\n", count, n);
- return false;
- }
- ret = processFunction(buf, n, cookie);
- if (!ret) {
- return false;
- }
- bytesLeft -= count;
- }
- return true;
-}
-
-static bool processDeflatedEntry(const ZipArchive *pArchive,
- const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
- void *cookie)
-{
- long result = -1;
- unsigned char readBuf[32 * 1024];
- unsigned char procBuf[32 * 1024];
- z_stream zstream;
- int zerr;
- long compRemaining;
-
- compRemaining = pEntry->compLen;
-
- /*
- * Initialize the zlib stream.
- */
- memset(&zstream, 0, sizeof(zstream));
- zstream.zalloc = Z_NULL;
- zstream.zfree = Z_NULL;
- zstream.opaque = Z_NULL;
- zstream.next_in = NULL;
- zstream.avail_in = 0;
- zstream.next_out = (Bytef*) procBuf;
- zstream.avail_out = sizeof(procBuf);
- zstream.data_type = Z_UNKNOWN;
-
- /*
- * Use the undocumented "negative window bits" feature to tell zlib
- * that there's no zlib header waiting for it.
- */
- zerr = inflateInit2(&zstream, -MAX_WBITS);
- if (zerr != Z_OK) {
- if (zerr == Z_VERSION_ERROR) {
- LOGE("Installed zlib is not compatible with linked version (%s)\n",
- ZLIB_VERSION);
- } else {
- LOGE("Call to inflateInit2 failed (zerr=%d)\n", zerr);
- }
- goto bail;
- }
-
- /*
- * Loop while we have data.
- */
- do {
- /* read as much as we can */
- if (zstream.avail_in == 0) {
- long getSize = (compRemaining > (long)sizeof(readBuf)) ?
- (long)sizeof(readBuf) : compRemaining;
- LOGVV("+++ reading %ld bytes (%ld left)\n",
- getSize, compRemaining);
-
- int cc = read(pArchive->fd, readBuf, getSize);
- if (cc != (int) getSize) {
- LOGW("inflate read failed (%d vs %ld)\n", cc, getSize);
- goto z_bail;
- }
-
- compRemaining -= getSize;
-
- zstream.next_in = readBuf;
- zstream.avail_in = getSize;
- }
-
- /* uncompress the data */
- zerr = inflate(&zstream, Z_NO_FLUSH);
- if (zerr != Z_OK && zerr != Z_STREAM_END) {
- LOGD("zlib inflate call failed (zerr=%d)\n", zerr);
- goto z_bail;
- }
-
- /* write when we're full or when we're done */
- if (zstream.avail_out == 0 ||
- (zerr == Z_STREAM_END && zstream.avail_out != sizeof(procBuf)))
- {
- long procSize = zstream.next_out - procBuf;
- LOGVV("+++ processing %d bytes\n", (int) procSize);
- bool ret = processFunction(procBuf, procSize, cookie);
- if (!ret) {
- LOGW("Process function elected to fail (in inflate)\n");
- goto z_bail;
- }
-
- zstream.next_out = procBuf;
- zstream.avail_out = sizeof(procBuf);
- }
- } while (zerr == Z_OK);
-
- assert(zerr == Z_STREAM_END); /* other errors should've been caught */
-
- // success!
- result = zstream.total_out;
-
-z_bail:
- inflateEnd(&zstream); /* free up any allocated structures */
-
-bail:
- if (result != pEntry->uncompLen) {
- if (result != -1) // error already shown?
- LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
- result, pEntry->uncompLen);
- return false;
- }
- return true;
-}
-
-/*
- * Stream the uncompressed data through the supplied function,
- * passing cookie to it each time it gets called. processFunction
- * may be called more than once.
- *
- * If processFunction returns false, the operation is abandoned and
- * mzProcessZipEntryContents() immediately returns false.
- *
- * This is useful for calculating the hash of an entry's uncompressed contents.
- */
-bool mzProcessZipEntryContents(const ZipArchive *pArchive,
- const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
- void *cookie)
-{
- bool ret = false;
- off_t oldOff;
-
- /* save current offset */
- oldOff = lseek(pArchive->fd, 0, SEEK_CUR);
-
- /* Seek to the beginning of the entry's compressed data. */
- lseek(pArchive->fd, pEntry->offset, SEEK_SET);
-
- switch (pEntry->compression) {
- case STORED:
- ret = processStoredEntry(pArchive, pEntry, processFunction, cookie);
- break;
- case DEFLATED:
- ret = processDeflatedEntry(pArchive, pEntry, processFunction, cookie);
- break;
- default:
- LOGE("Unsupported compression type %d for entry '%s'\n",
- pEntry->compression, pEntry->fileName);
- break;
- }
-
- /* restore file offset */
- lseek(pArchive->fd, oldOff, SEEK_SET);
- return ret;
-}
-
-static bool crcProcessFunction(const unsigned char *data, int dataLen,
- void *crc)
-{
- *(unsigned long *)crc = crc32(*(unsigned long *)crc, data, dataLen);
- return true;
-}
-
-/*
- * Check the CRC on this entry; return true if it is correct.
- * May do other internal checks as well.
- */
-bool mzIsZipEntryIntact(const ZipArchive *pArchive, const ZipEntry *pEntry)
-{
- unsigned long crc;
- bool ret;
-
- crc = crc32(0L, Z_NULL, 0);
- ret = mzProcessZipEntryContents(pArchive, pEntry, crcProcessFunction,
- (void *)&crc);
- if (!ret) {
- LOGE("Can't calculate CRC for entry\n");
- return false;
- }
- if (crc != (unsigned long)pEntry->crc32) {
- LOGW("CRC for entry %.*s (0x%08lx) != expected (0x%08lx)\n",
- pEntry->fileNameLen, pEntry->fileName, crc, pEntry->crc32);
- return false;
- }
- return true;
-}
-
-typedef struct {
- char *buf;
- int bufLen;
-} CopyProcessArgs;
-
-static bool copyProcessFunction(const unsigned char *data, int dataLen,
- void *cookie)
-{
- CopyProcessArgs *args = (CopyProcessArgs *)cookie;
- if (dataLen <= args->bufLen) {
- memcpy(args->buf, data, dataLen);
- args->buf += dataLen;
- args->bufLen -= dataLen;
- return true;
- }
- return false;
-}
-
-/*
- * Read an entry into a buffer allocated by the caller.
- */
-bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
- char *buf, int bufLen)
-{
- CopyProcessArgs args;
- bool ret;
-
- args.buf = buf;
- args.bufLen = bufLen;
- ret = mzProcessZipEntryContents(pArchive, pEntry, copyProcessFunction,
- (void *)&args);
- if (!ret) {
- LOGE("Can't extract entry to buffer.\n");
- return false;
- }
- return true;
-}
-
-static bool writeProcessFunction(const unsigned char *data, int dataLen,
- void *fd)
-{
- ssize_t n = write((int)fd, data, dataLen);
- if (n != dataLen) {
- LOGE("Can't write %d bytes (only %ld) from zip file: %s\n",
- dataLen, n, strerror(errno));
- return false;
- }
- return true;
-}
-
-/*
- * Uncompress "pEntry" in "pArchive" to "fd" at the current offset.
- */
-bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
- const ZipEntry *pEntry, int fd)
-{
- bool ret = mzProcessZipEntryContents(pArchive, pEntry, writeProcessFunction,
- (void *)fd);
- if (!ret) {
- LOGE("Can't extract entry to file.\n");
- return false;
- }
- return true;
-}
-
-/* Helper state to make path translation easier and less malloc-happy.
- */
-typedef struct {
- const char *targetDir;
- const char *zipDir;
- char *buf;
- int targetDirLen;
- int zipDirLen;
- int bufLen;
-} MzPathHelper;
-
-/* Given the values of targetDir and zipDir in the helper,
- * return the target filename of the provided entry.
- * The helper must be initialized first.
- */
-static const char *targetEntryPath(MzPathHelper *helper, ZipEntry *pEntry)
-{
- int needLen;
- bool firstTime = (helper->buf == NULL);
-
- /* target file <-- targetDir + / + entry[zipDirLen:]
- */
- needLen = helper->targetDirLen + 1 +
- pEntry->fileNameLen - helper->zipDirLen + 1;
- if (needLen > helper->bufLen) {
- char *newBuf;
-
- needLen *= 2;
- newBuf = (char *)realloc(helper->buf, needLen);
- if (newBuf == NULL) {
- return NULL;
- }
- helper->buf = newBuf;
- helper->bufLen = needLen;
- }
-
- /* Every path will start with the target path and a slash.
- */
- if (firstTime) {
- char *p = helper->buf;
- memcpy(p, helper->targetDir, helper->targetDirLen);
- p += helper->targetDirLen;
- if (p == helper->buf || p[-1] != '/') {
- helper->targetDirLen += 1;
- *p++ = '/';
- }
- }
-
- /* Replace the custom part of the path with the appropriate
- * part of the entry's path.
- */
- char *epath = helper->buf + helper->targetDirLen;
- memcpy(epath, pEntry->fileName + helper->zipDirLen,
- pEntry->fileNameLen - helper->zipDirLen);
- epath += pEntry->fileNameLen - helper->zipDirLen;
- *epath = '\0';
-
- return helper->buf;
-}
-
-/*
- * Inflate all entries under zipDir to the directory specified by
- * targetDir, which must exist and be a writable directory.
- *
- * The immediate children of zipDir will become the immediate
- * children of targetDir; e.g., if the archive contains the entries
- *
- * a/b/c/one
- * a/b/c/two
- * a/b/c/d/three
- *
- * and mzExtractRecursive(a, "a/b/c", "/tmp") is called, the resulting
- * files will be
- *
- * /tmp/one
- * /tmp/two
- * /tmp/d/three
- *
- * Returns true on success, false on failure.
- */
-bool mzExtractRecursive(const ZipArchive *pArchive,
- const char *zipDir, const char *targetDir,
- int flags, const struct utimbuf *timestamp,
- void (*callback)(const char *fn, void *), void *cookie)
-{
- if (zipDir[0] == '/') {
- LOGE("mzExtractRecursive(): zipDir must be a relative path.\n");
- return false;
- }
- if (targetDir[0] != '/') {
- LOGE("mzExtractRecursive(): targetDir must be an absolute path.\n");
- return false;
- }
-
- unsigned int zipDirLen;
- char *zpath;
-
- zipDirLen = strlen(zipDir);
- zpath = (char *)malloc(zipDirLen + 2);
- if (zpath == NULL) {
- LOGE("Can't allocate %d bytes for zip path\n", zipDirLen + 2);
- return false;
- }
- /* If zipDir is empty, we'll extract the entire zip file.
- * Otherwise, canonicalize the path.
- */
- if (zipDirLen > 0) {
- /* Make sure there's (hopefully, exactly one) slash at the
- * end of the path. This way we don't need to worry about
- * accidentally extracting "one/twothree" when a path like
- * "one/two" is specified.
- */
- memcpy(zpath, zipDir, zipDirLen);
- if (zpath[zipDirLen-1] != '/') {
- zpath[zipDirLen++] = '/';
- }
- }
- zpath[zipDirLen] = '\0';
-
- /* Set up the helper structure that we'll use to assemble paths.
- */
- MzPathHelper helper;
- helper.targetDir = targetDir;
- helper.targetDirLen = strlen(helper.targetDir);
- helper.zipDir = zpath;
- helper.zipDirLen = strlen(helper.zipDir);
- helper.buf = NULL;
- helper.bufLen = 0;
-
- /* Walk through the entries and extract anything whose path begins
- * with zpath.
-//TODO: since the entries are sorted, binary search for the first match
-// and stop after the first non-match.
- */
- unsigned int i;
- bool seenMatch = false;
- int ok = true;
- for (i = 0; i < pArchive->numEntries; i++) {
- ZipEntry *pEntry = pArchive->pEntries + i;
- if (pEntry->fileNameLen < zipDirLen) {
-//TODO: look out for a single empty directory entry that matches zpath, but
-// missing the trailing slash. Most zip files seem to include
-// the trailing slash, but I think it's legal to leave it off.
-// e.g., zpath "a/b/", entry "a/b", with no children of the entry.
- /* No chance of matching.
- */
-#if SORT_ENTRIES
- if (seenMatch) {
- /* Since the entries are sorted, we can give up
- * on the first mismatch after the first match.
- */
- break;
- }
-#endif
- continue;
- }
- /* If zpath is empty, this strncmp() will match everything,
- * which is what we want.
- */
- if (strncmp(pEntry->fileName, zpath, zipDirLen) != 0) {
-#if SORT_ENTRIES
- if (seenMatch) {
- /* Since the entries are sorted, we can give up
- * on the first mismatch after the first match.
- */
- break;
- }
-#endif
- continue;
- }
- /* This entry begins with zipDir, so we'll extract it.
- */
- seenMatch = true;
-
- /* Find the target location of the entry.
- */
- const char *targetFile = targetEntryPath(&helper, pEntry);
- if (targetFile == NULL) {
- LOGE("Can't assemble target path for \"%.*s\"\n",
- pEntry->fileNameLen, pEntry->fileName);
- ok = false;
- break;
- }
-
- /* With DRY_RUN set, invoke the callback but don't do anything else.
- */
- if (flags & MZ_EXTRACT_DRY_RUN) {
- if (callback != NULL) callback(targetFile, cookie);
- continue;
- }
-
- /* Create the file or directory.
- */
-#define UNZIP_DIRMODE 0755
-#define UNZIP_FILEMODE 0644
- if (pEntry->fileName[pEntry->fileNameLen-1] == '/') {
- if (!(flags & MZ_EXTRACT_FILES_ONLY)) {
- int ret = dirCreateHierarchy(
- targetFile, UNZIP_DIRMODE, timestamp, false);
- if (ret != 0) {
- LOGE("Can't create containing directory for \"%s\": %s\n",
- targetFile, strerror(errno));
- ok = false;
- break;
- }
- LOGD("Extracted dir \"%s\"\n", targetFile);
- }
- } else {
- /* This is not a directory. First, make sure that
- * the containing directory exists.
- */
- int ret = dirCreateHierarchy(
- targetFile, UNZIP_DIRMODE, timestamp, true);
- if (ret != 0) {
- LOGE("Can't create containing directory for \"%s\": %s\n",
- targetFile, strerror(errno));
- ok = false;
- break;
- }
-
- /* With FILES_ONLY set, we need to ignore metadata entirely,
- * so treat symlinks as regular files.
- */
- if (!(flags & MZ_EXTRACT_FILES_ONLY) && mzIsZipEntrySymlink(pEntry)) {
- /* The entry is a symbolic link.
- * The relative target of the symlink is in the
- * data section of this entry.
- */
- if (pEntry->uncompLen == 0) {
- LOGE("Symlink entry \"%s\" has no target\n",
- targetFile);
- ok = false;
- break;
- }
- char *linkTarget = malloc(pEntry->uncompLen + 1);
- if (linkTarget == NULL) {
- ok = false;
- break;
- }
- ok = mzReadZipEntry(pArchive, pEntry, linkTarget,
- pEntry->uncompLen);
- if (!ok) {
- LOGE("Can't read symlink target for \"%s\"\n",
- targetFile);
- free(linkTarget);
- break;
- }
- linkTarget[pEntry->uncompLen] = '\0';
-
- /* Make the link.
- */
- ret = symlink(linkTarget, targetFile);
- if (ret != 0) {
- LOGE("Can't symlink \"%s\" to \"%s\": %s\n",
- targetFile, linkTarget, strerror(errno));
- free(linkTarget);
- ok = false;
- break;
- }
- LOGD("Extracted symlink \"%s\" -> \"%s\"\n",
- targetFile, linkTarget);
- free(linkTarget);
- } else {
- /* The entry is a regular file.
- * Open the target for writing.
- */
- int fd = creat(targetFile, UNZIP_FILEMODE);
- if (fd < 0) {
- LOGE("Can't create target file \"%s\": %s\n",
- targetFile, strerror(errno));
- ok = false;
- break;
- }
-
- bool ok = mzExtractZipEntryToFile(pArchive, pEntry, fd);
- close(fd);
- if (!ok) {
- LOGE("Error extracting \"%s\"\n", targetFile);
- ok = false;
- break;
- }
-
- if (timestamp != NULL && utime(targetFile, timestamp)) {
- LOGE("Error touching \"%s\"\n", targetFile);
- ok = false;
- break;
- }
-
- LOGD("Extracted file \"%s\"\n", targetFile);
- }
- }
-
- if (callback != NULL) callback(targetFile, cookie);
- }
-
- free(helper.buf);
- free(zpath);
-
- return ok;
-}
diff --git a/minzip/Zip.h b/minzip/Zip.h
deleted file mode 100644
index 1c1df2f..0000000
--- a/minzip/Zip.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright 2006 The Android Open Source Project
- *
- * Simple Zip archive support.
- */
-#ifndef _MINZIP_ZIP
-#define _MINZIP_ZIP
-
-#include "inline_magic.h"
-
-#include <stdlib.h>
-#include <utime.h>
-
-#include "Hash.h"
-#include "SysUtil.h"
-
-/*
- * One entry in the Zip archive. Treat this as opaque -- use accessors below.
- *
- * TODO: we're now keeping the pages mapped so we don't have to copy the
- * filename. We can change the accessors to retrieve the various pieces
- * directly from the source file instead of copying them out, for a very
- * slight speed hit and a modest reduction in memory usage.
- */
-typedef struct ZipEntry {
- unsigned int fileNameLen;
- const char* fileName; // not null-terminated
- long offset;
- long compLen;
- long uncompLen;
- int compression;
- long modTime;
- long crc32;
- int versionMadeBy;
- long externalFileAttributes;
-} ZipEntry;
-
-/*
- * One Zip archive. Treat as opaque.
- */
-typedef struct ZipArchive {
- int fd;
- unsigned int numEntries;
- ZipEntry* pEntries;
- HashTable* pHash; // maps file name to ZipEntry
- MemMapping map;
-} ZipArchive;
-
-/*
- * Represents a non-NUL-terminated string,
- * which is how entry names are stored.
- */
-typedef struct {
- const char *str;
- size_t len;
-} UnterminatedString;
-
-/*
- * Open a Zip archive.
- *
- * On success, returns 0 and populates "pArchive". Returns nonzero errno
- * value on failure.
- */
-int mzOpenZipArchive(const char* fileName, ZipArchive* pArchive);
-
-/*
- * Close archive, releasing resources associated with it.
- *
- * Depending on the implementation this could unmap pages used by classes
- * stored in a Jar. This should only be done after unloading classes.
- */
-void mzCloseZipArchive(ZipArchive* pArchive);
-
-
-/*
- * Find an entry in the Zip archive, by name.
- */
-const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
- const char* entryName);
-
-/*
- * Get the number of entries in the Zip archive.
- */
-INLINE unsigned int mzZipEntryCount(const ZipArchive* pArchive) {
- return pArchive->numEntries;
-}
-
-/*
- * Get an entry by index. Returns NULL if the index is out-of-bounds.
- */
-INLINE const ZipEntry*
-mzGetZipEntryAt(const ZipArchive* pArchive, unsigned int index)
-{
- if (index < pArchive->numEntries) {
- return pArchive->pEntries + index;
- }
- return NULL;
-}
-
-/*
- * Get the index number of an entry in the archive.
- */
-INLINE unsigned int
-mzGetZipEntryIndex(const ZipArchive *pArchive, const ZipEntry *pEntry) {
- return pEntry - pArchive->pEntries;
-}
-
-/*
- * Simple accessors.
- */
-INLINE UnterminatedString mzGetZipEntryFileName(const ZipEntry* pEntry) {
- UnterminatedString ret;
- ret.str = pEntry->fileName;
- ret.len = pEntry->fileNameLen;
- return ret;
-}
-INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) {
- return pEntry->offset;
-}
-INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
- return pEntry->uncompLen;
-}
-INLINE long mzGetZipEntryModTime(const ZipEntry* pEntry) {
- return pEntry->modTime;
-}
-INLINE long mzGetZipEntryCrc32(const ZipEntry* pEntry) {
- return pEntry->crc32;
-}
-bool mzIsZipEntrySymlink(const ZipEntry* pEntry);
-
-
-/*
- * Type definition for the callback function used by
- * mzProcessZipEntryContents().
- */
-typedef bool (*ProcessZipEntryContentsFunction)(const unsigned char *data,
- int dataLen, void *cookie);
-
-/*
- * Stream the uncompressed data through the supplied function,
- * passing cookie to it each time it gets called. processFunction
- * may be called more than once.
- *
- * If processFunction returns false, the operation is abandoned and
- * mzProcessZipEntryContents() immediately returns false.
- *
- * This is useful for calculating the hash of an entry's uncompressed contents.
- */
-bool mzProcessZipEntryContents(const ZipArchive *pArchive,
- const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
- void *cookie);
-
-/*
- * Read an entry into a buffer allocated by the caller.
- */
-bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
- char* buf, int bufLen);
-
-/*
- * Check the CRC on this entry; return true if it is correct.
- * May do other internal checks as well.
- */
-bool mzIsZipEntryIntact(const ZipArchive *pArchive, const ZipEntry *pEntry);
-
-/*
- * Inflate and write an entry to a file.
- */
-bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
- const ZipEntry *pEntry, int fd);
-
-/*
- * Inflate all entries under zipDir to the directory specified by
- * targetDir, which must exist and be a writable directory.
- *
- * The immediate children of zipDir will become the immediate
- * children of targetDir; e.g., if the archive contains the entries
- *
- * a/b/c/one
- * a/b/c/two
- * a/b/c/d/three
- *
- * and mzExtractRecursive(a, "a/b/c", "/tmp", ...) is called, the resulting
- * files will be
- *
- * /tmp/one
- * /tmp/two
- * /tmp/d/three
- *
- * flags is zero or more of the following:
- *
- * MZ_EXTRACT_FILES_ONLY - only unpack files, not directories or symlinks
- * MZ_EXTRACT_DRY_RUN - don't do anything, but do invoke the callback
- *
- * If timestamp is non-NULL, file timestamps will be set accordingly.
- *
- * If callback is non-NULL, it will be invoked with each unpacked file.
- *
- * Returns true on success, false on failure.
- */
-enum { MZ_EXTRACT_FILES_ONLY = 1, MZ_EXTRACT_DRY_RUN = 2 };
-bool mzExtractRecursive(const ZipArchive *pArchive,
- const char *zipDir, const char *targetDir,
- int flags, const struct utimbuf *timestamp,
- void (*callback)(const char *fn, void*), void *cookie);
-
-#endif /*_MINZIP_ZIP*/
diff --git a/minzip/inline_magic.h b/minzip/inline_magic.h
deleted file mode 100644
index 8c185e1..0000000
--- a/minzip/inline_magic.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MINZIP_INLINE_MAGIC_H_
-#define MINZIP_INLINE_MAGIC_H_
-
-#ifndef MINZIP_GENERATE_INLINES
-#define INLINE extern __inline__
-#else
-#define INLINE
-#endif
-
-#endif // MINZIP_INLINE_MAGIC_H_
diff --git a/mtdutils/Android.mk b/mtdutils/Android.mk
deleted file mode 100644
index 1a75423..0000000
--- a/mtdutils/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-ifneq ($(TARGET_SIMULATOR),true)
-ifeq ($(TARGET_ARCH),arm)
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- mtdutils.c \
- mounts.c
-
-LOCAL_MODULE := libmtdutils
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := flash_image.c
-LOCAL_MODULE := flash_image
-LOCAL_STATIC_LIBRARIES := libmtdutils
-LOCAL_SHARED_LIBRARIES := libcutils libc
-include $(BUILD_EXECUTABLE)
-
-endif # TARGET_ARCH == arm
-endif # !TARGET_SIMULATOR
diff --git a/mtdutils/flash_image.c b/mtdutils/flash_image.c
deleted file mode 100644
index c776876..0000000
--- a/mtdutils/flash_image.c
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "cutils/log.h"
-#include "mtdutils.h"
-
-#define LOG_TAG "flash_image"
-
-#define HEADER_SIZE 2048 // size of header to compare for equality
-
-void die(const char *msg, ...) {
- int err = errno;
- va_list args;
- va_start(args, msg);
- char buf[1024];
- vsnprintf(buf, sizeof(buf), msg, args);
- va_end(args);
-
- if (err != 0) {
- strlcat(buf, ": ", sizeof(buf));
- strlcat(buf, strerror(err), sizeof(buf));
- }
-
- fprintf(stderr, "%s\n", buf);
- LOGE("%s\n", buf);
- exit(1);
-}
-
-/* Read an image file and write it to a flash partition. */
-
-int main(int argc, char **argv) {
- const MtdPartition *ptn;
- MtdWriteContext *write;
- void *data;
- unsigned sz;
-
- if (argc != 3) {
- fprintf(stderr, "usage: %s partition file.img\n", argv[0]);
- return 2;
- }
-
- if (mtd_scan_partitions() <= 0) die("error scanning partitions");
- const MtdPartition *partition = mtd_find_partition_by_name(argv[1]);
- if (partition == NULL) die("can't find %s partition", argv[1]);
-
- // If the first part of the file matches the partition, skip writing
-
- int fd = open(argv[2], O_RDONLY);
- if (fd < 0) die("error opening %s", argv[2]);
-
- char header[HEADER_SIZE];
- int headerlen = read(fd, header, sizeof(header));
- if (headerlen <= 0) die("error reading %s header", argv[2]);
-
- MtdReadContext *in = mtd_read_partition(partition);
- if (in == NULL) {
- LOGW("error opening %s: %s\n", argv[1], strerror(errno));
- // just assume it needs re-writing
- } else {
- char check[HEADER_SIZE];
- int checklen = mtd_read_data(in, check, sizeof(check));
- if (checklen <= 0) {
- LOGW("error reading %s: %s\n", argv[1], strerror(errno));
- // just assume it needs re-writing
- } else if (checklen == headerlen && !memcmp(header, check, headerlen)) {
- LOGI("header is the same, not flashing %s\n", argv[1]);
- return 0;
- }
- mtd_read_close(in);
- }
-
- // Skip the header (we'll come back to it), write everything else
- LOGI("flashing %s from %s\n", argv[1], argv[2]);
-
- MtdWriteContext *out = mtd_write_partition(partition);
- if (out == NULL) die("error writing %s", argv[1]);
-
- char buf[HEADER_SIZE];
- memset(buf, 0, headerlen);
- int wrote = mtd_write_data(out, buf, headerlen);
- if (wrote != headerlen) die("error writing %s", argv[1]);
-
- int len;
- while ((len = read(fd, buf, sizeof(buf))) > 0) {
- wrote = mtd_write_data(out, buf, len);
- if (wrote != len) die("error writing %s", argv[1]);
- }
- if (len < 0) die("error reading %s", argv[2]);
-
- if (mtd_write_close(out)) die("error closing %s", argv[1]);
-
- // Now come back and write the header last
-
- out = mtd_write_partition(partition);
- if (out == NULL) die("error re-opening %s", argv[1]);
-
- wrote = mtd_write_data(out, header, headerlen);
- if (wrote != headerlen) die("error re-writing %s", argv[1]);
-
- // Need to write a complete block, so write the rest of the first block
- size_t block_size;
- if (mtd_partition_info(partition, NULL, &block_size, NULL))
- die("error getting %s block size", argv[1]);
-
- if (lseek(fd, headerlen, SEEK_SET) != headerlen)
- die("error rewinding %s", argv[2]);
-
- int left = block_size - headerlen;
- while (left < 0) left += block_size;
- while (left > 0) {
- len = read(fd, buf, left > (int)sizeof(buf) ? (int)sizeof(buf) : left);
- if (len <= 0) die("error reading %s", argv[2]);
- if (mtd_write_data(out, buf, len) != len)
- die("error writing %s", argv[1]);
- left -= len;
- }
-
- if (mtd_write_close(out)) die("error closing %s", argv[1]);
- return 0;
-}
diff --git a/mtdutils/mounts.c b/mtdutils/mounts.c
deleted file mode 100644
index 2ab3ff6..0000000
--- a/mtdutils/mounts.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/mount.h>
-
-#include "mounts.h"
-
-struct MountedVolume {
- const char *device;
- const char *mount_point;
- const char *filesystem;
- const char *flags;
-};
-
-typedef struct {
- MountedVolume *volumes;
- int volumes_allocd;
- int volume_count;
-} MountsState;
-
-static MountsState g_mounts_state = {
- NULL, // volumes
- 0, // volumes_allocd
- 0 // volume_count
-};
-
-static inline void
-free_volume_internals(const MountedVolume *volume, int zero)
-{
- free((char *)volume->device);
- free((char *)volume->mount_point);
- free((char *)volume->filesystem);
- free((char *)volume->flags);
- if (zero) {
- memset((void *)volume, 0, sizeof(*volume));
- }
-}
-
-#define PROC_MOUNTS_FILENAME "/proc/mounts"
-
-int
-scan_mounted_volumes()
-{
- char buf[2048];
- const char *bufp;
- int fd;
- ssize_t nbytes;
-
- if (g_mounts_state.volumes == NULL) {
- const int numv = 32;
- MountedVolume *volumes = malloc(numv * sizeof(*volumes));
- if (volumes == NULL) {
- errno = ENOMEM;
- return -1;
- }
- g_mounts_state.volumes = volumes;
- g_mounts_state.volumes_allocd = numv;
- memset(volumes, 0, numv * sizeof(*volumes));
- } else {
- /* Free the old volume strings.
- */
- int i;
- for (i = 0; i < g_mounts_state.volume_count; i++) {
- free_volume_internals(&g_mounts_state.volumes[i], 1);
- }
- }
- g_mounts_state.volume_count = 0;
-
- /* Open and read the file contents.
- */
- fd = open(PROC_MOUNTS_FILENAME, O_RDONLY);
- if (fd < 0) {
- goto bail;
- }
- nbytes = read(fd, buf, sizeof(buf) - 1);
- close(fd);
- if (nbytes < 0) {
- goto bail;
- }
- buf[nbytes] = '\0';
-
- /* Parse the contents of the file, which looks like:
- *
- * # cat /proc/mounts
- * rootfs / rootfs rw 0 0
- * /dev/pts /dev/pts devpts rw 0 0
- * /proc /proc proc rw 0 0
- * /sys /sys sysfs rw 0 0
- * /dev/block/mtdblock4 /system yaffs2 rw,nodev,noatime,nodiratime 0 0
- * /dev/block/mtdblock5 /data yaffs2 rw,nodev,noatime,nodiratime 0 0
- * /dev/block/mmcblk0p1 /sdcard vfat rw,sync,dirsync,fmask=0000,dmask=0000,codepage=cp437,iocharset=iso8859-1,utf8 0 0
- *
- * The zeroes at the end are dummy placeholder fields to make the
- * output match Linux's /etc/mtab, but don't represent anything here.
- */
- bufp = buf;
- while (nbytes > 0) {
- char device[64];
- char mount_point[64];
- char filesystem[64];
- char flags[128];
- int matches;
-
- /* %as is a gnu extension that malloc()s a string for each field.
- */
- matches = sscanf(bufp, "%63s %63s %63s %127s",
- device, mount_point, filesystem, flags);
-
- if (matches == 4) {
- device[sizeof(device)-1] = '\0';
- mount_point[sizeof(mount_point)-1] = '\0';
- filesystem[sizeof(filesystem)-1] = '\0';
- flags[sizeof(flags)-1] = '\0';
-
- MountedVolume *v =
- &g_mounts_state.volumes[g_mounts_state.volume_count++];
- v->device = strdup(device);
- v->mount_point = strdup(mount_point);
- v->filesystem = strdup(filesystem);
- v->flags = strdup(flags);
- } else {
-printf("matches was %d on <<%.40s>>\n", matches, bufp);
- }
-
- /* Eat the line.
- */
- while (nbytes > 0 && *bufp != '\n') {
- bufp++;
- nbytes--;
- }
- if (nbytes > 0) {
- bufp++;
- nbytes--;
- }
- }
-
- return 0;
-
-bail:
-//TODO: free the strings we've allocated.
- g_mounts_state.volume_count = 0;
- return -1;
-}
-
-const MountedVolume *
-find_mounted_volume_by_device(const char *device)
-{
- if (g_mounts_state.volumes != NULL) {
- int i;
- for (i = 0; i < g_mounts_state.volume_count; i++) {
- MountedVolume *v = &g_mounts_state.volumes[i];
- /* May be null if it was unmounted and we haven't rescanned.
- */
- if (v->device != NULL) {
- if (strcmp(v->device, device) == 0) {
- return v;
- }
- }
- }
- }
- return NULL;
-}
-
-const MountedVolume *
-find_mounted_volume_by_mount_point(const char *mount_point)
-{
- if (g_mounts_state.volumes != NULL) {
- int i;
- for (i = 0; i < g_mounts_state.volume_count; i++) {
- MountedVolume *v = &g_mounts_state.volumes[i];
- /* May be null if it was unmounted and we haven't rescanned.
- */
- if (v->mount_point != NULL) {
- if (strcmp(v->mount_point, mount_point) == 0) {
- return v;
- }
- }
- }
- }
- return NULL;
-}
-
-int
-unmount_mounted_volume(const MountedVolume *volume)
-{
- /* Intentionally pass NULL to umount if the caller tries
- * to unmount a volume they already unmounted using this
- * function.
- */
- int ret = umount(volume->mount_point);
- if (ret == 0) {
- free_volume_internals(volume, 1);
- return 0;
- }
- return ret;
-}
diff --git a/mtdutils/mounts.h b/mtdutils/mounts.h
deleted file mode 100644
index 2e2765a..0000000
--- a/mtdutils/mounts.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MTDUTILS_MOUNTS_H_
-#define MTDUTILS_MOUNTS_H_
-
-typedef struct MountedVolume MountedVolume;
-
-int scan_mounted_volumes(void);
-
-const MountedVolume *find_mounted_volume_by_device(const char *device);
-
-const MountedVolume *
-find_mounted_volume_by_mount_point(const char *mount_point);
-
-int unmount_mounted_volume(const MountedVolume *volume);
-
-#endif // MTDUTILS_MOUNTS_H_
diff --git a/mtdutils/mtdutils.c b/mtdutils/mtdutils.c
deleted file mode 100644
index 2b0106f..0000000
--- a/mtdutils/mtdutils.c
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/mount.h> // for _IOW, _IOR, mount()
-#include <sys/stat.h>
-#include <mtd/mtd-user.h>
-#undef NDEBUG
-#include <assert.h>
-
-#include "mtdutils.h"
-
-struct MtdPartition {
- int device_index;
- unsigned int size;
- unsigned int erase_size;
- char *name;
-};
-
-struct MtdReadContext {
- const MtdPartition *partition;
- char *buffer;
- size_t consumed;
- int fd;
-};
-
-struct MtdWriteContext {
- const MtdPartition *partition;
- char *buffer;
- size_t stored;
- int fd;
-};
-
-typedef struct {
- MtdPartition *partitions;
- int partitions_allocd;
- int partition_count;
-} MtdState;
-
-static MtdState g_mtd_state = {
- NULL, // partitions
- 0, // partitions_allocd
- -1 // partition_count
-};
-
-#define MTD_PROC_FILENAME "/proc/mtd"
-
-int
-mtd_scan_partitions()
-{
- char buf[2048];
- const char *bufp;
- int fd;
- int i;
- ssize_t nbytes;
-
- if (g_mtd_state.partitions == NULL) {
- const int nump = 32;
- MtdPartition *partitions = malloc(nump * sizeof(*partitions));
- if (partitions == NULL) {
- errno = ENOMEM;
- return -1;
- }
- g_mtd_state.partitions = partitions;
- g_mtd_state.partitions_allocd = nump;
- memset(partitions, 0, nump * sizeof(*partitions));
- }
- g_mtd_state.partition_count = 0;
-
- /* Initialize all of the entries to make things easier later.
- * (Lets us handle sparsely-numbered partitions, which
- * may not even be possible.)
- */
- for (i = 0; i < g_mtd_state.partitions_allocd; i++) {
- MtdPartition *p = &g_mtd_state.partitions[i];
- if (p->name != NULL) {
- free(p->name);
- p->name = NULL;
- }
- p->device_index = -1;
- }
-
- /* Open and read the file contents.
- */
- fd = open(MTD_PROC_FILENAME, O_RDONLY);
- if (fd < 0) {
- goto bail;
- }
- nbytes = read(fd, buf, sizeof(buf) - 1);
- close(fd);
- if (nbytes < 0) {
- goto bail;
- }
- buf[nbytes] = '\0';
-
- /* Parse the contents of the file, which looks like:
- *
- * # cat /proc/mtd
- * dev: size erasesize name
- * mtd0: 00080000 00020000 "bootloader"
- * mtd1: 00400000 00020000 "mfg_and_gsm"
- * mtd2: 00400000 00020000 "0000000c"
- * mtd3: 00200000 00020000 "0000000d"
- * mtd4: 04000000 00020000 "system"
- * mtd5: 03280000 00020000 "userdata"
- */
- bufp = buf;
- while (nbytes > 0) {
- int mtdnum, mtdsize, mtderasesize;
- int matches;
- char mtdname[64];
- mtdname[0] = '\0';
- mtdnum = -1;
-
- matches = sscanf(bufp, "mtd%d: %x %x \"%63[^\"]",
- &mtdnum, &mtdsize, &mtderasesize, mtdname);
- /* This will fail on the first line, which just contains
- * column headers.
- */
- if (matches == 4) {
- MtdPartition *p = &g_mtd_state.partitions[mtdnum];
- p->device_index = mtdnum;
- p->size = mtdsize;
- p->erase_size = mtderasesize;
- p->name = strdup(mtdname);
- if (p->name == NULL) {
- errno = ENOMEM;
- goto bail;
- }
- g_mtd_state.partition_count++;
- }
-
- /* Eat the line.
- */
- while (nbytes > 0 && *bufp != '\n') {
- bufp++;
- nbytes--;
- }
- if (nbytes > 0) {
- bufp++;
- nbytes--;
- }
- }
-
- return g_mtd_state.partition_count;
-
-bail:
- // keep "partitions" around so we can free the names on a rescan.
- g_mtd_state.partition_count = -1;
- return -1;
-}
-
-const MtdPartition *
-mtd_find_partition_by_name(const char *name)
-{
- if (g_mtd_state.partitions != NULL) {
- int i;
- for (i = 0; i < g_mtd_state.partitions_allocd; i++) {
- MtdPartition *p = &g_mtd_state.partitions[i];
- if (p->device_index >= 0 && p->name != NULL) {
- if (strcmp(p->name, name) == 0) {
- return p;
- }
- }
- }
- }
- return NULL;
-}
-
-int
-mtd_mount_partition(const MtdPartition *partition, const char *mount_point,
- const char *filesystem, int read_only)
-{
- const unsigned long flags = MS_NOATIME | MS_NODEV | MS_NODIRATIME;
- char devname[64];
- int rv = -1;
-
- sprintf(devname, "/dev/block/mtdblock%d", partition->device_index);
- if (!read_only) {
- rv = mount(devname, mount_point, filesystem, flags, NULL);
- }
- if (read_only || rv < 0) {
- rv = mount(devname, mount_point, filesystem, flags | MS_RDONLY, 0);
- if (rv < 0) {
- printf("Failed to mount %s on %s: %s\n",
- devname, mount_point, strerror(errno));
- } else {
- printf("Mount %s on %s read-only\n", devname, mount_point);
- }
- }
-#if 1 //TODO: figure out why this is happening; remove include of stat.h
- if (rv >= 0) {
- /* For some reason, the x bits sometimes aren't set on the root
- * of mounted volumes.
- */
- struct stat st;
- rv = stat(mount_point, &st);
- if (rv < 0) {
- return rv;
- }
- mode_t new_mode = st.st_mode | S_IXUSR | S_IXGRP | S_IXOTH;
- if (new_mode != st.st_mode) {
-printf("Fixing execute permissions for %s\n", mount_point);
- rv = chmod(mount_point, new_mode);
- if (rv < 0) {
- printf("Couldn't fix permissions for %s: %s\n",
- mount_point, strerror(errno));
- }
- }
- }
-#endif
- return rv;
-}
-
-int
-mtd_partition_info(const MtdPartition *partition,
- size_t *total_size, size_t *erase_size, size_t *write_size)
-{
- char mtddevname[32];
- sprintf(mtddevname, "/dev/mtd/mtd%d", partition->device_index);
- int fd = open(mtddevname, O_RDONLY);
- if (fd < 0) return -1;
-
- struct mtd_info_user mtd_info;
- int ret = ioctl(fd, MEMGETINFO, &mtd_info);
- close(fd);
- if (ret < 0) return -1;
-
- if (total_size != NULL) *total_size = mtd_info.size;
- if (erase_size != NULL) *erase_size = mtd_info.erasesize;
- if (write_size != NULL) *write_size = mtd_info.writesize;
- return 0;
-}
-
-MtdReadContext *mtd_read_partition(const MtdPartition *partition)
-{
- MtdReadContext *ctx = (MtdReadContext*) malloc(sizeof(MtdReadContext));
- if (ctx == NULL) return NULL;
-
- ctx->buffer = malloc(partition->erase_size);
- if (ctx->buffer == NULL) {
- free(ctx);
- return NULL;
- }
-
- char mtddevname[32];
- sprintf(mtddevname, "/dev/mtd/mtd%d", partition->device_index);
- ctx->fd = open(mtddevname, O_RDONLY);
- if (ctx->fd < 0) {
- free(ctx);
- free(ctx->buffer);
- return NULL;
- }
-
- ctx->partition = partition;
- ctx->consumed = partition->erase_size;
- return ctx;
-}
-
-static int read_block(const MtdPartition *partition, int fd, char *data)
-{
- struct mtd_ecc_stats before, after;
- if (ioctl(fd, ECCGETSTATS, &before)) {
- fprintf(stderr, "mtd: ECCGETSTATS error (%s)\n", strerror(errno));
- return -1;
- }
-
- off_t pos = lseek(fd, 0, SEEK_CUR);
- ssize_t size = partition->erase_size;
- while (pos + size <= (int) partition->size) {
- if (lseek(fd, pos, SEEK_SET) != pos || read(fd, data, size) != size) {
- fprintf(stderr, "mtd: read error at 0x%08lx (%s)\n",
- pos, strerror(errno));
- } else if (ioctl(fd, ECCGETSTATS, &after)) {
- fprintf(stderr, "mtd: ECCGETSTATS error (%s)\n", strerror(errno));
- return -1;
- } else if (after.failed != before.failed) {
- fprintf(stderr, "mtd: ECC errors (%d soft, %d hard) at 0x%08lx\n",
- after.corrected - before.corrected,
- after.failed - before.failed, pos);
- } else {
- return 0; // Success!
- }
-
- pos += partition->erase_size;
- }
-
- errno = ENOSPC;
- return -1;
-}
-
-ssize_t mtd_read_data(MtdReadContext *ctx, char *data, size_t len)
-{
- ssize_t read = 0;
- while (read < (int) len) {
- if (ctx->consumed < ctx->partition->erase_size) {
- size_t avail = ctx->partition->erase_size - ctx->consumed;
- size_t copy = len - read < avail ? len - read : avail;
- memcpy(data + read, ctx->buffer + ctx->consumed, copy);
- ctx->consumed += copy;
- read += copy;
- }
-
- // Read complete blocks directly into the user's buffer
- while (ctx->consumed == ctx->partition->erase_size &&
- len - read >= ctx->partition->erase_size) {
- if (read_block(ctx->partition, ctx->fd, data + read)) return -1;
- read += ctx->partition->erase_size;
- }
-
- // Read the next block into the buffer
- if (ctx->consumed == ctx->partition->erase_size && read < (int) len) {
- if (read_block(ctx->partition, ctx->fd, ctx->buffer)) return -1;
- ctx->consumed = 0;
- }
- }
-
- return read;
-}
-
-void mtd_read_close(MtdReadContext *ctx)
-{
- close(ctx->fd);
- free(ctx->buffer);
- free(ctx);
-}
-
-MtdWriteContext *mtd_write_partition(const MtdPartition *partition)
-{
- MtdWriteContext *ctx = (MtdWriteContext*) malloc(sizeof(MtdWriteContext));
- if (ctx == NULL) return NULL;
-
- ctx->buffer = malloc(partition->erase_size);
- if (ctx->buffer == NULL) {
- free(ctx);
- return NULL;
- }
-
- char mtddevname[32];
- sprintf(mtddevname, "/dev/mtd/mtd%d", partition->device_index);
- ctx->fd = open(mtddevname, O_RDWR);
- if (ctx->fd < 0) {
- free(ctx->buffer);
- free(ctx);
- return NULL;
- }
-
- ctx->partition = partition;
- ctx->stored = 0;
- return ctx;
-}
-
-static int write_block(const MtdPartition *partition, int fd, const char *data)
-{
- off_t pos = lseek(fd, 0, SEEK_CUR);
- if (pos == (off_t) -1) return 1;
-
- ssize_t size = partition->erase_size;
- while (pos + size <= (int) partition->size) {
- loff_t bpos = pos;
- if (ioctl(fd, MEMGETBADBLOCK, &bpos) > 0) {
- fprintf(stderr, "mtd: not writing bad block at 0x%08lx\n", pos);
- pos += partition->erase_size;
- continue; // Don't try to erase known factory-bad blocks.
- }
-
- struct erase_info_user erase_info;
- erase_info.start = pos;
- erase_info.length = size;
- int retry;
- for (retry = 0; retry < 2; ++retry) {
- if (ioctl(fd, MEMERASE, &erase_info) < 0) {
- fprintf(stderr, "mtd: erase failure at 0x%08lx (%s)\n",
- pos, strerror(errno));
- continue;
- }
- if (lseek(fd, pos, SEEK_SET) != pos ||
- write(fd, data, size) != size) {
- fprintf(stderr, "mtd: write error at 0x%08lx (%s)\n",
- pos, strerror(errno));
- }
-
- char verify[size];
- if (lseek(fd, pos, SEEK_SET) != pos ||
- read(fd, verify, size) != size) {
- fprintf(stderr, "mtd: re-read error at 0x%08lx (%s)\n",
- pos, strerror(errno));
- continue;
- }
- if (memcmp(data, verify, size) != 0) {
- fprintf(stderr, "mtd: verification error at 0x%08lx (%s)\n",
- pos, strerror(errno));
- continue;
- }
-
- if (retry > 0) {
- fprintf(stderr, "mtd: wrote block after %d retries\n", retry);
- }
- return 0; // Success!
- }
-
- // Try to erase it once more as we give up on this block
- fprintf(stderr, "mtd: skipping write block at 0x%08lx\n", pos);
- ioctl(fd, MEMERASE, &erase_info);
- pos += partition->erase_size;
- }
-
- // Ran out of space on the device
- errno = ENOSPC;
- return -1;
-}
-
-ssize_t mtd_write_data(MtdWriteContext *ctx, const char *data, size_t len)
-{
- size_t wrote = 0;
- while (wrote < len) {
- // Coalesce partial writes into complete blocks
- if (ctx->stored > 0 || len - wrote < ctx->partition->erase_size) {
- size_t avail = ctx->partition->erase_size - ctx->stored;
- size_t copy = len - wrote < avail ? len - wrote : avail;
- memcpy(ctx->buffer + ctx->stored, data + wrote, copy);
- ctx->stored += copy;
- wrote += copy;
- }
-
- // If a complete block was accumulated, write it
- if (ctx->stored == ctx->partition->erase_size) {
- if (write_block(ctx->partition, ctx->fd, ctx->buffer)) return -1;
- ctx->stored = 0;
- }
-
- // Write complete blocks directly from the user's buffer
- while (ctx->stored == 0 && len - wrote >= ctx->partition->erase_size) {
- if (write_block(ctx->partition, ctx->fd, data + wrote)) return -1;
- wrote += ctx->partition->erase_size;
- }
- }
-
- return wrote;
-}
-
-off_t mtd_erase_blocks(MtdWriteContext *ctx, int blocks)
-{
- // Zero-pad and write any pending data to get us to a block boundary
- if (ctx->stored > 0) {
- size_t zero = ctx->partition->erase_size - ctx->stored;
- memset(ctx->buffer + ctx->stored, 0, zero);
- if (write_block(ctx->partition, ctx->fd, ctx->buffer)) return -1;
- ctx->stored = 0;
- }
-
- off_t pos = lseek(ctx->fd, 0, SEEK_CUR);
- if ((off_t) pos == (off_t) -1) return pos;
-
- const int total = (ctx->partition->size - pos) / ctx->partition->erase_size;
- if (blocks < 0) blocks = total;
- if (blocks > total) {
- errno = ENOSPC;
- return -1;
- }
-
- // Erase the specified number of blocks
- while (blocks-- > 0) {
- loff_t bpos = pos;
- if (ioctl(ctx->fd, MEMGETBADBLOCK, &bpos) > 0) {
- fprintf(stderr, "mtd: not erasing bad block at 0x%08lx\n", pos);
- pos += ctx->partition->erase_size;
- continue; // Don't try to erase known factory-bad blocks.
- }
-
- struct erase_info_user erase_info;
- erase_info.start = pos;
- erase_info.length = ctx->partition->erase_size;
- if (ioctl(ctx->fd, MEMERASE, &erase_info) < 0) {
- fprintf(stderr, "mtd: erase failure at 0x%08lx\n", pos);
- }
- pos += ctx->partition->erase_size;
- }
-
- return pos;
-}
-
-int mtd_write_close(MtdWriteContext *ctx)
-{
- int r = 0;
- // Make sure any pending data gets written
- if (mtd_erase_blocks(ctx, 0) == (off_t) -1) r = -1;
- if (close(ctx->fd)) r = -1;
- free(ctx->buffer);
- free(ctx);
- return r;
-}
diff --git a/mtdutils/mtdutils.h b/mtdutils/mtdutils.h
deleted file mode 100644
index 8d2cb56..0000000
--- a/mtdutils/mtdutils.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MTDUTILS_H_
-#define MTDUTILS_H_
-
-#include <sys/types.h> // for size_t, etc.
-
-typedef struct MtdPartition MtdPartition;
-
-int mtd_scan_partitions(void);
-
-const MtdPartition *mtd_find_partition_by_name(const char *name);
-
-/* mount_point is like "/system"
- * filesystem is like "yaffs2"
- */
-int mtd_mount_partition(const MtdPartition *partition, const char *mount_point,
- const char *filesystem, int read_only);
-
-/* get the partition and the minimum erase/write block size. NULL is ok.
- */
-int mtd_partition_info(const MtdPartition *partition,
- size_t *total_size, size_t *erase_size, size_t *write_size);
-
-/* read or write raw data from a partition, starting at the beginning.
- * skips bad blocks as best we can.
- */
-typedef struct MtdReadContext MtdReadContext;
-typedef struct MtdWriteContext MtdWriteContext;
-
-MtdReadContext *mtd_read_partition(const MtdPartition *);
-ssize_t mtd_read_data(MtdReadContext *, char *data, size_t data_len);
-void mtd_read_close(MtdReadContext *);
-
-MtdWriteContext *mtd_write_partition(const MtdPartition *);
-ssize_t mtd_write_data(MtdWriteContext *, const char *data, size_t data_len);
-off_t mtd_erase_blocks(MtdWriteContext *, int blocks); /* 0 ok, -1 for all */
-int mtd_write_close(MtdWriteContext *);
-
-#endif // MTDUTILS_H_
diff --git a/recovery.c b/recovery.c
deleted file mode 100644
index 221ee29..0000000
--- a/recovery.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <getopt.h>
-#include <limits.h>
-#include <linux/input.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/reboot.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "bootloader.h"
-#include "commands.h"
-#include "common.h"
-#include "cutils/properties.h"
-#include "firmware.h"
-#include "install.h"
-#include "minui/minui.h"
-#include "minzip/DirUtil.h"
-#include "roots.h"
-
-static const struct option OPTIONS[] = {
- { "send_intent", required_argument, NULL, 's' },
- { "update_package", required_argument, NULL, 'u' },
- { "wipe_data", no_argument, NULL, 'w' },
- { "wipe_cache", no_argument, NULL, 'c' },
-};
-
-static const char *COMMAND_FILE = "CACHE:recovery/command";
-static const char *INTENT_FILE = "CACHE:recovery/intent";
-static const char *LOG_FILE = "CACHE:recovery/log";
-static const char *SDCARD_PACKAGE_FILE = "SDCARD:update.zip";
-static const char *TEMPORARY_LOG_FILE = "/tmp/recovery.log";
-
-/*
- * The recovery tool communicates with the main system through /cache files.
- * /cache/recovery/command - INPUT - command line for tool, one arg per line
- * /cache/recovery/log - OUTPUT - combined log file from recovery run(s)
- * /cache/recovery/intent - OUTPUT - intent that was passed in
- *
- * The arguments which may be supplied in the recovery.command file:
- * --send_intent=anystring - write the text out to recovery.intent
- * --update_package=root:path - verify install an OTA package file
- * --wipe_data - erase user data (and cache), then reboot
- * --wipe_cache - wipe cache (but not user data), then reboot
- *
- * After completing, we remove /cache/recovery/command and reboot.
- * Arguments may also be supplied in the bootloader control block (BCB).
- * These important scenarios must be safely restartable at any point:
- *
- * FACTORY RESET
- * 1. user selects "factory reset"
- * 2. main system writes "--wipe_data" to /cache/recovery/command
- * 3. main system reboots into recovery
- * 4. get_args() writes BCB with "boot-recovery" and "--wipe_data"
- * -- after this, rebooting will restart the erase --
- * 5. erase_root() reformats /data
- * 6. erase_root() reformats /cache
- * 7. finish_recovery() erases BCB
- * -- after this, rebooting will restart the main system --
- * 8. main() calls reboot() to boot main system
- *
- * OTA INSTALL
- * 1. main system downloads OTA package to /cache/some-filename.zip
- * 2. main system writes "--update_package=CACHE:some-filename.zip"
- * 3. main system reboots into recovery
- * 4. get_args() writes BCB with "boot-recovery" and "--update_package=..."
- * -- after this, rebooting will attempt to reinstall the update --
- * 5. install_package() attempts to install the update
- * NOTE: the package install must itself be restartable from any point
- * 6. finish_recovery() erases BCB
- * -- after this, rebooting will (try to) restart the main system --
- * 7. ** if install failed **
- * 7a. prompt_and_wait() shows an error icon and waits for the user
- * 7b; the user reboots (pulling the battery, etc) into the main system
- * 8. main() calls maybe_install_firmware_update()
- * ** if the update contained radio/hboot firmware **:
- * 8a. m_i_f_u() writes BCB with "boot-recovery" and "--wipe_cache"
- * -- after this, rebooting will reformat cache & restart main system --
- * 8b. m_i_f_u() writes firmware image into raw cache partition
- * 8c. m_i_f_u() writes BCB with "update-radio/hboot" and "--wipe_cache"
- * -- after this, rebooting will attempt to reinstall firmware --
- * 8d. bootloader tries to flash firmware
- * 8e. bootloader writes BCB with "boot-recovery" (keeping "--wipe_cache")
- * -- after this, rebooting will reformat cache & restart main system --
- * 8f. erase_root() reformats /cache
- * 8g. finish_recovery() erases BCB
- * -- after this, rebooting will (try to) restart the main system --
- * 9. main() calls reboot() to boot main system
- */
-
-static const int MAX_ARG_LENGTH = 4096;
-static const int MAX_ARGS = 100;
-
-// open a file given in root:path format, mounting partitions as necessary
-static FILE*
-fopen_root_path(const char *root_path, const char *mode) {
- if (ensure_root_path_mounted(root_path) != 0) {
- LOGE("Can't mount %s\n", root_path);
- return NULL;
- }
-
- char path[PATH_MAX] = "";
- if (translate_root_path(root_path, path, sizeof(path)) == NULL) {
- LOGE("Bad path %s\n", root_path);
- return NULL;
- }
-
- // When writing, try to create the containing directory, if necessary.
- // Use generous permissions, the system (init.rc) will reset them.
- if (strchr("wa", mode[0])) dirCreateHierarchy(path, 0777, NULL, 1);
-
- FILE *fp = fopen(path, mode);
- if (fp == NULL) LOGE("Can't open %s\n", path);
- return fp;
-}
-
-// close a file, log an error if the error indicator is set
-static void
-check_and_fclose(FILE *fp, const char *name) {
- fflush(fp);
- if (ferror(fp)) LOGE("Error in %s\n(%s)\n", name, strerror(errno));
- fclose(fp);
-}
-
-// command line args come from, in decreasing precedence:
-// - the actual command line
-// - the bootloader control block (one per line, after "recovery")
-// - the contents of COMMAND_FILE (one per line)
-static void
-get_args(int *argc, char ***argv) {
- struct bootloader_message boot;
- memset(&boot, 0, sizeof(boot));
- get_bootloader_message(&boot); // this may fail, leaving a zeroed structure
-
- if (boot.command[0] != 0 && boot.command[0] != 255) {
- LOGI("Boot command: %.*s\n", sizeof(boot.command), boot.command);
- }
-
- if (boot.status[0] != 0 && boot.status[0] != 255) {
- LOGI("Boot status: %.*s\n", sizeof(boot.status), boot.status);
- }
-
- // --- if arguments weren't supplied, look in the bootloader control block
- if (*argc <= 1) {
- boot.recovery[sizeof(boot.recovery) - 1] = '\0'; // Ensure termination
- const char *arg = strtok(boot.recovery, "\n");
- if (arg != NULL && !strcmp(arg, "recovery")) {
- *argv = (char **) malloc(sizeof(char *) * MAX_ARGS);
- (*argv)[0] = strdup(arg);
- for (*argc = 1; *argc < MAX_ARGS; ++*argc) {
- if ((arg = strtok(NULL, "\n")) == NULL) break;
- (*argv)[*argc] = strdup(arg);
- }
- LOGI("Got arguments from boot message\n");
- } else if (boot.recovery[0] != 0 && boot.recovery[0] != 255) {
- LOGE("Bad boot message\n\"%.20s\"\n", boot.recovery);
- }
- }
-
- // --- if that doesn't work, try the command file
- if (*argc <= 1) {
- FILE *fp = fopen_root_path(COMMAND_FILE, "r");
- if (fp != NULL) {
- char *argv0 = (*argv)[0];
- *argv = (char **) malloc(sizeof(char *) * MAX_ARGS);
- (*argv)[0] = argv0; // use the same program name
-
- char buf[MAX_ARG_LENGTH];
- for (*argc = 1; *argc < MAX_ARGS; ++*argc) {
- if (!fgets(buf, sizeof(buf), fp)) break;
- (*argv)[*argc] = strdup(strtok(buf, "\r\n")); // Strip newline.
- }
-
- check_and_fclose(fp, COMMAND_FILE);
- LOGI("Got arguments from %s\n", COMMAND_FILE);
- }
- }
-
- // --> write the arguments we have back into the bootloader control block
- // always boot into recovery after this (until finish_recovery() is called)
- strlcpy(boot.command, "boot-recovery", sizeof(boot.command));
- strlcpy(boot.recovery, "recovery\n", sizeof(boot.recovery));
- int i;
- for (i = 1; i < *argc; ++i) {
- strlcat(boot.recovery, (*argv)[i], sizeof(boot.recovery));
- strlcat(boot.recovery, "\n", sizeof(boot.recovery));
- }
- set_bootloader_message(&boot);
-}
-
-
-// clear the recovery command and prepare to boot a (hopefully working) system,
-// copy our log file to cache as well (for the system to read), and
-// record any intent we were asked to communicate back to the system.
-// this function is idempotent: call it as many times as you like.
-static void
-finish_recovery(const char *send_intent)
-{
- // By this point, we're ready to return to the main system...
- if (send_intent != NULL) {
- FILE *fp = fopen_root_path(INTENT_FILE, "w");
- if (fp != NULL) {
- fputs(send_intent, fp);
- check_and_fclose(fp, INTENT_FILE);
- }
- }
-
- // Copy logs to cache so the system can find out what happened.
- FILE *log = fopen_root_path(LOG_FILE, "a");
- if (log != NULL) {
- FILE *tmplog = fopen(TEMPORARY_LOG_FILE, "r");
- if (tmplog == NULL) {
- LOGE("Can't open %s\n", TEMPORARY_LOG_FILE);
- } else {
- static long tmplog_offset = 0;
- fseek(tmplog, tmplog_offset, SEEK_SET); // Since last write
- char buf[4096];
- while (fgets(buf, sizeof(buf), tmplog)) fputs(buf, log);
- tmplog_offset = ftell(tmplog);
- check_and_fclose(tmplog, TEMPORARY_LOG_FILE);
- }
- check_and_fclose(log, LOG_FILE);
- }
-
- // Reset the bootloader message to revert to a normal main system boot.
- struct bootloader_message boot;
- memset(&boot, 0, sizeof(boot));
- set_bootloader_message(&boot);
-
- // Remove the command file, so recovery won't repeat indefinitely.
- char path[PATH_MAX] = "";
- if (ensure_root_path_mounted(COMMAND_FILE) != 0 ||
- translate_root_path(COMMAND_FILE, path, sizeof(path)) == NULL ||
- (unlink(path) && errno != ENOENT)) {
- LOGW("Can't unlink %s\n", COMMAND_FILE);
- }
-
- sync(); // For good measure.
-}
-
-#define TEST_AMEND 0
-#if TEST_AMEND
-static void
-test_amend()
-{
- extern int test_symtab(void);
- extern int test_cmd_fn(void);
- extern int test_permissions(void);
- int ret;
- LOGD("Testing symtab...\n");
- ret = test_symtab();
- LOGD(" returned %d\n", ret);
- LOGD("Testing cmd_fn...\n");
- ret = test_cmd_fn();
- LOGD(" returned %d\n", ret);
- LOGD("Testing permissions...\n");
- ret = test_permissions();
- LOGD(" returned %d\n", ret);
-}
-#endif // TEST_AMEND
-
-static int
-erase_root(const char *root)
-{
- ui_set_background(BACKGROUND_ICON_INSTALLING);
- ui_show_indeterminate_progress();
- ui_print("Formatting %s...\n", root);
- return format_root_device(root);
-}
-
-static void
-prompt_and_wait()
-{
- char* headers[] = { "Android system recovery utility",
- "",
- "Use trackball to highlight;",
- "click to select.",
- "",
- NULL };
-
- // these constants correspond to elements of the items[] list.
-#define ITEM_REBOOT 0
-#define ITEM_APPLY_SDCARD 1
-#define ITEM_WIPE_DATA 2
- char* items[] = { "reboot system now [Home+Back]",
- "apply sdcard:update.zip [Alt+S]",
- "wipe data/factory reset [Alt+W]",
- NULL };
-
- ui_start_menu(headers, items);
- int selected = 0;
- int chosen_item = -1;
-
- finish_recovery(NULL);
- ui_reset_progress();
- for (;;) {
- int key = ui_wait_key();
- int alt = ui_key_pressed(KEY_LEFTALT) || ui_key_pressed(KEY_RIGHTALT);
- int visible = ui_text_visible();
-
- if (key == KEY_DREAM_BACK && ui_key_pressed(KEY_DREAM_HOME)) {
- // Wait for the keys to be released, to avoid triggering
- // special boot modes (like coming back into recovery!).
- while (ui_key_pressed(KEY_DREAM_BACK) ||
- ui_key_pressed(KEY_DREAM_HOME)) {
- usleep(1000);
- }
- chosen_item = ITEM_REBOOT;
- } else if (alt && key == KEY_W) {
- chosen_item = ITEM_WIPE_DATA;
- } else if (alt && key == KEY_S) {
- chosen_item = ITEM_APPLY_SDCARD;
- } else if ((key == KEY_DOWN || key == KEY_VOLUMEDOWN) && visible) {
- ++selected;
- selected = ui_menu_select(selected);
- } else if ((key == KEY_UP || key == KEY_VOLUMEUP) && visible) {
- --selected;
- selected = ui_menu_select(selected);
- } else if (key == BTN_MOUSE && visible) {
- chosen_item = selected;
- }
-
- if (chosen_item >= 0) {
- // turn off the menu, letting ui_print() to scroll output
- // on the screen.
- ui_end_menu();
-
- switch (chosen_item) {
- case ITEM_REBOOT:
- return;
-
- case ITEM_WIPE_DATA:
- ui_print("\n-- Wiping data...\n");
- erase_root("DATA:");
- erase_root("CACHE:");
- ui_print("Data wipe complete.\n");
- if (!ui_text_visible()) return;
- break;
-
- case ITEM_APPLY_SDCARD:
- ui_print("\n-- Install from sdcard...\n");
- int status = install_package(SDCARD_PACKAGE_FILE);
- if (status != INSTALL_SUCCESS) {
- ui_set_background(BACKGROUND_ICON_ERROR);
- ui_print("Installation aborted.\n");
- } else if (!ui_text_visible()) {
- return; // reboot if logs aren't visible
- } else {
- ui_print("Install from sdcard complete.\n");
- }
- break;
- }
-
- // if we didn't return from this function to reboot, show
- // the menu again.
- ui_start_menu(headers, items);
- selected = 0;
- chosen_item = -1;
-
- finish_recovery(NULL);
- ui_reset_progress();
-
- // throw away keys pressed while the command was running,
- // so user doesn't accidentally trigger menu items.
- ui_clear_key_queue();
- }
- }
-}
-
-static void
-print_property(const char *key, const char *name, void *cookie)
-{
- fprintf(stderr, "%s=%s\n", key, name);
-}
-
-int
-main(int argc, char **argv)
-{
- time_t start = time(NULL);
-
- // If these fail, there's not really anywhere to complain...
- freopen(TEMPORARY_LOG_FILE, "a", stdout); setbuf(stdout, NULL);
- freopen(TEMPORARY_LOG_FILE, "a", stderr); setbuf(stderr, NULL);
- fprintf(stderr, "Starting recovery on %s", ctime(&start));
-
- ui_init();
- get_args(&argc, &argv);
-
- int previous_runs = 0;
- const char *send_intent = NULL;
- const char *update_package = NULL;
- int wipe_data = 0, wipe_cache = 0;
-
- int arg;
- while ((arg = getopt_long(argc, argv, "", OPTIONS, NULL)) != -1) {
- switch (arg) {
- case 'p': previous_runs = atoi(optarg); break;
- case 's': send_intent = optarg; break;
- case 'u': update_package = optarg; break;
- case 'w': wipe_data = wipe_cache = 1; break;
- case 'c': wipe_cache = 1; break;
- case '?':
- LOGE("Invalid command argument\n");
- continue;
- }
- }
-
- fprintf(stderr, "Command:");
- for (arg = 0; arg < argc; arg++) {
- fprintf(stderr, " \"%s\"", argv[arg]);
- }
- fprintf(stderr, "\n\n");
-
- property_list(print_property, NULL);
- fprintf(stderr, "\n");
-
-#if TEST_AMEND
- test_amend();
-#endif
-
- RecoveryCommandContext ctx = { NULL };
- if (register_update_commands(&ctx)) {
- LOGE("Can't install update commands\n");
- }
-
- int status = INSTALL_SUCCESS;
-
- if (update_package != NULL) {
- status = install_package(update_package);
- if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
- } else if (wipe_data || wipe_cache) {
- if (wipe_data && erase_root("DATA:")) status = INSTALL_ERROR;
- if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
- if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
- } else {
- status = INSTALL_ERROR; // No command specified
- }
-
- if (status != INSTALL_SUCCESS) ui_set_background(BACKGROUND_ICON_ERROR);
- if (status != INSTALL_SUCCESS || ui_text_visible()) prompt_and_wait();
-
- // If there is a radio image pending, reboot now to install it.
- maybe_install_firmware_update(send_intent);
-
- // Otherwise, get ready to boot the main system...
- finish_recovery(send_intent);
- ui_print("Rebooting...\n");
- sync();
- reboot(RB_AUTOBOOT);
- return EXIT_SUCCESS;
-}
diff --git a/res/images/icon_error.bmp b/res/images/icon_error.bmp
deleted file mode 100644
index 7eb2bbc..0000000
--- a/res/images/icon_error.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/icon_firmware_error.bmp b/res/images/icon_firmware_error.bmp
deleted file mode 100644
index 5b8649f..0000000
--- a/res/images/icon_firmware_error.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/icon_firmware_install.bmp b/res/images/icon_firmware_install.bmp
deleted file mode 100644
index b0f5f95..0000000
--- a/res/images/icon_firmware_install.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/icon_installing.bmp b/res/images/icon_installing.bmp
deleted file mode 100644
index fff99fd..0000000
--- a/res/images/icon_installing.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/icon_unpacking.bmp b/res/images/icon_unpacking.bmp
deleted file mode 100644
index ab6548c..0000000
--- a/res/images/icon_unpacking.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/indeterminate1.bmp b/res/images/indeterminate1.bmp
deleted file mode 100644
index 716c925..0000000
--- a/res/images/indeterminate1.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/indeterminate2.bmp b/res/images/indeterminate2.bmp
deleted file mode 100644
index 223cd3c..0000000
--- a/res/images/indeterminate2.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/indeterminate3.bmp b/res/images/indeterminate3.bmp
deleted file mode 100644
index fd9086a..0000000
--- a/res/images/indeterminate3.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/indeterminate4.bmp b/res/images/indeterminate4.bmp
deleted file mode 100644
index 87b2640..0000000
--- a/res/images/indeterminate4.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/indeterminate5.bmp b/res/images/indeterminate5.bmp
deleted file mode 100644
index e16efb0..0000000
--- a/res/images/indeterminate5.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/indeterminate6.bmp b/res/images/indeterminate6.bmp
deleted file mode 100644
index 085ad95..0000000
--- a/res/images/indeterminate6.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/progress_bar_empty.bmp b/res/images/progress_bar_empty.bmp
deleted file mode 100644
index 8e512fd..0000000
--- a/res/images/progress_bar_empty.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/progress_bar_empty_left_round.bmp b/res/images/progress_bar_empty_left_round.bmp
deleted file mode 100644
index c4e2f44..0000000
--- a/res/images/progress_bar_empty_left_round.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/progress_bar_empty_right_round.bmp b/res/images/progress_bar_empty_right_round.bmp
deleted file mode 100644
index 1906f62..0000000
--- a/res/images/progress_bar_empty_right_round.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/progress_bar_fill.bmp b/res/images/progress_bar_fill.bmp
deleted file mode 100644
index 8d57d81..0000000
--- a/res/images/progress_bar_fill.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/progress_bar_left_round.bmp b/res/images/progress_bar_left_round.bmp
deleted file mode 100644
index 6d2df8d..0000000
--- a/res/images/progress_bar_left_round.bmp
+++ /dev/null
Binary files differ
diff --git a/res/images/progress_bar_right_round.bmp b/res/images/progress_bar_right_round.bmp
deleted file mode 100644
index 68bb6fe..0000000
--- a/res/images/progress_bar_right_round.bmp
+++ /dev/null
Binary files differ
diff --git a/roots.c b/roots.c
deleted file mode 100644
index 6a6cf8a..0000000
--- a/roots.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "mtdutils/mtdutils.h"
-#include "mtdutils/mounts.h"
-#include "minzip/Zip.h"
-#include "roots.h"
-#include "common.h"
-
-typedef struct {
- const char *name;
- const char *device;
- const char *device2; // If the first one doesn't work (may be NULL)
- const char *partition_name;
- const char *mount_point;
- const char *filesystem;
-} RootInfo;
-
-/* Canonical pointers.
-xxx may just want to use enums
- */
-static const char g_mtd_device[] = "@\0g_mtd_device";
-static const char g_raw[] = "@\0g_raw";
-static const char g_package_file[] = "@\0g_package_file";
-
-static RootInfo g_roots[] = {
- { "BOOT:", g_mtd_device, NULL, "boot", NULL, g_raw },
- { "CACHE:", g_mtd_device, NULL, "cache", "/cache", "yaffs2" },
- { "DATA:", g_mtd_device, NULL, "userdata", "/data", "yaffs2" },
- { "MISC:", g_mtd_device, NULL, "misc", NULL, g_raw },
- { "PACKAGE:", NULL, NULL, NULL, NULL, g_package_file },
- { "RECOVERY:", g_mtd_device, NULL, "recovery", "/", g_raw },
- { "SDCARD:", "/dev/block/mmcblk0p1", "/dev/block/mmcblk0", NULL, "/sdcard", "vfat" },
- { "SYSTEM:", g_mtd_device, NULL, "system", "/system", "yaffs2" },
- { "TMP:", NULL, NULL, NULL, "/tmp", NULL },
-};
-#define NUM_ROOTS (sizeof(g_roots) / sizeof(g_roots[0]))
-
-// TODO: for SDCARD:, try /dev/block/mmcblk0 if mmcblk0p1 fails
-
-static const RootInfo *
-get_root_info_for_path(const char *root_path)
-{
- const char *c;
-
- /* Find the first colon.
- */
- c = root_path;
- while (*c != '\0' && *c != ':') {
- c++;
- }
- if (*c == '\0') {
- return NULL;
- }
- size_t len = c - root_path + 1;
- size_t i;
- for (i = 0; i < NUM_ROOTS; i++) {
- RootInfo *info = &g_roots[i];
- if (strncmp(info->name, root_path, len) == 0) {
- return info;
- }
- }
- return NULL;
-}
-
-static const ZipArchive *g_package = NULL;
-static char *g_package_path = NULL;
-
-int
-register_package_root(const ZipArchive *package, const char *package_path)
-{
- if (package != NULL) {
- package_path = strdup(package_path);
- if (package_path == NULL) {
- return -1;
- }
- g_package_path = (char *)package_path;
- } else {
- free(g_package_path);
- g_package_path = NULL;
- }
- g_package = package;
- return 0;
-}
-
-int
-is_package_root_path(const char *root_path)
-{
- const RootInfo *info = get_root_info_for_path(root_path);
- return info != NULL && info->filesystem == g_package_file;
-}
-
-const char *
-translate_package_root_path(const char *root_path,
- char *out_buf, size_t out_buf_len, const ZipArchive **out_package)
-{
- const RootInfo *info = get_root_info_for_path(root_path);
- if (info == NULL || info->filesystem != g_package_file) {
- return NULL;
- }
-
- /* Strip the package root off of the path.
- */
- size_t root_len = strlen(info->name);
- root_path += root_len;
- size_t root_path_len = strlen(root_path);
-
- if (out_buf_len < root_path_len + 1) {
- return NULL;
- }
- strcpy(out_buf, root_path);
- *out_package = g_package;
- return out_buf;
-}
-
-/* Takes a string like "SYSTEM:lib" and turns it into a string
- * like "/system/lib". The translated path is put in out_buf,
- * and out_buf is returned if the translation succeeded.
- */
-const char *
-translate_root_path(const char *root_path, char *out_buf, size_t out_buf_len)
-{
- if (out_buf_len < 1) {
- return NULL;
- }
-
- const RootInfo *info = get_root_info_for_path(root_path);
- if (info == NULL || info->mount_point == NULL) {
- return NULL;
- }
-
- /* Find the relative part of the non-root part of the path.
- */
- root_path += strlen(info->name); // strip off the "root:"
- while (*root_path != '\0' && *root_path == '/') {
- root_path++;
- }
-
- size_t mp_len = strlen(info->mount_point);
- size_t rp_len = strlen(root_path);
- if (mp_len + 1 + rp_len + 1 > out_buf_len) {
- return NULL;
- }
-
- /* Glue the mount point to the relative part of the path.
- */
- memcpy(out_buf, info->mount_point, mp_len);
- if (out_buf[mp_len - 1] != '/') out_buf[mp_len++] = '/';
-
- memcpy(out_buf + mp_len, root_path, rp_len);
- out_buf[mp_len + rp_len] = '\0';
-
- return out_buf;
-}
-
-static int
-internal_root_mounted(const RootInfo *info)
-{
- if (info->mount_point == NULL) {
- return -1;
- }
-//xxx if TMP: (or similar) just say "yes"
-
- /* See if this root is already mounted.
- */
- int ret = scan_mounted_volumes();
- if (ret < 0) {
- return ret;
- }
- const MountedVolume *volume;
- volume = find_mounted_volume_by_mount_point(info->mount_point);
- if (volume != NULL) {
- /* It's already mounted.
- */
- return 0;
- }
- return -1;
-}
-
-int
-is_root_path_mounted(const char *root_path)
-{
- const RootInfo *info = get_root_info_for_path(root_path);
- if (info == NULL) {
- return -1;
- }
- return internal_root_mounted(info) >= 0;
-}
-
-int
-ensure_root_path_mounted(const char *root_path)
-{
- const RootInfo *info = get_root_info_for_path(root_path);
- if (info == NULL) {
- return -1;
- }
-
- int ret = internal_root_mounted(info);
- if (ret >= 0) {
- /* It's already mounted.
- */
- return 0;
- }
-
- /* It's not mounted.
- */
- if (info->device == g_mtd_device) {
- if (info->partition_name == NULL) {
- return -1;
- }
-//TODO: make the mtd stuff scan once when it needs to
- mtd_scan_partitions();
- const MtdPartition *partition;
- partition = mtd_find_partition_by_name(info->partition_name);
- if (partition == NULL) {
- return -1;
- }
- return mtd_mount_partition(partition, info->mount_point,
- info->filesystem, 0);
- }
-
- if (info->device == NULL || info->mount_point == NULL ||
- info->filesystem == NULL ||
- info->filesystem == g_raw ||
- info->filesystem == g_package_file) {
- return -1;
- }
-
- mkdir(info->mount_point, 0755); // in case it doesn't already exist
- if (mount(info->device, info->mount_point, info->filesystem,
- MS_NOATIME | MS_NODEV | MS_NODIRATIME, "")) {
- if (info->device2 == NULL) {
- LOGE("Can't mount %s\n(%s)\n", info->device, strerror(errno));
- return -1;
- } else if (mount(info->device2, info->mount_point, info->filesystem,
- MS_NOATIME | MS_NODEV | MS_NODIRATIME, "")) {
- LOGE("Can't mount %s (or %s)\n(%s)\n",
- info->device, info->device2, strerror(errno));
- return -1;
- }
- }
- return 0;
-}
-
-int
-ensure_root_path_unmounted(const char *root_path)
-{
- const RootInfo *info = get_root_info_for_path(root_path);
- if (info == NULL) {
- return -1;
- }
- if (info->mount_point == NULL) {
- /* This root can't be mounted, so by definition it isn't.
- */
- return 0;
- }
-//xxx if TMP: (or similar) just return error
-
- /* See if this root is already mounted.
- */
- int ret = scan_mounted_volumes();
- if (ret < 0) {
- return ret;
- }
- const MountedVolume *volume;
- volume = find_mounted_volume_by_mount_point(info->mount_point);
- if (volume == NULL) {
- /* It's not mounted.
- */
- return 0;
- }
-
- return unmount_mounted_volume(volume);
-}
-
-const MtdPartition *
-get_root_mtd_partition(const char *root_path)
-{
- const RootInfo *info = get_root_info_for_path(root_path);
- if (info == NULL || info->device != g_mtd_device ||
- info->partition_name == NULL)
- {
- return NULL;
- }
- mtd_scan_partitions();
- return mtd_find_partition_by_name(info->partition_name);
-}
-
-int
-format_root_device(const char *root)
-{
- /* Be a little safer here; require that "root" is just
- * a device with no relative path after it.
- */
- const char *c = root;
- while (*c != '\0' && *c != ':') {
- c++;
- }
- if (c[0] != ':' || c[1] != '\0') {
- LOGW("format_root_device: bad root name \"%s\"\n", root);
- return -1;
- }
-
- const RootInfo *info = get_root_info_for_path(root);
- if (info == NULL || info->device == NULL) {
- LOGW("format_root_device: can't resolve \"%s\"\n", root);
- return -1;
- }
- if (info->mount_point != NULL) {
- /* Don't try to format a mounted device.
- */
- int ret = ensure_root_path_unmounted(root);
- if (ret < 0) {
- LOGW("format_root_device: can't unmount \"%s\"\n", root);
- return ret;
- }
- }
-
- /* Format the device.
- */
- if (info->device == g_mtd_device) {
- mtd_scan_partitions();
- const MtdPartition *partition;
- partition = mtd_find_partition_by_name(info->partition_name);
- if (partition == NULL) {
- LOGW("format_root_device: can't find mtd partition \"%s\"\n",
- info->partition_name);
- return -1;
- }
- if (info->filesystem == g_raw || !strcmp(info->filesystem, "yaffs2")) {
- MtdWriteContext *write = mtd_write_partition(partition);
- if (write == NULL) {
- LOGW("format_root_device: can't open \"%s\"\n", root);
- return -1;
- } else if (mtd_erase_blocks(write, -1) == (off_t) -1) {
- LOGW("format_root_device: can't erase \"%s\"\n", root);
- mtd_write_close(write);
- return -1;
- } else if (mtd_write_close(write)) {
- LOGW("format_root_device: can't close \"%s\"\n", root);
- return -1;
- } else {
- return 0;
- }
- }
- }
-//TODO: handle other device types (sdcard, etc.)
- LOGW("format_root_device: can't handle non-mtd device \"%s\"\n", root);
- return -1;
-}
diff --git a/roots.h b/roots.h
deleted file mode 100644
index bc847ea..0000000
--- a/roots.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef RECOVERY_ROOTS_H_
-#define RECOVERY_ROOTS_H_
-
-#include "minzip/Zip.h"
-#include "mtdutils/mtdutils.h"
-
-/* Any of the "root_path" arguments can be paths with relative
- * components, like "SYSTEM:a/b/c".
- */
-
-/* Associate this package with the package root "PKG:".
- */
-int register_package_root(const ZipArchive *package, const char *package_path);
-
-/* Returns non-zero iff root_path points inside a package.
- */
-int is_package_root_path(const char *root_path);
-
-/* Takes a string like "SYSTEM:lib" and turns it into a string
- * like "/system/lib". The translated path is put in out_buf,
- * and out_buf is returned if the translation succeeded.
- */
-const char *translate_root_path(const char *root_path,
- char *out_buf, size_t out_buf_len);
-
-/* Takes a string like "PKG:lib/libc.so" and returns a pointer to
- * the containing zip file and a path like "lib/libc.so".
- */
-const char *translate_package_root_path(const char *root_path,
- char *out_buf, size_t out_buf_len, const ZipArchive **out_package);
-
-/* Returns negative on error, positive if it's mounted, zero if it isn't.
- */
-int is_root_path_mounted(const char *root_path);
-
-int ensure_root_path_mounted(const char *root_path);
-
-int ensure_root_path_unmounted(const char *root_path);
-
-const MtdPartition *get_root_mtd_partition(const char *root_path);
-
-/* "root" must be the exact name of the root; no relative path is permitted.
- * If the named root is mounted, this will attempt to unmount it first.
- */
-int format_root_device(const char *root);
-
-#endif // RECOVERY_ROOTS_H_
diff --git a/test_roots.c b/test_roots.c
deleted file mode 100644
index f49f55e..0000000
--- a/test_roots.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <sys/stat.h>
-#include "roots.h"
-#include "common.h"
-
-#define CANARY_FILE "/system/build.prop"
-#define CANARY_FILE_ROOT_PATH "SYSTEM:build.prop"
-
-int
-file_exists(const char *path)
-{
- struct stat st;
- int ret;
- ret = stat(path, &st);
- if (ret == 0) {
- return S_ISREG(st.st_mode);
- }
- return 0;
-}
-
-int
-test_roots()
-{
- int ret;
-
- /* Make sure that /system isn't mounted yet.
- */
- if (file_exists(CANARY_FILE)) return -__LINE__;
- if (is_root_path_mounted(CANARY_FILE_ROOT_PATH)) return -__LINE__;
-
- /* Try to mount the root.
- */
- ret = ensure_root_path_mounted(CANARY_FILE_ROOT_PATH);
- if (ret < 0) return -__LINE__;
-
- /* Make sure we can see the file now and that we know the root is mounted.
- */
- if (!file_exists(CANARY_FILE)) return -__LINE__;
- if (!is_root_path_mounted(CANARY_FILE_ROOT_PATH)) return -__LINE__;
-
- /* Make sure that the root path corresponds to the regular path.
- */
- struct stat st1, st2;
- char buf[128];
- const char *path = translate_root_path(CANARY_FILE_ROOT_PATH,
- buf, sizeof(buf));
- if (path == NULL) return -__LINE__;
- ret = stat(CANARY_FILE, &st1);
- if (ret != 0) return -__LINE__;
- ret = stat(path, &st2);
- if (ret != 0) return -__LINE__;
- if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) return -__LINE__;
-
- /* Try to unmount the root.
- */
- ret = ensure_root_path_unmounted(CANARY_FILE_ROOT_PATH);
- if (ret < 0) return -__LINE__;
-
- /* Make sure that we can't see the file anymore and that
- * we don't think the root is mounted.
- */
- if (file_exists(CANARY_FILE)) return -__LINE__;
- if (is_root_path_mounted(CANARY_FILE_ROOT_PATH)) return -__LINE__;
-
- return 0;
-}
diff --git a/tools/Android.mk b/tools/Android.mk
deleted file mode 100644
index 6571161..0000000
--- a/tools/Android.mk
+++ /dev/null
@@ -1 +0,0 @@
-include $(all-subdir-makefiles)
diff --git a/tools/ota/Android.mk b/tools/ota/Android.mk
deleted file mode 100644
index b7a57d6..0000000
--- a/tools/ota/Android.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (C) 2008 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := make-update-script
-LOCAL_SRC_FILES := make-update-script.c
-include $(BUILD_HOST_EXECUTABLE)
-
-ifneq ($(TARGET_SIMULATOR),true)
-
-include $(CLEAR_VARS)
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE := add-property-tag
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := debug
-LOCAL_SRC_FILES := add-property-tag.c
-LOCAL_STATIC_LIBRARIES := libc
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE := check-lost+found
-LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
-LOCAL_MODULE_TAGS := debug
-LOCAL_SRC_FILES := check-lost+found.c
-LOCAL_STATIC_LIBRARIES := libcutils libc
-include $(BUILD_EXECUTABLE)
-
-endif # !TARGET_SIMULATOR
diff --git a/tools/ota/add-data-wipe b/tools/ota/add-data-wipe
deleted file mode 100755
index 8d2626f..0000000
--- a/tools/ota/add-data-wipe
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-PROGNAME=`basename $0`
-
-function cleantmp
-{
- if [ ! -z "$TMPDIR" ]
- then
- rm -rf "$TMPDIR"
- TMPDIR=
- fi
-}
-
-function println
-{
- if [ $# -gt 0 ]
- then
- echo "$PROGNAME: $@"
- fi
-}
-
-function fail
-{
- println "$@"
- cleantmp
- exit 1
-}
-
-function usage
-{
- println "$@"
- echo "Usage: $PROGNAME <input file> <output file>"
- fail
-}
-
-OTATOOL=`which otatool`
-if [ -z "$OTATOOL" ]
-then
- OTATOOL="`dirname $0`/otatool"
- if [ ! -x "$OTATOOL" ]
- then
- fail "Can't find otatool"
- fi
-fi
-
-
-if [ $# -ne 2 ]
-then
- usage
-fi
-
-INFILE="$1"
-OUTFILE="$2"
-
-if [ ! -f "$INFILE" ]
-then
- fail "$INFILE doesn't exist or isn't a file"
-fi
-
-if [ -z "$OUTFILE" ]
-then
- usage "Output file not specified"
-fi
-
-if [ -d "$OUTFILE" ]
-then
- usage "Output file may not be a directory"
-fi
-
-if [ "$INFILE" -ef "$OUTFILE" ]
-then
- fail "Refusing to use the input file as the output file"
-fi
-
-TMPDIR=`mktemp -d "/tmp/$PROGNAME.XXXXXX"`
-if [ $? -ne 0 ]
-then
- TMPDIR=
- fail "Can't create temporary directory"
-fi
-
-ORIGSCRIPT="$TMPDIR/orig"
-NEWSCRIPT="$TMPDIR/new"
-
-"$OTATOOL" --dump-script "$INFILE" |
-awk '
- { print }
- /^format SYSTEM:$/ {
- print "delete_recursive DATA:"
- }
-' > "$NEWSCRIPT"
-if [ $? -ne 0 ]
-then
- fail "Couldn't modify script"
-fi
-
-"$OTATOOL" --replace-script "$NEWSCRIPT" -o "$OUTFILE" "$INFILE"
-if [ $? -ne 0 ]
-then
- fail "Couldn't replace script"
-fi
-
-cleantmp
diff --git a/tools/ota/add-property-tag.c b/tools/ota/add-property-tag.c
deleted file mode 100644
index 5277edd..0000000
--- a/tools/ota/add-property-tag.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <ctype.h>
-#include <errno.h>
-#include <getopt.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*
- * Append a tag to a property value in a .prop file if it isn't already there.
- * Normally used to modify build properties to record incremental updates.
- */
-
-// Return nonzero if the tag should be added to this line.
-int should_tag(const char *line, const char *propname) {
- const char *prop = strstr(line, propname);
- if (prop == NULL) return 0;
-
- // Make sure this is actually the property name (not an accidental hit)
- const char *ptr;
- for (ptr = line; ptr < prop && isspace(*ptr); ++ptr) ;
- if (ptr != prop) return 0; // Must be at the beginning of the line
-
- for (ptr += strlen(propname); *ptr != '\0' && isspace(*ptr); ++ptr) ;
- return (*ptr == '='); // Must be followed by a '='
-}
-
-// Remove existing tags from the line, return the following number (if any)
-int remove_tag(char *line, const char *tag) {
- char *pos = strstr(line, tag);
- if (pos == NULL) return 0;
-
- char *end;
- int num = strtoul(pos + strlen(tag), &end, 10);
- strcpy(pos, end);
- return num;
-}
-
-// Write line to output with the tag added, adding a number (if >0)
-void write_tagged(FILE *out, const char *line, const char *tag, int number) {
- const char *end = line + strlen(line);
- while (end > line && isspace(end[-1])) --end;
- if (number > 0) {
- fprintf(out, "%.*s%s%d%s", end - line, line, tag, number, end);
- } else {
- fprintf(out, "%.*s%s%s", end - line, line, tag, end);
- }
-}
-
-int main(int argc, char **argv) {
- const char *filename = "/system/build.prop";
- const char *propname = "ro.build.fingerprint";
- const char *tag = NULL;
- int do_remove = 0, do_number = 0;
-
- int opt;
- while ((opt = getopt(argc, argv, "f:p:rn")) != -1) {
- switch (opt) {
- case 'f': filename = optarg; break;
- case 'p': propname = optarg; break;
- case 'r': do_remove = 1; break;
- case 'n': do_number = 1; break;
- case '?': return 2;
- }
- }
-
- if (argc != optind + 1) {
- fprintf(stderr,
- "usage: add-property-tag [flags] tag-to-add\n"
- "flags: -f /dir/file.prop (default /system/build.prop)\n"
- " -p prop.name (default ro.build.fingerprint)\n"
- " -r (if set, remove the tag rather than adding it)\n"
- " -n (if set, add and increment a number after the tag)\n");
- return 2;
- }
-
- tag = argv[optind];
- FILE *input = fopen(filename, "r");
- if (input == NULL) {
- fprintf(stderr, "can't read %s: %s\n", filename, strerror(errno));
- return 1;
- }
-
- char tmpname[PATH_MAX];
- snprintf(tmpname, sizeof(tmpname), "%s.tmp", filename);
- FILE *output = fopen(tmpname, "w");
- if (output == NULL) {
- fprintf(stderr, "can't write %s: %s\n", tmpname, strerror(errno));
- return 1;
- }
-
- int found = 0;
- char line[4096];
- while (fgets(line, sizeof(line), input)) {
- if (!should_tag(line, propname)) {
- fputs(line, output); // Pass through unmodified
- } else {
- found = 1;
- int number = remove_tag(line, tag);
- if (do_remove) {
- fputs(line, output); // Remove the tag but don't re-add it
- } else {
- write_tagged(output, line, tag, number + do_number);
- }
- }
- }
-
- fclose(input);
- fclose(output);
-
- if (!found) {
- fprintf(stderr, "property %s not found in %s\n", propname, filename);
- remove(tmpname);
- return 1;
- }
-
- if (rename(tmpname, filename)) {
- fprintf(stderr, "can't rename %s to %s: %s\n",
- tmpname, filename, strerror(errno));
- remove(tmpname);
- return 1;
- }
-
- return 0;
-}
diff --git a/tools/ota/check-lost+found.c b/tools/ota/check-lost+found.c
deleted file mode 100644
index f856275..0000000
--- a/tools/ota/check-lost+found.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <dirent.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/klog.h>
-#include <sys/reboot.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <time.h>
-
-#include "private/android_filesystem_config.h"
-
-// Sentinel file used to track whether we've forced a reboot
-static const char *kMarkerFile = "/data/misc/check-lost+found-rebooted-2";
-
-// Output file in tombstones directory (first 8K will be uploaded)
-static const char *kOutputDir = "/data/tombstones";
-static const char *kOutputFile = "/data/tombstones/check-lost+found-log";
-
-// Partitions to check
-static const char *kPartitions[] = { "/system", "/data", "/cache", NULL };
-
-/*
- * 1. If /data/misc/forced-reboot is missing, touch it & force "unclean" boot.
- * 2. Write a log entry with the number of files in lost+found directories.
- */
-
-int main(int argc, char **argv) {
- mkdir(kOutputDir, 0755);
- chown(kOutputDir, AID_SYSTEM, AID_SYSTEM);
- FILE *out = fopen(kOutputFile, "a");
- if (out == NULL) {
- fprintf(stderr, "Can't write %s: %s\n", kOutputFile, strerror(errno));
- return 1;
- }
-
- // Note: only the first 8K of log will be uploaded, so be terse.
- time_t start = time(NULL);
- fprintf(out, "*** check-lost+found ***\nStarted: %s", ctime(&start));
-
- struct stat st;
- if (stat(kMarkerFile, &st)) {
- // No reboot marker -- need to force an unclean reboot.
- // But first, try to create the marker file. If that fails,
- // skip the reboot, so we don't get caught in an infinite loop.
-
- int fd = open(kMarkerFile, O_WRONLY|O_CREAT, 0444);
- if (fd >= 0 && close(fd) == 0) {
- fprintf(out, "Wrote %s, rebooting\n", kMarkerFile);
- fflush(out);
- sync(); // Make sure the marker file is committed to disk
-
- // If possible, dirty each of these partitions before rebooting,
- // to make sure the filesystem has to do a scan on mount.
- int i;
- for (i = 0; kPartitions[i] != NULL; ++i) {
- char fn[PATH_MAX];
- snprintf(fn, sizeof(fn), "%s/%s", kPartitions[i], "dirty");
- fd = open(fn, O_WRONLY|O_CREAT, 0444);
- if (fd >= 0) { // Don't sweat it if we can't write the file.
- write(fd, fn, sizeof(fn)); // write, you know, some data
- close(fd);
- unlink(fn);
- }
- }
-
- reboot(RB_AUTOBOOT); // reboot immediately, with dirty filesystems
- fprintf(out, "Reboot failed?!\n");
- exit(1);
- } else {
- fprintf(out, "Can't write %s: %s\n", kMarkerFile, strerror(errno));
- }
- } else {
- fprintf(out, "Found %s\n", kMarkerFile);
- }
-
- int i;
- for (i = 0; kPartitions[i] != NULL; ++i) {
- char fn[PATH_MAX];
- snprintf(fn, sizeof(fn), "%s/%s", kPartitions[i], "lost+found");
- DIR *dir = opendir(fn);
- if (dir == NULL) {
- fprintf(out, "Can't open %s: %s\n", fn, strerror(errno));
- } else {
- int count = 0;
- struct dirent *ent;
- while ((ent = readdir(dir))) {
- if (strcmp(ent->d_name, ".") && strcmp(ent->d_name, ".."))
- ++count;
- }
- closedir(dir);
- if (count > 0) {
- fprintf(out, "OMGZ FOUND %d FILES IN %s\n", count, fn);
- } else {
- fprintf(out, "%s is clean\n", fn);
- }
- }
- }
-
- char dmesg[131073];
- int len = klogctl(KLOG_READ_ALL, dmesg, sizeof(dmesg) - 1);
- if (len < 0) {
- fprintf(out, "Can't read kernel log: %s\n", strerror(errno));
- } else { // To conserve space, only write lines with certain keywords
- fprintf(out, "--- Kernel log ---\n");
- dmesg[len] = '\0';
- char *saveptr, *line;
- int in_yaffs = 0;
- for (line = strtok_r(dmesg, "\n", &saveptr); line != NULL;
- line = strtok_r(NULL, "\n", &saveptr)) {
- if (strstr(line, "yaffs: dev is")) in_yaffs = 1;
-
- if (in_yaffs ||
- strstr(line, "yaffs") ||
- strstr(line, "mtd") ||
- strstr(line, "msm_nand")) {
- fprintf(out, "%s\n", line);
- }
-
- if (strstr(line, "yaffs_read_super: isCheckpointed")) in_yaffs = 0;
- }
- }
-
- return 0;
-}
diff --git a/tools/ota/convert-to-bmp.py b/tools/ota/convert-to-bmp.py
deleted file mode 100644
index 446c09d..0000000
--- a/tools/ota/convert-to-bmp.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/python2.4
-
-"""A simple script to convert asset images to BMP files, that supports
-RGBA image."""
-
-import struct
-import Image
-import sys
-
-infile = sys.argv[1]
-outfile = sys.argv[2]
-
-if not outfile.endswith(".bmp"):
- print >> sys.stderr, "Warning: I'm expecting to write BMP files."
-
-im = Image.open(infile)
-if im.mode == 'RGB':
- im.save(outfile)
-elif im.mode == 'RGBA':
- # Python Imaging Library doesn't write RGBA BMP files, so we roll
- # our own.
-
- BMP_HEADER_FMT = ("<" # little-endian
- "H" # signature
- "L" # file size
- "HH" # reserved (set to 0)
- "L" # offset to start of bitmap data)
- )
-
- BITMAPINFO_HEADER_FMT= ("<" # little-endian
- "L" # size of this struct
- "L" # width
- "L" # height
- "H" # planes (set to 1)
- "H" # bit count
- "L" # compression (set to 0 for minui)
- "L" # size of image data (0 if uncompressed)
- "L" # x pixels per meter (1)
- "L" # y pixels per meter (1)
- "L" # colors used (0)
- "L" # important colors (0)
- )
-
- fileheadersize = struct.calcsize(BMP_HEADER_FMT)
- infoheadersize = struct.calcsize(BITMAPINFO_HEADER_FMT)
-
- header = struct.pack(BMP_HEADER_FMT,
- 0x4d42, # "BM" in little-endian
- (fileheadersize + infoheadersize +
- im.size[0] * im.size[1] * 4),
- 0, 0,
- fileheadersize + infoheadersize)
-
- info = struct.pack(BITMAPINFO_HEADER_FMT,
- infoheadersize,
- im.size[0],
- im.size[1],
- 1,
- 32,
- 0,
- 0,
- 1,
- 1,
- 0,
- 0)
-
- f = open(outfile, "wb")
- f.write(header)
- f.write(info)
- data = im.tostring()
- for j in range(im.size[1]-1, -1, -1): # rows bottom-to-top
- for i in range(j*im.size[0]*4, (j+1)*im.size[0]*4, 4):
- f.write(data[i+2]) # B
- f.write(data[i+1]) # G
- f.write(data[i+0]) # R
- f.write(data[i+3]) # A
- f.close()
-else:
- print >> sys.stderr, "Don't know how to handle image mode '%s'." % (im.mode,)
diff --git a/tools/ota/make-update-script.c b/tools/ota/make-update-script.c
deleted file mode 100644
index 225dc52..0000000
--- a/tools/ota/make-update-script.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "private/android_filesystem_config.h"
-
-#include <dirent.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-/*
- * Recursively walk the directory tree at <sysdir>/<subdir>, writing
- * script commands to set permissions and create symlinks.
- * Assume the contents already have the specified default permissions,
- * so only output commands if they need to be changed from the defaults.
- *
- * Note that permissions are set by fs_config(), which uses a lookup table of
- * Android permissions. They are not drawn from the build host filesystem.
- */
-static void walk_files(
- const char *sysdir, const char *subdir,
- unsigned default_uid, unsigned default_gid,
- unsigned default_dir_mode, unsigned default_file_mode) {
- const char *sep = strcmp(subdir, "") ? "/" : "";
-
- char fn[PATH_MAX];
- unsigned dir_uid = 0, dir_gid = 0, dir_mode = 0;
- snprintf(fn, PATH_MAX, "system%s%s", sep, subdir);
- fs_config(fn, 1, &dir_uid, &dir_gid, &dir_mode);
-
- snprintf(fn, PATH_MAX, "%s%s%s", sysdir, sep, subdir);
- DIR *dir = opendir(fn);
- if (dir == NULL) {
- perror(fn);
- exit(1);
- }
-
- /*
- * We can use "set_perm" and "set_perm_recursive" to set file permissions
- * (owner, group, and file mode) for individual files and entire subtrees.
- * We want to use set_perm_recursive efficiently to avoid setting the
- * permissions of every single file in the system image individually.
- *
- * What we do is recursively set our entire subtree to the permissions
- * used by the first file we encounter, and then use "set_perm" to adjust
- * the permissions of subsequent files which don't match the first one.
- * This is bad if the first file is an outlier, but it generally works.
- * Subdirectories can do the same thing recursively if they're different.
- */
-
- int is_first = 1;
- const struct dirent *e;
- while ((e = readdir(dir))) {
- // Skip over "." and ".." entries
- if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) continue;
-
- if (e->d_type == DT_LNK) { // Symlink
-
- // Symlinks don't really have permissions, so this is orthogonal.
- snprintf(fn, PATH_MAX, "%s/%s%s%s", sysdir, subdir, sep, e->d_name);
- int len = readlink(fn, fn, PATH_MAX - 1);
- if (len <= 0) {
- perror(fn);
- exit(1);
- }
- fn[len] = '\0';
- printf("symlink %s SYSTEM:%s%s%s\n", fn, subdir, sep, e->d_name);
-
- } else if (e->d_type == DT_DIR) { // Subdirectory
-
- // Use the parent directory as the model for default permissions.
- // We haven't seen a file, so just make up some file defaults.
- if (is_first && (
- dir_mode != default_dir_mode ||
- dir_uid != default_uid || dir_gid != default_gid)) {
- default_uid = dir_uid;
- default_gid = dir_gid;
- default_dir_mode = dir_mode;
- default_file_mode = dir_mode & default_file_mode & 0666;
- printf("set_perm_recursive %d %d 0%o 0%o SYSTEM:%s\n",
- default_uid, default_gid,
- default_dir_mode, default_file_mode,
- subdir);
- }
-
- is_first = 0;
-
- // Recursively handle the subdirectory.
- // Note, the recursive call handles the directory's own permissions.
- snprintf(fn, PATH_MAX, "%s%s%s", subdir, sep, e->d_name);
- walk_files(sysdir, fn,
- default_uid, default_gid,
- default_dir_mode, default_file_mode);
-
- } else { // Ordinary file
-
- // Get the file's desired permissions.
- unsigned file_uid = 0, file_gid = 0, file_mode = 0;
- snprintf(fn, PATH_MAX, "system/%s%s%s", subdir, sep, e->d_name);
- fs_config(fn, 0, &file_uid, &file_gid, &file_mode);
-
- // If this is the first file, its mode gets to become the default.
- if (is_first && (
- dir_mode != default_dir_mode ||
- file_mode != default_file_mode ||
- dir_uid != default_uid || file_uid != default_uid ||
- dir_gid != default_gid || file_gid != default_gid)) {
- default_uid = dir_uid;
- default_gid = dir_gid;
- default_dir_mode = dir_mode;
- default_file_mode = file_mode;
- printf("set_perm_recursive %d %d 0%o 0%o SYSTEM:%s\n",
- default_uid, default_gid,
- default_dir_mode, default_file_mode,
- subdir);
- }
-
- is_first = 0;
-
- // Otherwise, override this file if it doesn't match the defaults.
- if (file_mode != default_file_mode ||
- file_uid != default_uid || file_gid != default_gid) {
- printf("set_perm %d %d 0%o SYSTEM:%s%s%s\n",
- file_uid, file_gid, file_mode,
- subdir, sep, e->d_name);
- }
-
- }
- }
-
- // Set the directory's permissions directly, if they never got set.
- if (dir_mode != default_dir_mode ||
- dir_uid != default_uid || dir_gid != default_gid) {
- printf("set_perm %d %d 0%o SYSTEM:%s\n",
- dir_uid, dir_gid, dir_mode, subdir);
- }
-
- closedir(dir);
-}
-
-/*
- * Generate the update script (in "Amend", see commands/recovery/commands.c)
- * for the complete-reinstall OTA update packages the build system makes.
- *
- * The generated script makes a variety of sanity checks about the device,
- * erases and reinstalls system files, and sets file permissions appropriately.
- */
-int main(int argc, char *argv[]) {
- if (argc != 3) {
- fprintf(stderr, "usage: %s systemdir android-info.txt >update-script\n",
- argv[0]);
- return 2;
- }
-
- // ensure basic recovery script language compatibility
- printf("assert compatible_with(\"0.2\") == \"true\"\n");
-
- // if known, make sure the device name is correct
- const char *device = getenv("TARGET_DEVICE");
- if (device != NULL) {
- printf("assert getprop(\"ro.product.device\") == \"%s\" || "
- "getprop(\"ro.build.product\") == \"%s\"\n", device, device);
- }
-
- // scan android-info.txt to enforce compatibility with the target system
- FILE *fp = fopen(argv[2], "r");
- if (fp == NULL) {
- perror(argv[2]);
- return 1;
- }
-
- // The lines we're looking for look like:
- // version-bootloader=x.yy.zzzz
- // or:
- // require version-bootloader=x.yy.zzzz
- char line[256];
- while (fgets(line, sizeof(line), fp)) {
- const char *name = strtok(line, "="), *value = strtok(NULL, "\n");
- if (value != NULL &&
- (!strcmp(name, "version-bootloader") ||
- !strcmp(name, "require version-bootloader"))) {
- printf("assert getprop(\"ro.bootloader\") == \"%s\"\n", value);
- }
- // We also used to check version-baseband, but we update radio.img
- // ourselves, so there's no need.
- }
-
- // erase the boot sector first, so if the update gets interrupted,
- // the system will reboot into the recovery partition and start over.
- printf("format BOOT:\n");
-
- // write the radio image (actually just loads it into RAM for now)
- printf("show_progress 0.1 0\n");
- printf("write_radio_image PACKAGE:radio.img\n");
-
- // erase and reinstall the system image
- printf("show_progress 0.5 0\n");
- printf("format SYSTEM:\n");
- printf("copy_dir PACKAGE:system SYSTEM:\n");
-
- // walk the files in the system image, set their permissions, etc.
- // use -1 for default values to force permissions to be set explicitly.
- walk_files(argv[1], "", -1, -1, -1, -1);
-
- // as the last step, write the boot sector.
- printf("show_progress 0.2 0\n");
- printf("write_raw_image PACKAGE:boot.img BOOT:\n");
-
- // after the end of the script, the radio will be written to cache
- // leave some space in the progress bar for this operation
- printf("show_progress 0.2 10\n");
- return 0;
-}
diff --git a/tools/ota/otatool b/tools/ota/otatool
deleted file mode 100755
index 4b02629..0000000
--- a/tools/ota/otatool
+++ /dev/null
@@ -1,225 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-PROGNAME=`basename "$0"`
-
-INSTALL_SCRIPT_NAME=META-INF/com/android/update-script
-
-function cleantmp
-{
- if [ ! -z "$TMPDIR" ]
- then
- rm -rf "$TMPDIR"
- TMPDIR=
- fi
-}
-
-function println
-{
- if [ $# -gt 0 ]
- then
- echo "$PROGNAME: $@"
- fi
-}
-
-function fail
-{
- println "$@"
- cleantmp
- exit 1
-}
-
-function usage
-{
- println "$@"
- echo "Usage: $PROGNAME <command> [command-options] <ota-file>"
- echo " Where <command> is one of:"
- echo " --dump"
- echo " Dump a description of the ota file"
- echo " --dump-script"
- echo " Dumps the install script to standard out"
- echo " --append-script <file> -o|--output <outfile>"
- echo " Append the contents of <file> to the install script"
- echo " --replace-script <file> -o|--output <outfile>"
- echo " Replace the install script with the contents of <file>"
- fail
-}
-
-if [ $# -lt 2 ]
-then
- usage
-fi
-CMD="$1"
-shift
-if [ "$CMD" = --dump ]
-then
- CMD_DUMP=1
- UNPACK_FILE=1
-elif [ "$CMD" = --dump-script ]
-then
- CMD_DUMP_SCRIPT=1
-elif [ "$CMD" = --append-script ]
-then
- CMD_APPEND_SCRIPT=1
- SCRIPT_FILE=$1
- shift
- NEEDS_SCRIPT_FILE=1
- NEEDS_OUTPUT=1
-elif [ "$CMD" = --replace-script ]
-then
- CMD_REPLACE_SCRIPT=1
- SCRIPT_FILE=$1
- shift
- NEEDS_SCRIPT_FILE=1
- NEEDS_OUTPUT=1
-else
- usage "Unknown command $CMD"
-fi
-
-if [ ! -z "$NEED_SCRIPT_FILE" ]
-then
- if [ -z "$SCRIPT_FILE" -o ! -f "$SCRIPT_FILE" ]
- then
- usage "$CMD requires a valid script file"
- fi
-fi
-
-if [ ! -z "$NEEDS_OUTPUT" ]
-then
- if [ "x$1" != "x-o" -a "x$1" != "x--output" ]
- then
- usage "$CMD requires \"-o <file>\" or \"--output <file>\""
- fi
- shift
-
- OUTFILE="$1"
- shift
- if [ -z "$OUTFILE" ]
- then
- usage "$CMD requires \"-o <file>\" or \"--output <file>\""
- fi
- if [ -d "$OUTFILE" ]
- then
- fail "Output file \"$OUTFILE\" is a directory"
- fi
-fi
-
-FILE="$1"
-if [ ! -f "$FILE" ]
-then
- fail "$FILE doesn't exist or isn't a file"
-fi
-if [ ! -z "$OUTFILE" -a "$FILE" -ef "$OUTFILE" ]
-then
- fail "Refusing to use the input file as the output file"
-fi
-
-if [ $CMD_DUMP_SCRIPT ]
-then
- unzip -p "$FILE" "$INSTALL_SCRIPT_NAME"
- exit 0
-fi
-
-# Create a temporary directory for scratch files.
-#
-TMPDIR=`mktemp -d /tmp/$PROGNAME.XXXXXX`
-if [ $? -ne 0 ]
-then
- TMPDIR=
- fail "Can't create temporary directory"
-fi
-
-
-if [ $UNPACK_FILE ]
-then
- ROOTDIR="$TMPDIR/root"
- mkdir -p "$ROOTDIR"
-
- println "Unpacking `basename $FILE`..."
-
- unzip -q -d "$ROOTDIR" "$FILE"
- if [ $? -ne 0 ]
- then
- fail "Couldn't unpack $FILE"
- fi
-fi
-
-
-if [ $CMD_DUMP ]
-then
- function dumpfile
- {
- echo "BEGIN `basename $1`"
- cat "$1" | sed -e 's/^/ /'
- echo "END `basename $1`"
- }
-
- echo Contents of root:
- ls -1 "$ROOTDIR" | sed -e 's/^/ /'
- echo
- echo Contents of META-INF:
- (cd "$ROOTDIR" && find META-INF -type f) | sed -e 's/^/ /'
-
- echo
- dumpfile "$ROOTDIR/META-INF/MANIFEST.MF"
- echo
- dumpfile "$ROOTDIR/$INSTALL_SCRIPT_NAME"
- echo
- dumpfile "$ROOTDIR/android-product.txt"
- echo
- dumpfile "$ROOTDIR/system/build.prop"
-fi
-
-if [ $CMD_APPEND_SCRIPT ]
-then
- TMPSCRIPT="$TMPDIR/script"
- NEWSCRIPT="$TMPDIR/$INSTALL_SCRIPT_NAME"
- unzip -p "$FILE" "$INSTALL_SCRIPT_NAME" > "$TMPSCRIPT"
- if [ $? -ne 0 ]
- then
- fail "Couldn't extract $INSTALL_SCRIPT_NAME from $FILE"
- fi
- mkdir -p `dirname "$NEWSCRIPT"`
- cat "$TMPSCRIPT" "$SCRIPT_FILE" > "$NEWSCRIPT"
-
- OVERWRITE_SCRIPT=1
-fi
-
-if [ $CMD_REPLACE_SCRIPT ]
-then
- NEWSCRIPT="$TMPDIR/$INSTALL_SCRIPT_NAME"
- mkdir -p `dirname "$NEWSCRIPT"`
- cp "$SCRIPT_FILE" "$NEWSCRIPT"
-
- OVERWRITE_SCRIPT=1
-fi
-
-if [ $OVERWRITE_SCRIPT ]
-then
- cp "$FILE" "$TMPDIR/outfile.zip"
- (cd "$TMPDIR" && zip -qu outfile.zip "$INSTALL_SCRIPT_NAME")
- if [ $? -ne 0 ]
- then
- fail "Couldn't add new $INSTALL_SCRIPT_NAME to output file"
- fi
-
- rm -f "$OUTFILE"
- mkdir -p `dirname "$OUTFILE"`
- mv "$TMPDIR/outfile.zip" "$OUTFILE"
-fi
-
-cleantmp
diff --git a/ui.c b/ui.c
deleted file mode 100644
index 5d06561..0000000
--- a/ui.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <linux/input.h>
-#include <pthread.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/reboot.h>
-#include <sys/time.h>
-#include <time.h>
-#include <unistd.h>
-
-#include "common.h"
-#include "minui/minui.h"
-
-#define MAX_COLS 64
-#define MAX_ROWS 32
-
-#define CHAR_WIDTH 10
-#define CHAR_HEIGHT 18
-
-#define PROGRESSBAR_INDETERMINATE_STATES 6
-#define PROGRESSBAR_INDETERMINATE_FPS 15
-
-enum { LEFT_SIDE, CENTER_TILE, RIGHT_SIDE, NUM_SIDES };
-
-static pthread_mutex_t gUpdateMutex = PTHREAD_MUTEX_INITIALIZER;
-static gr_surface gBackgroundIcon[NUM_BACKGROUND_ICONS];
-static gr_surface gProgressBarIndeterminate[PROGRESSBAR_INDETERMINATE_STATES];
-static gr_surface gProgressBarEmpty[NUM_SIDES];
-static gr_surface gProgressBarFill[NUM_SIDES];
-
-static const struct { gr_surface* surface; const char *name; } BITMAPS[] = {
- { &gBackgroundIcon[BACKGROUND_ICON_UNPACKING], "icon_unpacking" },
- { &gBackgroundIcon[BACKGROUND_ICON_INSTALLING], "icon_installing" },
- { &gBackgroundIcon[BACKGROUND_ICON_ERROR], "icon_error" },
- { &gBackgroundIcon[BACKGROUND_ICON_FIRMWARE_INSTALLING],
- "icon_firmware_install" },
- { &gBackgroundIcon[BACKGROUND_ICON_FIRMWARE_ERROR],
- "icon_firmware_error" },
- { &gProgressBarIndeterminate[0], "indeterminate1" },
- { &gProgressBarIndeterminate[1], "indeterminate2" },
- { &gProgressBarIndeterminate[2], "indeterminate3" },
- { &gProgressBarIndeterminate[3], "indeterminate4" },
- { &gProgressBarIndeterminate[4], "indeterminate5" },
- { &gProgressBarIndeterminate[5], "indeterminate6" },
- { &gProgressBarEmpty[LEFT_SIDE], "progress_bar_empty_left_round" },
- { &gProgressBarEmpty[CENTER_TILE], "progress_bar_empty" },
- { &gProgressBarEmpty[RIGHT_SIDE], "progress_bar_empty_right_round" },
- { &gProgressBarFill[LEFT_SIDE], "progress_bar_left_round" },
- { &gProgressBarFill[CENTER_TILE], "progress_bar_fill" },
- { &gProgressBarFill[RIGHT_SIDE], "progress_bar_right_round" },
- { NULL, NULL },
-};
-
-static gr_surface gCurrentIcon = NULL;
-
-static enum ProgressBarType {
- PROGRESSBAR_TYPE_NONE,
- PROGRESSBAR_TYPE_INDETERMINATE,
- PROGRESSBAR_TYPE_NORMAL,
-} gProgressBarType = PROGRESSBAR_TYPE_NONE;
-
-// Progress bar scope of current operation
-static float gProgressScopeStart = 0, gProgressScopeSize = 0, gProgress = 0;
-static time_t gProgressScopeTime, gProgressScopeDuration;
-
-// Set to 1 when both graphics pages are the same (except for the progress bar)
-static int gPagesIdentical = 0;
-
-// Log text overlay, displayed when a magic key is pressed
-static char text[MAX_ROWS][MAX_COLS];
-static int text_cols = 0, text_rows = 0;
-static int text_col = 0, text_row = 0, text_top = 0;
-static int show_text = 0;
-
-static char menu[MAX_ROWS][MAX_COLS];
-static int show_menu = 0;
-static int menu_top = 0, menu_items = 0, menu_sel = 0;
-
-// Key event input queue
-static pthread_mutex_t key_queue_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t key_queue_cond = PTHREAD_COND_INITIALIZER;
-static int key_queue[256], key_queue_len = 0;
-static volatile char key_pressed[KEY_MAX + 1];
-
-// Clear the screen and draw the currently selected background icon (if any).
-// Should only be called with gUpdateMutex locked.
-static void draw_background_locked(gr_surface icon)
-{
- gPagesIdentical = 0;
- gr_color(0, 0, 0, 255);
- gr_fill(0, 0, gr_fb_width(), gr_fb_height());
-
- if (icon) {
- int iconWidth = gr_get_width(icon);
- int iconHeight = gr_get_height(icon);
- int iconX = (gr_fb_width() - iconWidth) / 2;
- int iconY = (gr_fb_height() - iconHeight) / 2;
- gr_blit(icon, 0, 0, iconWidth, iconHeight, iconX, iconY);
- }
-}
-
-// Draw the progress bar (if any) on the screen. Does not flip pages.
-// Should only be called with gUpdateMutex locked.
-static void draw_progress_locked()
-{
- if (gProgressBarType == PROGRESSBAR_TYPE_NONE) return;
-
- int iconHeight = gr_get_height(gBackgroundIcon[BACKGROUND_ICON_INSTALLING]);
- int width = gr_get_width(gProgressBarIndeterminate[0]);
- int height = gr_get_height(gProgressBarIndeterminate[0]);
-
- int dx = (gr_fb_width() - width)/2;
- int dy = (3*gr_fb_height() + iconHeight - 2*height)/4;
-
- // Erase behind the progress bar (in case this was a progress-only update)
- gr_color(0, 0, 0, 255);
- gr_fill(dx, dy, width, height);
-
- if (gProgressBarType == PROGRESSBAR_TYPE_NORMAL) {
- float progress = gProgressScopeStart + gProgress * gProgressScopeSize;
- int pos = (int) (progress * width);
-
- gr_surface s = (pos ? gProgressBarFill : gProgressBarEmpty)[LEFT_SIDE];
- gr_blit(s, 0, 0, gr_get_width(s), gr_get_height(s), dx, dy);
-
- int x = gr_get_width(s);
- while (x + (int) gr_get_width(gProgressBarEmpty[RIGHT_SIDE]) < width) {
- s = (pos > x ? gProgressBarFill : gProgressBarEmpty)[CENTER_TILE];
- gr_blit(s, 0, 0, gr_get_width(s), gr_get_height(s), dx + x, dy);
- x += gr_get_width(s);
- }
-
- s = (pos > x ? gProgressBarFill : gProgressBarEmpty)[RIGHT_SIDE];
- gr_blit(s, 0, 0, gr_get_width(s), gr_get_height(s), dx + x, dy);
- }
-
- if (gProgressBarType == PROGRESSBAR_TYPE_INDETERMINATE) {
- static int frame = 0;
- gr_blit(gProgressBarIndeterminate[frame], 0, 0, width, height, dx, dy);
- frame = (frame + 1) % PROGRESSBAR_INDETERMINATE_STATES;
- }
-}
-
-static void draw_text_line(int row, const char* t) {
- if (t[0] != '\0') {
- gr_text(0, (row+1)*CHAR_HEIGHT-1, t);
- }
-}
-
-// Redraw everything on the screen. Does not flip pages.
-// Should only be called with gUpdateMutex locked.
-static void draw_screen_locked(void)
-{
- draw_background_locked(gCurrentIcon);
- draw_progress_locked();
-
- if (show_text) {
- gr_color(0, 0, 0, 160);
- gr_fill(0, 0, gr_fb_width(), gr_fb_height());
-
- int i = 0;
- if (show_menu) {
- gr_color(64, 96, 255, 255);
- gr_fill(0, (menu_top+menu_sel) * CHAR_HEIGHT,
- gr_fb_width(), (menu_top+menu_sel+1)*CHAR_HEIGHT+1);
-
- for (; i < menu_top + menu_items; ++i) {
- if (i == menu_top + menu_sel) {
- gr_color(255, 255, 255, 255);
- draw_text_line(i, menu[i]);
- gr_color(64, 96, 255, 255);
- } else {
- draw_text_line(i, menu[i]);
- }
- }
- gr_fill(0, i*CHAR_HEIGHT+CHAR_HEIGHT/2-1,
- gr_fb_width(), i*CHAR_HEIGHT+CHAR_HEIGHT/2+1);
- ++i;
- }
-
- gr_color(255, 255, 0, 255);
-
- for (; i < text_rows; ++i) {
- draw_text_line(i, text[(i+text_top) % text_rows]);
- }
- }
-}
-
-// Redraw everything on the screen and flip the screen (make it visible).
-// Should only be called with gUpdateMutex locked.
-static void update_screen_locked(void)
-{
- draw_screen_locked();
- gr_flip();
-}
-
-// Updates only the progress bar, if possible, otherwise redraws the screen.
-// Should only be called with gUpdateMutex locked.
-static void update_progress_locked(void)
-{
- if (show_text || !gPagesIdentical) {
- draw_screen_locked(); // Must redraw the whole screen
- gPagesIdentical = 1;
- } else {
- draw_progress_locked(); // Draw only the progress bar
- }
- gr_flip();
-}
-
-// Keeps the progress bar updated, even when the process is otherwise busy.
-static void *progress_thread(void *cookie)
-{
- for (;;) {
- usleep(1000000 / PROGRESSBAR_INDETERMINATE_FPS);
- pthread_mutex_lock(&gUpdateMutex);
-
- // update the progress bar animation, if active
- // skip this if we have a text overlay (too expensive to update)
- if (gProgressBarType == PROGRESSBAR_TYPE_INDETERMINATE && !show_text) {
- update_progress_locked();
- }
-
- // move the progress bar forward on timed intervals, if configured
- int duration = gProgressScopeDuration;
- if (gProgressBarType == PROGRESSBAR_TYPE_NORMAL && duration > 0) {
- int elapsed = time(NULL) - gProgressScopeTime;
- float progress = 1.0 * elapsed / duration;
- if (progress > 1.0) progress = 1.0;
- if (progress > gProgress) {
- gProgress = progress;
- update_progress_locked();
- }
- }
-
- pthread_mutex_unlock(&gUpdateMutex);
- }
- return NULL;
-}
-
-// Reads input events, handles special hot keys, and adds to the key queue.
-static void *input_thread(void *cookie)
-{
- int rel_sum = 0;
- int fake_key = 0;
- for (;;) {
- // wait for the next key event
- struct input_event ev;
- do {
- ev_get(&ev, 0);
-
- if (ev.type == EV_SYN) {
- continue;
- } else if (ev.type == EV_REL) {
- if (ev.code == REL_Y) {
- // accumulate the up or down motion reported by
- // the trackball. When it exceeds a threshold
- // (positive or negative), fake an up/down
- // key event.
- rel_sum += ev.value;
- if (rel_sum > 3) {
- fake_key = 1;
- ev.type = EV_KEY;
- ev.code = KEY_DOWN;
- ev.value = 1;
- rel_sum = 0;
- } else if (rel_sum < -3) {
- fake_key = 1;
- ev.type = EV_KEY;
- ev.code = KEY_UP;
- ev.value = 1;
- rel_sum = 0;
- }
- }
- } else {
- rel_sum = 0;
- }
- } while (ev.type != EV_KEY || ev.code > KEY_MAX);
-
- pthread_mutex_lock(&key_queue_mutex);
- if (!fake_key) {
- // our "fake" keys only report a key-down event (no
- // key-up), so don't record them in the key_pressed
- // table.
- key_pressed[ev.code] = ev.value;
- }
- fake_key = 0;
- const int queue_max = sizeof(key_queue) / sizeof(key_queue[0]);
- if (ev.value > 0 && key_queue_len < queue_max) {
- key_queue[key_queue_len++] = ev.code;
- pthread_cond_signal(&key_queue_cond);
- }
- pthread_mutex_unlock(&key_queue_mutex);
-
- // Alt+L or Home+End: toggle log display
- int alt = key_pressed[KEY_LEFTALT] || key_pressed[KEY_RIGHTALT];
- if ((alt && ev.code == KEY_L && ev.value > 0) ||
- (key_pressed[KEY_HOME] && ev.code == KEY_END && ev.value > 0)) {
- pthread_mutex_lock(&gUpdateMutex);
- show_text = !show_text;
- update_screen_locked();
- pthread_mutex_unlock(&gUpdateMutex);
- }
-
- // Green+Menu+Red: reboot immediately
- if (ev.code == KEY_DREAM_RED &&
- key_pressed[KEY_DREAM_MENU] &&
- key_pressed[KEY_DREAM_GREEN]) {
- reboot(RB_AUTOBOOT);
- }
- }
- return NULL;
-}
-
-void ui_init(void)
-{
- gr_init();
- ev_init();
-
- text_col = text_row = 0;
- text_rows = gr_fb_height() / CHAR_HEIGHT;
- if (text_rows > MAX_ROWS) text_rows = MAX_ROWS;
- text_top = 1;
-
- text_cols = gr_fb_width() / CHAR_WIDTH;
- if (text_cols > MAX_COLS - 1) text_cols = MAX_COLS - 1;
-
- int i;
- for (i = 0; BITMAPS[i].name != NULL; ++i) {
- int result = res_create_surface(BITMAPS[i].name, BITMAPS[i].surface);
- if (result < 0) {
- LOGE("Missing bitmap %s\n(Code %d)\n", BITMAPS[i].name, result);
- *BITMAPS[i].surface = NULL;
- }
- }
-
- pthread_t t;
- pthread_create(&t, NULL, progress_thread, NULL);
- pthread_create(&t, NULL, input_thread, NULL);
-}
-
-char *ui_copy_image(int icon, int *width, int *height, int *bpp) {
- pthread_mutex_lock(&gUpdateMutex);
- draw_background_locked(gBackgroundIcon[icon]);
- *width = gr_fb_width();
- *height = gr_fb_height();
- *bpp = sizeof(gr_pixel) * 8;
- int size = *width * *height * sizeof(gr_pixel);
- char *ret = malloc(size);
- if (ret == NULL) {
- LOGE("Can't allocate %d bytes for image\n", size);
- } else {
- memcpy(ret, gr_fb_data(), size);
- }
- pthread_mutex_unlock(&gUpdateMutex);
- return ret;
-}
-
-void ui_set_background(int icon)
-{
- pthread_mutex_lock(&gUpdateMutex);
- gCurrentIcon = gBackgroundIcon[icon];
- update_screen_locked();
- pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_show_indeterminate_progress()
-{
- pthread_mutex_lock(&gUpdateMutex);
- if (gProgressBarType != PROGRESSBAR_TYPE_INDETERMINATE) {
- gProgressBarType = PROGRESSBAR_TYPE_INDETERMINATE;
- update_progress_locked();
- }
- pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_show_progress(float portion, int seconds)
-{
- pthread_mutex_lock(&gUpdateMutex);
- gProgressBarType = PROGRESSBAR_TYPE_NORMAL;
- gProgressScopeStart += gProgressScopeSize;
- gProgressScopeSize = portion;
- gProgressScopeTime = time(NULL);
- gProgressScopeDuration = seconds;
- gProgress = 0;
- update_progress_locked();
- pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_set_progress(float fraction)
-{
- pthread_mutex_lock(&gUpdateMutex);
- if (fraction < 0.0) fraction = 0.0;
- if (fraction > 1.0) fraction = 1.0;
- if (gProgressBarType == PROGRESSBAR_TYPE_NORMAL && fraction > gProgress) {
- // Skip updates that aren't visibly different.
- int width = gr_get_width(gProgressBarIndeterminate[0]);
- float scale = width * gProgressScopeSize;
- if ((int) (gProgress * scale) != (int) (fraction * scale)) {
- gProgress = fraction;
- update_progress_locked();
- }
- }
- pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_reset_progress()
-{
- pthread_mutex_lock(&gUpdateMutex);
- gProgressBarType = PROGRESSBAR_TYPE_NONE;
- gProgressScopeStart = gProgressScopeSize = 0;
- gProgressScopeTime = gProgressScopeDuration = 0;
- gProgress = 0;
- update_screen_locked();
- pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_print(const char *fmt, ...)
-{
- char buf[256];
- va_list ap;
- va_start(ap, fmt);
- vsnprintf(buf, 256, fmt, ap);
- va_end(ap);
-
- fputs(buf, stderr);
-
- // This can get called before ui_init(), so be careful.
- pthread_mutex_lock(&gUpdateMutex);
- if (text_rows > 0 && text_cols > 0) {
- char *ptr;
- for (ptr = buf; *ptr != '\0'; ++ptr) {
- if (*ptr == '\n' || text_col >= text_cols) {
- text[text_row][text_col] = '\0';
- text_col = 0;
- text_row = (text_row + 1) % text_rows;
- if (text_row == text_top) text_top = (text_top + 1) % text_rows;
- }
- if (*ptr != '\n') text[text_row][text_col++] = *ptr;
- }
- text[text_row][text_col] = '\0';
- update_screen_locked();
- }
- pthread_mutex_unlock(&gUpdateMutex);
-}
-
-void ui_start_menu(char** headers, char** items) {
- int i;
- pthread_mutex_lock(&gUpdateMutex);
- if (text_rows > 0 && text_cols > 0) {
- for (i = 0; i < text_rows; ++i) {
- if (headers[i] == NULL) break;
- strncpy(menu[i], headers[i], text_cols-1);
- menu[i][text_cols-1] = '\0';
- }
- menu_top = i;
- for (; i < text_rows; ++i) {
- if (items[i-menu_top] == NULL) break;
- strncpy(menu[i], items[i-menu_top], text_cols-1);
- menu[i][text_cols-1] = '\0';
- }
- menu_items = i - menu_top;
- show_menu = 1;
- menu_sel = 0;
- update_screen_locked();
- }
- pthread_mutex_unlock(&gUpdateMutex);
-}
-
-int ui_menu_select(int sel) {
- int old_sel;
- pthread_mutex_lock(&gUpdateMutex);
- if (show_menu > 0) {
- old_sel = menu_sel;
- menu_sel = sel;
- if (menu_sel < 0) menu_sel = 0;
- if (menu_sel >= menu_items) menu_sel = menu_items-1;
- sel = menu_sel;
- if (menu_sel != old_sel) update_screen_locked();
- }
- pthread_mutex_unlock(&gUpdateMutex);
- return sel;
-}
-
-void ui_end_menu() {
- int i;
- pthread_mutex_lock(&gUpdateMutex);
- if (show_menu > 0 && text_rows > 0 && text_cols > 0) {
- show_menu = 0;
- update_screen_locked();
- }
- pthread_mutex_unlock(&gUpdateMutex);
-}
-
-int ui_text_visible()
-{
- pthread_mutex_lock(&gUpdateMutex);
- int visible = show_text;
- pthread_mutex_unlock(&gUpdateMutex);
- return visible;
-}
-
-int ui_wait_key()
-{
- pthread_mutex_lock(&key_queue_mutex);
- while (key_queue_len == 0) {
- pthread_cond_wait(&key_queue_cond, &key_queue_mutex);
- }
-
- int key = key_queue[0];
- memcpy(&key_queue[0], &key_queue[1], sizeof(int) * --key_queue_len);
- pthread_mutex_unlock(&key_queue_mutex);
- return key;
-}
-
-int ui_key_pressed(int key)
-{
- // This is a volatile static array, don't bother locking
- return key_pressed[key];
-}
-
-void ui_clear_key_queue() {
- pthread_mutex_lock(&key_queue_mutex);
- key_queue_len = 0;
- pthread_mutex_unlock(&key_queue_mutex);
-}
diff --git a/verifier.c b/verifier.c
deleted file mode 100644
index 1180ae8..0000000
--- a/verifier.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "common.h"
-#include "verifier.h"
-
-#include "minzip/Zip.h"
-#include "mincrypt/rsa.h"
-#include "mincrypt/sha.h"
-
-#include <netinet/in.h> /* required for resolv.h */
-#include <resolv.h> /* for base64 codec */
-#include <string.h>
-
-/* Return an allocated buffer with the contents of a zip file entry. */
-static char *slurpEntry(const ZipArchive *pArchive, const ZipEntry *pEntry) {
- if (!mzIsZipEntryIntact(pArchive, pEntry)) {
- UnterminatedString fn = mzGetZipEntryFileName(pEntry);
- LOGE("Invalid %.*s\n", fn.len, fn.str);
- return NULL;
- }
-
- int len = mzGetZipEntryUncompLen(pEntry);
- char *buf = malloc(len + 1);
- if (buf == NULL) {
- UnterminatedString fn = mzGetZipEntryFileName(pEntry);
- LOGE("Can't allocate %d bytes for %.*s\n", len, fn.len, fn.str);
- return NULL;
- }
-
- if (!mzReadZipEntry(pArchive, pEntry, buf, len)) {
- UnterminatedString fn = mzGetZipEntryFileName(pEntry);
- LOGE("Can't read %.*s\n", fn.len, fn.str);
- free(buf);
- return NULL;
- }
-
- buf[len] = '\0';
- return buf;
-}
-
-
-struct DigestContext {
- SHA_CTX digest;
- unsigned *doneBytes;
- unsigned totalBytes;
-};
-
-
-/* mzProcessZipEntryContents callback to update an SHA-1 hash context. */
-static bool updateHash(const unsigned char *data, int dataLen, void *cookie) {
- struct DigestContext *context = (struct DigestContext *) cookie;
- SHA_update(&context->digest, data, dataLen);
- if (context->doneBytes != NULL) {
- *context->doneBytes += dataLen;
- if (context->totalBytes > 0) {
- ui_set_progress(*context->doneBytes * 1.0 / context->totalBytes);
- }
- }
- return true;
-}
-
-
-/* Get the SHA-1 digest of a zip file entry. */
-static bool digestEntry(const ZipArchive *pArchive, const ZipEntry *pEntry,
- unsigned *doneBytes, unsigned totalBytes,
- uint8_t digest[SHA_DIGEST_SIZE]) {
- struct DigestContext context;
- SHA_init(&context.digest);
- context.doneBytes = doneBytes;
- context.totalBytes = totalBytes;
- if (!mzProcessZipEntryContents(pArchive, pEntry, updateHash, &context)) {
- UnterminatedString fn = mzGetZipEntryFileName(pEntry);
- LOGE("Can't digest %.*s\n", fn.len, fn.str);
- return false;
- }
-
- memcpy(digest, SHA_final(&context.digest), SHA_DIGEST_SIZE);
-
-#ifdef LOG_VERBOSE
- UnterminatedString fn = mzGetZipEntryFileName(pEntry);
- char base64[SHA_DIGEST_SIZE * 3];
- b64_ntop(digest, SHA_DIGEST_SIZE, base64, sizeof(base64));
- LOGV("sha1(%.*s) = %s\n", fn.len, fn.str, base64);
-#endif
-
- return true;
-}
-
-
-/* Find a /META-INF/xxx.SF signature file signed by a matching xxx.RSA file. */
-static const ZipEntry *verifySignature(const ZipArchive *pArchive,
- const RSAPublicKey *pKeys, unsigned int numKeys) {
- static const char prefix[] = "META-INF/";
- static const char rsa[] = ".RSA", sf[] = ".SF";
-
- unsigned int i, j;
- for (i = 0; i < mzZipEntryCount(pArchive); ++i) {
- const ZipEntry *rsaEntry = mzGetZipEntryAt(pArchive, i);
- UnterminatedString rsaName = mzGetZipEntryFileName(rsaEntry);
- int rsaLen = mzGetZipEntryUncompLen(rsaEntry);
- if (rsaLen >= RSANUMBYTES && rsaName.len > sizeof(prefix) &&
- !strncmp(rsaName.str, prefix, sizeof(prefix) - 1) &&
- !strncmp(rsaName.str + rsaName.len - sizeof(rsa) + 1,
- rsa, sizeof(rsa) - 1)) {
- char *sfName = malloc(rsaName.len - sizeof(rsa) + sizeof(sf) + 1);
- if (sfName == NULL) {
- LOGE("Can't allocate %d bytes for filename\n", rsaName.len);
- continue;
- }
-
- /* Replace .RSA with .SF */
- strncpy(sfName, rsaName.str, rsaName.len - sizeof(rsa) + 1);
- strcpy(sfName + rsaName.len - sizeof(rsa) + 1, sf);
- const ZipEntry *sfEntry = mzFindZipEntry(pArchive, sfName);
-
- if (sfEntry == NULL) {
- LOGW("Missing signature file %s\n", sfName);
- free(sfName);
- continue;
- }
-
- free(sfName);
-
- uint8_t sfDigest[SHA_DIGEST_SIZE];
- if (!digestEntry(pArchive, sfEntry, NULL, 0, sfDigest)) continue;
-
- char *rsaBuf = slurpEntry(pArchive, rsaEntry);
- if (rsaBuf == NULL) continue;
-
- /* Try to verify the signature with all the keys. */
- uint8_t *sig = (uint8_t *) rsaBuf + rsaLen - RSANUMBYTES;
- for (j = 0; j < numKeys; ++j) {
- if (RSA_verify(&pKeys[j], sig, RSANUMBYTES, sfDigest)) {
- free(rsaBuf);
- LOGI("Verified %.*s\n", rsaName.len, rsaName.str);
- return sfEntry;
- }
- }
-
- free(rsaBuf);
- LOGW("Can't verify %.*s\n", rsaName.len, rsaName.str);
- }
- }
-
- LOGE("No signature (%d files)\n", mzZipEntryCount(pArchive));
- return NULL;
-}
-
-
-/* Verify /META-INF/MANIFEST.MF against the digest in a signature file. */
-static const ZipEntry *verifyManifest(const ZipArchive *pArchive,
- const ZipEntry *sfEntry) {
- static const char prefix[] = "SHA1-Digest-Manifest: ", eol[] = "\r\n";
- uint8_t expected[SHA_DIGEST_SIZE + 3], actual[SHA_DIGEST_SIZE];
-
- char *sfBuf = slurpEntry(pArchive, sfEntry);
- if (sfBuf == NULL) return NULL;
-
- char *line, *save;
- for (line = strtok_r(sfBuf, eol, &save); line != NULL;
- line = strtok_r(NULL, eol, &save)) {
- if (!strncasecmp(prefix, line, sizeof(prefix) - 1)) {
- UnterminatedString fn = mzGetZipEntryFileName(sfEntry);
- const char *digest = line + sizeof(prefix) - 1;
- int n = b64_pton(digest, expected, sizeof(expected));
- if (n != SHA_DIGEST_SIZE) {
- LOGE("Invalid base64 in %.*s: %s (%d)\n",
- fn.len, fn.str, digest, n);
- line = NULL;
- }
- break;
- }
- }
-
- free(sfBuf);
-
- if (line == NULL) {
- LOGE("No digest manifest in signature file\n");
- return false;
- }
-
- const char *mfName = "META-INF/MANIFEST.MF";
- const ZipEntry *mfEntry = mzFindZipEntry(pArchive, mfName);
- if (mfEntry == NULL) {
- LOGE("No manifest file %s\n", mfName);
- return NULL;
- }
-
- if (!digestEntry(pArchive, mfEntry, NULL, 0, actual)) return NULL;
- if (memcmp(expected, actual, SHA_DIGEST_SIZE)) {
- UnterminatedString fn = mzGetZipEntryFileName(sfEntry);
- LOGE("Wrong digest for %s in %.*s\n", mfName, fn.len, fn.str);
- return NULL;
- }
-
- LOGI("Verified %s\n", mfName);
- return mfEntry;
-}
-
-
-/* Verify all the files in a Zip archive against the manifest. */
-static bool verifyArchive(const ZipArchive *pArchive, const ZipEntry *mfEntry) {
- static const char namePrefix[] = "Name: ";
- static const char contPrefix[] = " "; // Continuation of the filename
- static const char digestPrefix[] = "SHA1-Digest: ";
- static const char eol[] = "\r\n";
-
- char *mfBuf = slurpEntry(pArchive, mfEntry);
- if (mfBuf == NULL) return false;
-
- /* we're using calloc() here, so the initial state of the array is false */
- bool *unverified = (bool *) calloc(mzZipEntryCount(pArchive), sizeof(bool));
- if (unverified == NULL) {
- LOGE("Can't allocate valid flags\n");
- free(mfBuf);
- return false;
- }
-
- /* Mark all the files in the archive that need to be verified.
- * As we scan the manifest and check signatures, we'll unset these flags.
- * At the end, we'll make sure that all the flags are unset.
- */
-
- unsigned i, totalBytes = 0;
- for (i = 0; i < mzZipEntryCount(pArchive); ++i) {
- const ZipEntry *entry = mzGetZipEntryAt(pArchive, i);
- UnterminatedString fn = mzGetZipEntryFileName(entry);
- int len = mzGetZipEntryUncompLen(entry);
-
- // Don't validate: directories, the manifest, *.RSA, and *.SF.
-
- if (entry == mfEntry) {
- LOGV("Skipping manifest %.*s\n", fn.len, fn.str);
- } else if (fn.len > 0 && fn.str[fn.len-1] == '/' && len == 0) {
- LOGV("Skipping directory %.*s\n", fn.len, fn.str);
- } else if (!strncasecmp(fn.str, "META-INF/", 9) && (
- !strncasecmp(fn.str + fn.len - 4, ".RSA", 4) ||
- !strncasecmp(fn.str + fn.len - 3, ".SF", 3))) {
- LOGV("Skipping signature %.*s\n", fn.len, fn.str);
- } else {
- unverified[i] = true;
- totalBytes += len;
- }
- }
-
- unsigned doneBytes = 0;
- char *line, *save, *name = NULL;
- for (line = strtok_r(mfBuf, eol, &save); line != NULL;
- line = strtok_r(NULL, eol, &save)) {
- if (!strncasecmp(line, namePrefix, sizeof(namePrefix) - 1)) {
- // "Name:" introducing a new stanza
- if (name != NULL) {
- LOGE("No digest:\n %s\n", name);
- break;
- }
-
- name = strdup(line + sizeof(namePrefix) - 1);
- if (name == NULL) {
- LOGE("Can't copy filename in %s\n", line);
- break;
- }
- } else if (!strncasecmp(line, contPrefix, sizeof(contPrefix) - 1)) {
- // Continuing a long name (nothing else should be continued)
- const char *tail = line + sizeof(contPrefix) - 1;
- if (name == NULL) {
- LOGE("Unexpected continuation:\n %s\n", tail);
- }
-
- char *concat;
- if (asprintf(&concat, "%s%s", name, tail) < 0) {
- LOGE("Can't append continuation %s\n", tail);
- break;
- }
- free(name);
- name = concat;
- } else if (!strncasecmp(line, digestPrefix, sizeof(digestPrefix) - 1)) {
- // "Digest:" supplying a hash code for the current stanza
- const char *base64 = line + sizeof(digestPrefix) - 1;
- if (name == NULL) {
- LOGE("Unexpected digest:\n %s\n", base64);
- break;
- }
-
- const ZipEntry *entry = mzFindZipEntry(pArchive, name);
- if (entry == NULL) {
- LOGE("Missing file:\n %s\n", name);
- break;
- }
- if (!mzIsZipEntryIntact(pArchive, entry)) {
- LOGE("Corrupt file:\n %s\n", name);
- break;
- }
- if (!unverified[mzGetZipEntryIndex(pArchive, entry)]) {
- LOGE("Unexpected file:\n %s\n", name);
- break;
- }
-
- uint8_t expected[SHA_DIGEST_SIZE + 3], actual[SHA_DIGEST_SIZE];
- int n = b64_pton(base64, expected, sizeof(expected));
- if (n != SHA_DIGEST_SIZE) {
- LOGE("Invalid base64:\n %s\n %s\n", name, base64);
- break;
- }
-
- if (!digestEntry(pArchive, entry, &doneBytes, totalBytes, actual) ||
- memcmp(expected, actual, SHA_DIGEST_SIZE) != 0) {
- LOGE("Wrong digest:\n %s\n", name);
- break;
- }
-
- LOGI("Verified %s\n", name);
- unverified[mzGetZipEntryIndex(pArchive, entry)] = false;
- free(name);
- name = NULL;
- }
- }
-
- if (name != NULL) free(name);
- free(mfBuf);
-
- for (i = 0; i < mzZipEntryCount(pArchive) && !unverified[i]; ++i) ;
- free(unverified);
-
- // This means we didn't get to the end of the manifest successfully.
- if (line != NULL) return false;
-
- if (i < mzZipEntryCount(pArchive)) {
- const ZipEntry *entry = mzGetZipEntryAt(pArchive, i);
- UnterminatedString fn = mzGetZipEntryFileName(entry);
- LOGE("No digest for %.*s\n", fn.len, fn.str);
- return false;
- }
-
- return true;
-}
-
-
-bool verify_jar_signature(const ZipArchive *pArchive,
- const RSAPublicKey *pKeys, int numKeys) {
- const ZipEntry *sfEntry = verifySignature(pArchive, pKeys, numKeys);
- if (sfEntry == NULL) return false;
-
- const ZipEntry *mfEntry = verifyManifest(pArchive, sfEntry);
- if (mfEntry == NULL) return false;
-
- return verifyArchive(pArchive, mfEntry);
-}
diff --git a/verifier.h b/verifier.h
deleted file mode 100644
index d784dce..0000000
--- a/verifier.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _RECOVERY_VERIFIER_H
-#define _RECOVERY_VERIFIER_H
-
-#include "minzip/Zip.h"
-#include "mincrypt/rsa.h"
-
-/*
- * Check the digital signature (as applied by jarsigner) on a Zip archive.
- * Every file in the archive must be signed by one of the supplied RSA keys.
- */
-bool verify_jar_signature(const ZipArchive *pArchive,
- const RSAPublicKey *pKeys, int numKeys);
-
-#endif /* _RECOVERY_VERIFIER_H */