Commit f4c2077d authored by Vojtěch Boček's avatar Vojtěch Boček
Browse files

Merge pull request #21 from nkk71/android-6.0-mrom-squashedcommit01

Add MultiROM support to standard TWRP tree
parents b7e8b98c ae45c87e
......@@ -59,6 +59,15 @@ LOCAL_SRC_FILES += \
openrecoveryscript.cpp \
tarWrite.c
#MultiROM
ifeq ($(TARGET_RECOVERY_IS_MULTIROM), true)
LOCAL_SRC_FILES += \
multirom/multirom.cpp \
multirom/mrominstaller.cpp \
multirom/multiromedify.cpp \
multirom/multirom_Zip.c
endif
ifneq ($(TARGET_RECOVERY_REBOOT_SRC),)
LOCAL_SRC_FILES += $(TARGET_RECOVERY_REBOOT_SRC)
endif
......@@ -113,6 +122,16 @@ LOCAL_STATIC_LIBRARIES += libguitwrp
LOCAL_SHARED_LIBRARIES += libz libc libcutils libstdc++ libtar libblkid libminuitwrp libminadbd libmtdutils libminzip libaosprecovery
LOCAL_SHARED_LIBRARIES += libcrecovery
#MultiROM
ifeq ($(TARGET_RECOVERY_IS_MULTIROM), true)
LOCAL_STATIC_LIBRARIES += libcp_xattrs
# clone libbootimg to /system/extras/ from
# https://github.com/Tasssadar/libbootimg.git
LOCAL_STATIC_LIBRARIES += libbootimg
LOCAL_C_INCLUDES += system/extras/libbootimg/include
endif
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 23; echo $$?),0)
LOCAL_SHARED_LIBRARIES += libstlport
else
......@@ -339,6 +358,32 @@ else
LOCAL_CFLAGS += -DTW_DEFAULT_LANGUAGE=en
endif
#MultiROM
ifeq ($(TARGET_RECOVERY_IS_MULTIROM), true)
LOCAL_CFLAGS += -DTARGET_RECOVERY_IS_MULTIROM
LOCAL_CFLAGS += -DTARGET_DEVICE="\"$(TARGET_DEVICE)\""
#TODO
LOCAL_CFLAGS += -DTW_DEFAULT_ROTATION=0
ifneq ($(MR_RD_ADDR),)
LOCAL_CFLAGS += -DMR_RD_ADDR=$(MR_RD_ADDR)
endif
ifeq ($(MR_USE_MROM_FSTAB),true)
LOCAL_CFLAGS += -DMR_USE_MROM_FSTAB
endif
ifneq ($(MR_DEVICE_RECOVERY_HOOKS),)
ifeq ($(MR_DEVICE_RECOVERY_HOOKS_VER),)
$(info MR_DEVICE_RECOVERY_HOOKS is set but MR_DEVICE_RECOVERY_HOOKS_VER is not specified!)
else
LOCAL_CFLAGS += -DMR_DEVICE_RECOVERY_HOOKS=$(MR_DEVICE_RECOVERY_HOOKS_VER)
LOCAL_SRC_FILES += ../../$(MR_DEVICE_RECOVERY_HOOKS)
endif
endif
endif
LOCAL_ADDITIONAL_DEPENDENCIES := \
dump_image \
erase_image \
......@@ -355,6 +400,20 @@ LOCAL_ADDITIONAL_DEPENDENCIES := \
permissive.sh \
simg2img_twrp
#MultiROM
ifeq ($(TARGET_RECOVERY_IS_MULTIROM), true)
#LOCAL_C_INCLUDES += $(LOCAL_PATH)/multirom
#MultiROM additions
LOCAL_ADDITIONAL_DEPENDENCIES += \
zip \
gnutar \
lz4 \
ntfs-3g \
cp_xattrs \
ls_xattrs
endif
ifneq ($(TARGET_ARCH), arm64)
ifneq ($(TARGET_ARCH), x86_64)
LOCAL_LDFLAGS += -Wl,-dynamic-linker,/sbin/linker
......@@ -597,6 +656,12 @@ include $(commands_recovery_local_path)/injecttwrp/Android.mk \
$(commands_recovery_local_path)/simg2img/Android.mk \
$(commands_recovery_local_path)/libpixelflinger/Android.mk
#MultiROM
ifeq ($(TARGET_RECOVERY_IS_MULTIROM), true)
include $(commands_recovery_local_path)/multirom/prebuilt/Android.mk \
$(commands_recovery_local_path)/multirom/cp_xattrs/Android.mk
endif
ifeq ($(TW_INCLUDE_CRYPTO), true)
include $(commands_recovery_local_path)/crypto/lollipop/Android.mk
include $(commands_recovery_local_path)/crypto/scrypt/Android.mk
......
......@@ -71,6 +71,11 @@ ifeq ($(TW_ROUND_SCREEN), true)
LOCAL_CFLAGS += -DTW_ROUND_SCREEN
endif
#MultiROM
ifeq ($(TARGET_RECOVERY_IS_MULTIROM), true)
LOCAL_CFLAGS += -DTARGET_RECOVERY_IS_MULTIROM
endif
LOCAL_C_INCLUDES += bionic system/core/libpixelflinger/include
ifeq ($(shell test $(PLATFORM_SDK_VERSION) -lt 23; echo $$?),0)
LOCAL_C_INCLUDES += external/stlport/stlport
......
This diff is collapsed.
......@@ -37,6 +37,9 @@ GUIFileSelector::GUIFileSelector(xml_node<>* node) : GUIScrollList(node)
{
xml_attribute<>* attr;
xml_node<>* child;
#ifdef TARGET_RECOVERY_IS_MULTIROM
xml_node<>* parent;
#endif
mFolderIcon = mFileIcon = NULL;
mShowFolders = mShowFiles = mShowNavFolders = 1;
......@@ -49,7 +52,26 @@ GUIFileSelector::GUIFileSelector(xml_node<>* node) : GUIScrollList(node)
if (child) {
attr = child->first_attribute("extn");
if (attr)
#ifndef TARGET_RECOVERY_IS_MULTIROM
mExtn = attr->value();
#else
{
std::string str = attr->value();
const char delimiter = ';';
size_t idx = 0, idx_next = 0, len;
do
{
idx_next = str.find(delimiter, idx+1);
if(idx != 0 && idx != std::string::npos)
++idx;
len = std::min(idx_next, str.size()) - idx;
mExtn.push_back(str.substr(idx, len));
idx = idx_next;
} while(idx != std::string::npos);
}
#endif //TARGET_RECOVERY_IS_MULTIROM
attr = child->first_attribute("folders");
if (attr)
mShowFolders = atoi(attr->value());
......@@ -115,6 +137,19 @@ GUIFileSelector::GUIFileSelector(xml_node<>* node) : GUIScrollList(node)
int iconHeight = std::max(mFolderIcon->GetHeight(), mFileIcon->GetHeight());
SetMaxIconSize(iconWidth, iconHeight);
#ifdef TARGET_RECOVERY_IS_MULTIROM
// Load excludes
parent = node->first_node("excludes");
if (parent) child = parent->first_node("exclude");
else child = node->first_node("exclude");
while (child)
{
mExcludeFiles.push_back(child->value());
child = child->next_sibling("exclude");
}
#endif //TARGET_RECOVERY_IS_MULTIROM
// Fetch the file/folder list
std::string value;
DataManager::GetValue(mPathVar, value);
......@@ -262,6 +297,12 @@ int GUIFileSelector::GetFileList(const std::string folder)
data.lastModified = st.st_mtime;
data.lastStatChange = st.st_ctime;
#ifdef TARGET_RECOVERY_IS_MULTIROM
// skip excludes
if(std::find(mExcludeFiles.begin(), mExcludeFiles.end(), data.fileName) != mExcludeFiles.end())
continue;
#endif
if (data.fileType == DT_UNKNOWN) {
data.fileType = TWFunc::Get_D_Type_From_Stat(path);
}
......@@ -269,9 +310,25 @@ int GUIFileSelector::GetFileList(const std::string folder)
if (mShowNavFolders || (data.fileName != "." && data.fileName != ".."))
mFolderList.push_back(data);
} else if (data.fileType == DT_REG || data.fileType == DT_LNK || data.fileType == DT_BLK) {
#ifndef TARGET_RECOVERY_IS_MULTIROM
if (mExtn.empty() || (data.fileName.length() > mExtn.length() && data.fileName.substr(data.fileName.length() - mExtn.length()) == mExtn)) {
mFileList.push_back(data);
}
#else
if(mExtn.empty()) {
mFileList.push_back(data);
} else {
for(size_t i = 0; i < mExtn.size(); ++i)
{
const std::string& ext = mExtn[i];
if (ext.empty() || (data.fileName.length() > ext.length() && data.fileName.substr(data.fileName.length() - ext.length()) == ext))
{
mFileList.push_back(data);
break;
}
}
}
#endif //TARGET_RECOVERY_IS_MULTIROM
}
}
closedir(d);
......
......@@ -78,6 +78,20 @@ GUIListBox::GUIListBox(xml_node<>* node) : GUIScrollList(node)
else
allowSelection = false; // allows using listbox as a read-only list or menu
#ifdef TARGET_RECOVERY_IS_MULTIROM
// Note: I'm adding this here, before the next section, because 'if (!child) return;' sounds redundant below
// Load dynamic data
child = node->first_node("items");
if (child)
mItemsVar = child->value();
// Call this to get the selected item to be shown in the list on first render
// don't think this is needed anymore: NotifyVarChange(mVariable, currentValue);
if(!mItemsVar.empty())
NotifyVarChange(mItemsVar, DataManager::GetStrValue(mItemsVar));
#endif //TARGET_RECOVERY_IS_MULTIROM
// Get the data for the list
child = FindNode(node, "listitem");
if (!child) return;
......@@ -143,6 +157,39 @@ int GUIListBox::NotifyVarChange(const std::string& varName, const std::string& v
if(!isConditionTrue())
return 0;
#ifdef TARGET_RECOVERY_IS_MULTIROM
if(!mItemsVar.empty() && mItemsVar == varName) {
std::string n;
char *cstr = new char[value.size()+1];
strcpy(cstr, value.c_str());
mListItems.clear();
char *p = strtok(cstr, "\n");
while(p)
{
n = std::string(p);
ListItem data;
data.displayName = n; //item.displayName = attr->value();
data.variableValue = n; //item.variableValue = gui_parse_text(child->value());
if(n == currentValue)
data.selected = 1; //item.selected = (child->value() == currentValue);
else
data.selected = 0;
data.action = NULL; //item.action = NULL;
mListItems.push_back(data);
mVisibleItems.push_back(mListItems.size()-1);
p = strtok(NULL, "\n");
}
delete[] cstr;
mUpdate = 1;
}
// in case we ever move the above code elsewhere
if(!mItemsVar.empty() && mItemsVar == varName) {
currentValue = value;
mUpdate = 1;
}
#endif
// Check to see if the variable that we are using to store the list selected value has been updated
if (varName == mVariable) {
currentValue = value;
......@@ -199,6 +246,10 @@ void GUIListBox::SetPageFocus(int inFocus)
item.displayName = gui_parse_text(item.displayName);
}
}
#ifdef TARGET_RECOVERY_IS_MULTIROM
if(!mItemsVar.empty())
NotifyVarChange(mItemsVar, DataManager::GetStrValue(mItemsVar));
#endif
DataManager::GetValue(mVariable, currentValue);
NotifyVarChange(mVariable, currentValue);
}
......
......@@ -321,6 +321,26 @@ protected:
int getpartitiondetails(std::string arg);
int screenshot(std::string arg);
int setbrightness(std::string arg);
#ifdef TARGET_RECOVERY_IS_MULTIROM
int rotation(std::string arg);
int timeout(std::string arg);
int multirom(std::string arg);
int multirom_reset_roms_paths(std::string arg);
int multirom_rename(std::string arg);
int multirom_manage(std::string arg);
int multirom_settings(std::string arg);
int multirom_settings_save(std::string arg);
int multirom_add(std::string arg);
int multirom_add_second(std::string arg);
int multirom_add_file_selected(std::string arg);
int multirom_change_img_size(std::string arg);
int multirom_change_img_size_act(std::string arg);
int multirom_set_list_loc(std::string arg);
int multirom_list_loc_selected(std::string arg);
int multirom_exit_backup(std::string arg);
int multirom_create_internal_rom_name(std::string arg);
int multirom_list_roms_for_swap(std::string arg);
#endif //TARGET_RECOVERY_IS_MULTIROM
// (originally) threaded actions
int fileexists(std::string arg);
......@@ -356,6 +376,27 @@ protected:
int cancelbackup(std::string arg);
int checkpartitionlifetimewrites(std::string arg);
int mountsystemtoggle(std::string arg);
#ifdef TARGET_RECOVERY_IS_MULTIROM
int multirom_delete(std::string arg);
int multirom_flash_zip(std::string arg);
int multirom_flash_zip_sailfish(std::string arg);
int multirom_inject(std::string arg);
int multirom_inject_curr_boot(std::string arg);
int multirom_add_rom(std::string arg);
int multirom_ubuntu_patch_init(std::string arg);
int multirom_touch_patch_init(std::string arg);
int multirom_wipe(std::string arg);
int multirom_disable_flash_kernel(std::string arg);
int multirom_rm_bootimg(std::string arg);
int multirom_backup_rom(std::string arg);
int multirom_sideload(std::string arg);
int multirom_swap_calc_space(std::string arg);
int multirom_execute_swap(std::string arg);
int multirom_set_fw(std::string arg);
int multirom_remove_fw(std::string arg);
int multirom_restorecon(std::string arg);
int system_image_upgrader(std::string arg);
#endif //TARGET_RECOVERY_IS_MULTIROM
int setlanguage(std::string arg);
int twcmd(std::string arg);
......@@ -593,7 +634,12 @@ protected:
std::vector<FileData> mFileList;
std::string mPathVar; // current path displayed, saved in the data manager
std::string mPathDefault; // default value for the path if none is set in mPathVar
#ifdef TARGET_RECOVERY_IS_MULTIROM
std::vector<std::string> mExcludeFiles;
std::vector<std::string> mExtn; // used for filtering the file list, for example, *.zip
#else
std::string mExtn; // used for filtering the file list, for example, *.zip
#endif
std::string mVariable; // set when the user selects an item, pull path like /path/to/foo
std::string mSortVariable; // data manager variable used to change the sorting of files
std::string mSelection; // set when the user selects an item without the full path like selecting /path/to/foo would just be set to foo
......@@ -641,6 +687,9 @@ protected:
std::vector<size_t> mVisibleItems; // contains indexes in mListItems of visible items only
std::string mVariable;
std::string currentValue;
#ifdef TARGET_RECOVERY_IS_MULTIROM
std::string mItemsVar;
#endif
ImageResource* mIconSelected;
ImageResource* mIconUnselected;
bool isCheckList;
......
......@@ -234,3 +234,61 @@ dirUnlinkHierarchy(const char *path)
/* 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;
}
......@@ -48,6 +48,14 @@ int dirCreateHierarchy(const char *path, int mode,
*/
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);
#ifdef __cplusplus
}
#endif
......
Build flag (in BoardConfig)
===========================
- add TARGET_RECOVERY_IS_MULTIROM := true
to enable multirom version of twrp
- TODO: check for this flag in system/extras/multirom
and libbootimg, and disable building them if the flag
is not set, otherwise multirom binaries always get
built and added into recovery
Folder changes
==============
- move multirom files to separate sub-folder recovery/multirom
- move multirom specific prebuilts to recovery/multirom/prebuilt (1)
- move multirom specific cp_xattrs to recovery/multirom/cp_xattrs (1)
Notes: (1) update/create Android.mk files
multirom Code changes
=====================
- fix #include statements (where needed) to look in parent folder
i.e. append "../" where necessary
- remove deprecated 'flags' in function call to mzExtractRecursive
in mrominstaller.cpp (line 317)
deprecated in this commit
https://github.com/omnirom/android_bootable_recovery/commit/9c0f5d6b348e37533bdcccf1166d6cbf1ca5c50b
minzip Code changes
===================
- add function 'read_data' needed by multirom in Zip.h and Zip.c
- update Android.mk with build flag TARGET_RECOVERY_IS_MULTIROM
Note: i guess this could get moved out of minzip and into multirom itself
gui Code changes
================
- objects.hpp add multirom action definitions
- action.cpp add multirom actions and functions
Note: TW_ORS_IS_SECONDARY_ROM code moved to openrecoveryscript.cpp
- update Android.mk with build flag TARGET_RECOVERY_IS_MULTIROM
main Code changes
=================
- variables.h add multirom specific defines
- twrp.cpp add/embed multirom specific code
- partitions.hpp, partition.cpp, partitionmanager.cpp
+ add and embed multirom specific code
- twrp-functions(hpp/cpp) add functions needed by multirom
+ static int Exec_Cmd_Show_Output(const string& cmd);
+ static int write_file(string fn, const string& line);
+ static int write_file(string fn, const string& line, const char *mode);
+ static bool loadTheme();
+ static bool reloadTheme();
+ static std::string getDefaultThemePath(int rotation);
+ static std::string getZIPThemePath(int rotation);
+ static std::string getROMName();
+ static void stringReplace(std::string& str, char before, char after);
+ static void trim(std::string& str);
+ static int64_t getFreeSpace(const std::string& path);
+ static bool restorecon(const std::string& path, struct selabel_handle *sh);
- openrecoveryscript.cpp
+ TW_ORS_IS_SECONDARY_ROM code moved here from gui/action.cpp
- update Android.mk
+ add new build flag TARGET_RECOVERY_IS_MULTIROM
+ add multirom source files, libraries, etc.
General notes
=============
- the theme files have not been updated; instead a multirom twrp theme should be
declared and added in the device folder
TODO: fix this
- rotation is currently not used (commented out), and set to false in Android.mk
which also affects the following function in twrp-functions.zpp
+ static bool loadTheme();
+ static bool reloadTheme();
+ static std::string getDefaultThemePath(int rotation);
+ static std::string getZIPThemePath(int rotation);
these are just dummy functions at the moment; the original code is still in
twrp-functions.cpp, but commented out
- partitions.hpp, partition.cpp, partitionmanager.cpp: code could be reviewed
for cleanup; many #ifdef...#endif statements can be recoded to a neater style
(since it's being more or less just duplicated) but for the time being i'm
keeping it as is, since it may make future merges easier to cope with.
TODO: reconsider this
- partitionmanager.cpp: deprecated function
+ void TWPartitionManager::Update_Storage_Sizes()
has been directly integrated into
+ void TWPartitionManager::Update_System_Details(void)
we could create the function with a suitable #ifdef...#else...#endif
instead of duplicating the code
for now, i'm keeping it as is, since the old code is also there, but
commented out (for reference)
- partition.cpp: use 'exfat_mounted' instead of 'mounted'
we don't want to rename exfat_mounted (for future merges), but we could
+ #define mounted exfat_mounted
to keep both visually intact
BUGS
====
- is restorecon still broken? due to the -D flag in multirom.cpp
+ #if PLATFORM_SDK_VERSION >= 21 #define RESTORECON_ARGS "-RFDv"
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := libcp_xattrs.cpp
LOCAL_MODULE := libcp_xattrs
LOCAL_MODULE_TAGS := eng
LOCAL_SHARED_LIBRARIES += libc libstlport
LOCAL_C_INCLUDES += bionic external/stlport/stlport
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := cp_xattrs.cpp
LOCAL_MODULE := cp_xattrs
LOCAL_MODULE_TAGS := eng
LOCAL_C_INCLUDES += bionic external/stlport/stlport
LOCAL_SHARED_LIBRARIES += libc libstlport
LOCAL_STATIC_LIBRARIES += libcp_xattrs
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_EXECUTABLES_UNSTRIPPED)
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := ls_xattrs.cpp
LOCAL_MODULE := ls_xattrs
LOCAL_MODULE_TAGS := eng
LOCAL_C_INCLUDES += bionic external/stlport/stlport
LOCAL_SHARED_LIBRARIES += libc libstlport
LOCAL_STATIC_LIBRARIES += libcp_xattrs
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_EXECUTABLES_UNSTRIPPED)
include $(BUILD_EXECUTABLE)
#include <stdio.h>
#include <string>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "libcp_xattrs.h"
int main(int argc, char *argv[])
{
std::string from, to;
struct stat info;
if(argc >= 3)
{
from = argv[1];
to = argv[2];
}
else
{
printf("Usage: %s SOURCE DEST\n", argv[0]);
return 1;
}
if(lstat(from.c_str(), &info) < 0)
{
fprintf(stderr, "lstat on %s failed: %s\n", from.c_str(), strerror(errno));
return 1;
}
return cp_xattrs_recursive(from, to, S_ISDIR(info.st_mode) ? DT_DIR : DT_REG) ? 0 : 1;
}
#include <stdio.h>
#include <unistd.h>
#include <string>
#include <dirent.h>
#include <stdlib.h>
#include <linux/capability.h>
#include <linux/xattr.h>
#include <sys/xattr.h>
#include <sys/vfs.h>
#include "libcp_xattrs.h"
static bool cp_xattrs_list_xattrs_callback(const std::string& from,
bool (*callback)(const char *attr, const char *data, ssize_t data_size, void *cookie),
void *cookie)
{
ssize_t res;
char static_names[512];
char static_data[256];
char *names = static_names;
char *data = static_data;
char *names_itr;
ssize_t list_size;
ssize_t value_size;
ssize_t data_size = sizeof(static_data);
list_size = llistxattr(from.c_str(), NULL, 0);
if(list_size == 0)
return true;
else if(list_size < 0)
{
fprintf(stderr, "Failed to llistxattr on %s: %s", from.c_str(), strerror(errno));
return false;
}
else if(list_size > 16*1024)
{
fprintf(stderr, "Failed to llistxattr: list is too long! %s (%d)", from.c_str(), list_size);
return false;
}
if(list_size > (ssize_t)sizeof(static_names))
{
names = (char*)malloc(list_size);
printf("alloc names %d\n", list_size);
}
list_size = llistxattr(from.c_str(), names, list_size);
if(list_size < 0)
{
fprintf(stderr, "Failed to llistxattr on %s: %s", from.c_str(), strerror(errno));
return false;
}
for(names_itr = names; names_itr < names + list_size; names_itr += strlen(names_itr) + 1)
{
value_size = lgetxattr(from.c_str(), names_itr, NULL, 0);
if(value_size < 0)
{
if(errno == ENOENT)
continue;
fprintf(stderr, "Failed lgetxattr on %s: %d (%s)\n", from.c_str(), errno, strerror(errno));
return false;
}
if(value_size > 16*1024)
{
fprintf(stderr, "Failed to lgetxattr: value is too long! %s (%d)", from.c_str(), value_size);
return false;
}
if(value_size > (ssize_t)sizeof(static_data) && value_size > data_size)
{
if(data == static_data)
data = NULL;
data_size = value_size;
data = (char*)realloc(data, data_size);
printf("alloc data %d\n", data_size);
}
res = lgetxattr(from.c_str(), names_itr, data, value_size);
if(res < 0)
{
fprintf(stderr, "Failed lgetxattr on %s: %d (%s)\n", from.c_str(), errno, strerror(errno));
return false;
}
if(!callback(names_itr, data, value_size, cookie))
return false;
}
if(names != static_names)
free(names);
if(data != static_data)
free(data);
return true;
}
static bool cp_xattrs_single_file_callback(const char *attr, const char *data, ssize_t data_size, void *cookie)
{
std::string *to = (std::string*)cookie;
ssize_t res = lsetxattr(to->c_str(), attr, data, data_size, 0);
if(res < 0 && errno != ENOENT)
{
fprintf(stderr, "Failed to lsetxattr %s on %s: %d (%s)\n", attr, to->c_str(), errno, strerror(errno));
return false;
}
return true;
}
bool cp_xattrs_single_file(const std::string& from, const std::string& to)
{
return cp_xattrs_list_xattrs_callback(from, &cp_xattrs_single_file_callback, (void*)&to);
}
static bool cp_xattrs_list_xattrs_map_callback(const char *attr, const char *data, ssize_t data_size, void *cookie)
{
std::map<std::string, std::vector<char> > *res = (std::map<std::string, std::vector<char> >*)cookie;
std::vector<char> data_vec(data, data+data_size);
res->insert(std::make_pair(attr, data_vec));
return true;
}
bool cp_xattrs_list_xattrs(const std::string& path, std::map<std::string, std::vector<char> > &res)
{
return cp_xattrs_list_xattrs_callback(path, &cp_xattrs_list_xattrs_map_callback, (void*)&res);
}
bool cp_xattrs_recursive(const std::string& from, const std::string& to, unsigned char type)
{
if(!cp_xattrs_single_file(from, to))
return false;
if(type != DT_DIR)
return true;
DIR *d;
struct dirent *dt;
d = opendir(from.c_str());
if(!d)
{
fprintf(stderr, "Failed to open dir %s\n", from.c_str());
return false;
}
while((dt = readdir(d)))
{
if (dt->d_type == DT_DIR && dt->d_name[0] == '.' &&
(dt->d_name[1] == '.' || dt->d_name[1] == 0))
continue;
if(!cp_xattrs_recursive(from + "/" + dt->d_name, to + "/" + dt->d_name, dt->d_type))
{
closedir(d);
return false;
}
}
closedir(d);
return true;
}
#ifndef LIBCPXATTRS_H
#define LIBCPXATTRS_H
#include <string>
#include <map>
#include <vector>
bool cp_xattrs_single_file(const std::string& from, const std::string& to);
bool cp_xattrs_recursive(const std::string& from, const std::string& to, unsigned char type);
bool cp_xattrs_list_xattrs(const std::string& path, std::map<std::string, std::vector<char> > &res);
#endif
#include <stdio.h>
#include <string>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "libcp_xattrs.h"
int main(int argc, char *argv[])
{
int i;
std::map<std::string, std::vector<char> > attrs;
std::map<std::string, std::vector<char> >::iterator itr;
if(argc < 2)
{
printf("Usage: %s FILE(s)\n", argv[0]);
return 1;
}
for(i = 1; i < argc; ++i)
{
printf("%s:\n", argv[i]);
if(!cp_xattrs_list_xattrs(argv[i], attrs))
return -1;
for(itr = attrs.begin(); itr != attrs.end(); ++itr)
{
printf(" %s: ", itr->first.c_str());
for(size_t c = 0; c < itr->second.size(); ++c)
printf("%c", itr->second[c]);
printf("\n");
}
printf("\n");
attrs.clear();
}
return 0;
}
#include <cstring>
#include <algorithm>
#include <limits>
// android does not have statvfs
//#include <sys/statvfs.h>
#include <sys/vfs.h>
#define statvfs statfs
#include "mrominstaller.h"
#include "../minzip/SysUtil.h"
#include "../minzip/Zip.h"
#include "multirom_Zip.h"
#include "../common.h"
#include "multirom.h"
#include "cutils/properties.h"
extern "C" {
#include "../twcommon.h"
}
#define INTERNAL_MEM_LOC_TXT "Internal memory"
MROMInstaller::MROMInstaller()
{
m_type = ROM_UNKNOWN;
}
MROMInstaller::~MROMInstaller()
{
}
int gui_changePage(std::string newPage);
int MROMInstaller::destroyWithErrorMsg(const std::string& ex)
{
delete this;
DataManager::SetValue("tw_mrom_text1", ex);
return gui_changePage("multirom_msg");
}
std::string MROMInstaller::open(const std::string& file)
{
char* manifest = NULL;
const ZipEntry *script_entry;
ZipArchive zip;
MemMapping map;
if (sysMapFile(file.c_str(), &map) != 0) {
LOGERR("Failed to sysMapFile '%s'\n", file.c_str());
return false;
}
if (mzOpenZipArchive(map.addr, map.length, &zip) != 0)
return "Failed to open installer file!";
script_entry = mzFindZipEntry(&zip, "manifest.txt");
if(!script_entry)
{
mzCloseZipArchive(&zip);
sysReleaseMap(&map);
return "Failed to find manifest.txt";
}
int res = read_data(&zip, script_entry, &manifest, NULL);
mzCloseZipArchive(&zip);
sysReleaseMap(&map);
if(res < 0)
return "Failed to read manifest.txt!";
int line_cnt = 1;
for(char *line = strtok(manifest, "\r\n"); line; line = strtok(NULL, "\r\n"), ++line_cnt)
{
if(line[0] == '#')
continue;
char *val = strchr(line, '=');
if(!val)
continue;
std::string key = std::string(line, val-line);
++val; // skip '=' char
char *start = strchr(val, '"');
char *end = strrchr(val, '"');
if(!start || start == end || start+1 == end)
gui_print("Line %d: failed to parse string\n", line_cnt);
else
{
++start;
m_vals[key] = std::string(start, end-start);
LOGI("MROMInstaller: got tag %s=%s\n", key.c_str(), m_vals[key].c_str());
}
}
free(manifest);
static const char* needed[] = {
"manifest_ver", "devices", "base_folders"
};
for(uint32_t i = 0; i < sizeof(needed)/sizeof(needed[0]); ++i)
{
std::map<std::string, std::string>::const_iterator itr = m_vals.find(needed[i]);
if(itr == m_vals.end())
return std::string("Required key not found in manifest: ") + needed[i];
}
m_file = file;
return std::string();
}
int MROMInstaller::getIntValue(const std::string& name, int def) const
{
std::map<std::string, std::string>::const_iterator itr = m_vals.find(name);
if(itr == m_vals.end())
return def;
return atoi(itr->second.c_str());
}
std::string MROMInstaller::getValue(const std::string& name, std::string def) const
{
std::map<std::string, std::string>::const_iterator itr = m_vals.find(name);
if(itr == m_vals.end())
return def;
return itr->second;
}
int MROMInstaller::getStringList(std::vector<std::string>& list, const std::string& name) const
{
std::string str = getValue(name);
if(str.empty())
return 0;
size_t idx = 0, idx_next = 0, len;
int cnt = 0;
do
{
idx_next = str.find(' ', idx+1);
if(idx != 0)
++idx;
len = std::min(idx_next, str.size()) - idx;
list.push_back(str.substr(idx, len));
idx = idx_next;
++cnt;
} while(idx != std::string::npos);
if(cnt == 0)
{
++cnt;
list.push_back(str);
}
return cnt;
}
std::string MROMInstaller::setInstallLoc(const std::string& loc, bool &images)
{
if(loc.compare(INTERNAL_MEM_LOC_TXT) == 0)
{
if(getIntValue("enable_internal"))
{
images = false;
m_type = ROM_INSTALLER_INTERNAL;
return std::string();
}
else
return "ROM can't be installed to internal memory!";
}
else
{
size_t start = loc.find('(');
size_t end = loc.find(')');
if(start == std::string::npos || end == std::string::npos)
return "Failed to get filesystem of target location";
++start;
std::string fs = loc.substr(start, end-start);
// try to be dir first
std::vector<std::string> supported;
getStringList(supported, "usb_dir_fs");
if(std::find(supported.begin(), supported.end(), fs) != supported.end())
{
images = false;
m_type = ROM_INSTALLER_USB_DIR;
return std::string();
}
// now images
supported.clear();
getStringList(supported, "usb_img_fs");
if(std::find(supported.begin(), supported.end(), fs) != supported.end())
{
images = true;
m_type = ROM_INSTALLER_USB_IMG;
return std::string();
}
return std::string("Install location has unsupported fs (") + fs + ")";
}
return std::string();
}
std::string MROMInstaller::checkDevices() const
{
bool found = false;
char device[255];
if(property_get("ro.product.device", device, NULL) <= 0)
return "Could not get ro.product.device property!";
std::string list = getValue("devices");
char *p = strtok((char*)list.c_str(), " ");
while(p && !found)
{
if(strcmp(device, p) == 0)
found = true;
p = strtok(NULL, " ");
}
if(!found)
return std::string("device (") + device + ") not supported (allowed: " + list + ")!";
return std::string();
}
std::string MROMInstaller::checkVersion() const
{
int min_ver = getIntValue("min_mrom_ver", -1);
if(min_ver == -1)
return std::string();
char cmd[256];
sprintf(cmd, "rm /tmp/ver; sh -c \"%s/multirom -v > /tmp/ver\"", MultiROM::getPath().c_str());
system(cmd);
FILE *f = fopen("/tmp/ver", "r");
if(!f)
return "Failed to check MultiROM version!";
fgets(cmd, sizeof(cmd), f);
fclose(f);
int ver = atoi(cmd);
if(ver < min_ver)
{
sprintf(cmd, "Required ver: %d, curr ver: %d", min_ver, ver);
return std::string(cmd);
}
return std::string();
}
std::string MROMInstaller::parseBaseFolders(bool ntfs)
{
MultiROM::clearBaseFolders();
char *itr, *itr2, *p, *t;
base_folder b;
std::string s = getValue("base_folders");
p = strtok_r((char*)s.c_str(), " ", &itr);
for(int i = 0; p; ++i)
{
t = strtok_r(p, ":", &itr2);
for(int x = 0; t; ++x)
{
switch(x)
{
case 0:
b.name = t;
break;
case 1:
b.min_size = std::min(atoi(t), ntfs ? INT_MAX : 4095);
break;
case 2:
b.size = std::min(atoi(t), ntfs ? INT_MAX : 4095);
MultiROM::addBaseFolder(b);
break;
}
t = strtok_r(NULL, ":", &itr2);
}
p = strtok_r(NULL, " ", &itr);
}
if(MultiROM::getBaseFolders().size() > MAX_BASE_FOLDER_CNT)
return "Too many base folders!";
return std::string();
}
bool MROMInstaller::extractDir(const std::string& name, const std::string& dest)
{
ZipArchive zip;
MemMapping map;
if (sysMapFile(m_file.c_str(), &map) != 0) {
LOGERR("Failed to sysMapFile '%s'\n", m_file.c_str());
return false;
}
if (mzOpenZipArchive(map.addr, map.length, &zip) != 0)
{
gui_print("Failed to open ZIP file %s\n", m_file.c_str());
sysReleaseMap(&map);
return false;
}
// To create a consistent system image, never use the clock for timestamps.
struct utimbuf timestamp = { 1217592000, 1217592000 }; // 8/1/2008 default
bool success = mzExtractRecursive(&zip, name.c_str(), dest.c_str(), &timestamp, NULL, NULL, NULL);
mzCloseZipArchive(&zip);
sysReleaseMap(&map);
if(!success)
{
gui_print("Failed to extract dir %s from zip %s\n", name.c_str(), m_file.c_str());
return false;
}
return true;
}
bool MROMInstaller::extractFile(const std::string& name, const std::string& dest)
{
ZipArchive zip;
MemMapping map;
if (sysMapFile(m_file.c_str(), &map) != 0) {
LOGERR("Failed to sysMapFile '%s'\n", m_file.c_str());
return false;
}
if (mzOpenZipArchive(map.addr, map.length, &zip) != 0)
{
gui_print("Failed to open ZIP file %s\n", m_file.c_str());
sysReleaseMap(&map);
return false;
}
bool res = false;
FILE* f = NULL;
const ZipEntry* entry = mzFindZipEntry(&zip, name.c_str());
if (entry == NULL)
{
gui_print("Could not find file %s in zip %s\n", name.c_str(), m_file.c_str());
goto exit;
}
f = fopen(dest.c_str(), "wb");
if(!f)
{
gui_print("Could not open dest file %s for writing!\n", dest.c_str());
goto exit;
}
res = mzExtractZipEntryToFile(&zip, entry, fileno(f));
if(!res)
gui_print("Failed to extract file %s from the ZIP!", name.c_str());
fclose(f);
exit:
mzCloseZipArchive(&zip);
sysReleaseMap(&map);
return res;
}
bool MROMInstaller::hasEntry(const std::string& name)
{
ZipArchive zip;
MemMapping map;
if (sysMapFile(m_file.c_str(), &map) != 0) {
LOGERR("Failed to sysMapFile '%s'\n", m_file.c_str());
return false;
}
if (mzOpenZipArchive(map.addr, map.length, &zip) != 0)
{
gui_print("Failed to open ZIP file %s\n", m_file.c_str());
sysReleaseMap(&map);
return false;
}
// Check also for entry with / - according to minzip, folders
// usually (but not always) end with /
const ZipEntry *entry1 = mzFindZipEntry(&zip, name.c_str());
const ZipEntry *entry2 = mzFindZipEntry(&zip, (name + "/").c_str());
mzCloseZipArchive(&zip);
sysReleaseMap(&map);
return entry1 || entry2;
}
bool MROMInstaller::runScripts(const std::string& dir, const std::string& base, const std::string& root)
{
system("rm -r /tmp/script; mkdir /tmp/script");
if(!hasEntry(dir))
{
LOGI("Skippping scripts in %s, not in the ZIP\n", dir.c_str());
return true;
}
if(!extractDir(dir, "/tmp/script/"))
return false;
if(system("ls /tmp/script/*.sh") == 0)
{
system("chmod -R 777 /tmp/script/*");
gui_print("Running %s scripts...\n", dir.c_str());
char cmd[512];
sprintf(cmd, "sh -c 'for x in $(ls /tmp/script/*.sh); do echo Running script $x; sh $x %s %s || exit 1; done'", base.c_str(), root.c_str());
if(system(cmd) != 0)
{
system("rm -r /tmp/script/");
gui_print("One of the ROM scripts returned error status!");
return false;
}
}
else
LOGI("Skipping folder %s, no bash scripts\n", dir.c_str());
system("rm -r /tmp/script");
return true;
}
bool MROMInstaller::extractTarballs(const std::string& base)
{
system("rm -r /tmp/tarballs; mkdir /tmp/tarballs");
if(!hasEntry("rom"))
{
gui_print("Skippping tarball extractions - no rom folder in the ZIP file\n");
return true;
}
bool res = false;
const MultiROM::baseFolders& folders = MultiROM::getBaseFolders();
MultiROM::baseFolders::const_iterator itr;
for(itr = folders.begin(); itr != folders.end(); ++itr)
{
if(!extractBase(base, itr->first))
{
gui_print("Failed to extract base %s\n", itr->first.c_str());
goto exit;
}
}
res = true;
exit:
system("rm -r /tmp/tarballs");
return res;
}
bool MROMInstaller::extractBase(const std::string& base, const std::string& name)
{
char cmd[256];
sprintf(cmd, "rom/%s.tar.gz", name.c_str());
if(hasEntry(cmd))
return extractTarball(base, name, cmd);
else
{
char cmd[256];
for(int i = 0; true; ++i)
{
sprintf(cmd, "rom/%s_%02d.tar.gz", name.c_str(), i);
if(!hasEntry(cmd))
break;
if(!extractTarball(base, name, cmd))
return false;
}
}
return true;
}
bool MROMInstaller::extractTarball(const std::string& base, const std::string& name, const std::string& tarball)
{
gui_print("Extrating tarball %s...\n", tarball.c_str());
system("rm /tmp/tarballs/rom.tar.gz");
if(!extractFile(tarball, "/tmp/tarballs/rom.tar.gz"))
return false;
bool res = true;
char cmd[256];
sprintf(cmd, "gnutar --numeric-owner --overwrite -C \"%s\" -xf /tmp/tarballs/rom.tar.gz", (base + "/" + name).c_str());
if(system(cmd) != 0)
{
gui_print("Failed to extract tarball %s for folder %s!\n", tarball.c_str(), name.c_str());
res = false;
}
system("rm /tmp/tarballs/rom.tar.gz");
return res;
}
bool MROMInstaller::checkFreeSpace(const std::string& base, bool images)
{
struct statvfs s;
int res = statvfs(base.c_str(), &s);
if(res < 0)
{
gui_print("Check for free space failed: %s %d %d %s!\n", base.c_str(), res, errno, strerror(errno));
return false;
}
int free = (s.f_bavail * (s.f_bsize/1024) ) / 1024;
int req = 0;
const MultiROM::baseFolders& folders = MultiROM::getBaseFolders();
MultiROM::baseFolders::const_iterator itr;
for(itr = folders.begin(); itr != folders.end(); ++itr)
{
if(images)
req += itr->second.size;
else
req += itr->second.min_size;
}
gui_print("Free space check: Required: %d MB, free: %d MB\n", req, free);
if(free < req)
LOGERR("Not enough free space!\n");
return free >= req;
}
#ifndef MROM_INSTALLER_H
#define MROM_INSTALLER_H
#include <map>
#include <string>
#include <vector>
class MROMInstaller
{
public:
MROMInstaller();
~MROMInstaller();
int destroyWithErrorMsg(const std::string& ex);
std::string open(const std::string& file);
std::string setInstallLoc(const std::string& loc, bool &images);
std::string checkDevices() const;
std::string checkVersion() const;
std::string parseBaseFolders(bool ntfs);
bool checkFreeSpace(const std::string& base, bool images);
int getRomType() const { return m_type; }
int getIntValue(const std::string& name, int def = 0) const;
std::string getValue(const std::string& name, std::string def = "") const;
int getStringList(std::vector<std::string>& list, const std::string& name) const;
bool runScripts(const std::string& dir, const std::string& base, const std::string& root);
bool extractDir(const std::string& name, const std::string& dest);
bool extractFile(const std::string& name, const std::string& dest);
bool extractTarballs(const std::string& base);
private:
bool hasEntry(const std::string& name);
bool extractBase(const std::string& base, const std::string& name);
bool extractTarball(const std::string& base, const std::string& name, const std::string& tarball);
std::map<std::string, std::string> m_vals;
std::string m_file;
int m_type;
};
#endif
\ No newline at end of file
This diff is collapsed.
#ifndef MULTIROM_H
#define MULTIROM_H
#include <string>
#include <sys/stat.h>
#include <dirent.h>
#include <algorithm>
#include <vector>
#include <errno.h>
#include <sys/mount.h>
#include "../data.hpp"
#include "mrominstaller.h"
enum
{
ROM_INTERNAL_PRIMARY = 0,
ROM_ANDROID_INTERNAL = 1,
ROM_ANDROID_USB_DIR = 2,
ROM_ANDROID_USB_IMG = 3,
ROM_UBUNTU_INTERNAL = 4,
ROM_UBUNTU_USB_DIR = 5,
ROM_UBUNTU_USB_IMG = 6,
ROM_INSTALLER_INTERNAL= 7,
ROM_INSTALLER_USB_DIR = 8,
ROM_INSTALLER_USB_IMG = 9,
ROM_UTOUCH_INTERNAL = 10,
ROM_UTOUCH_USB_DIR = 11,
ROM_UTOUCH_USB_IMG = 12,
ROM_SAILFISH_INTERNAL = 13,
ROM_UNKNOWN,
};
enum
{
CMPR_GZIP = 0,
CMPR_LZ4 = 1,
CMPR_LZMA = 2,
};
#define M(x) (1 << x)
#define MASK_UBUNTU (M(ROM_UBUNTU_INTERNAL) | M(ROM_UBUNTU_USB_IMG)| M(ROM_UBUNTU_USB_DIR))
#define MASK_ANDROID (M(ROM_INTERNAL_PRIMARY) | M(ROM_ANDROID_USB_DIR) | M(ROM_ANDROID_USB_IMG) | M(ROM_ANDROID_INTERNAL))
#define MASK_IMAGES (M(ROM_ANDROID_USB_IMG) | M(ROM_UBUNTU_USB_IMG) | M(ROM_INSTALLER_USB_IMG) | M(ROM_UTOUCH_USB_IMG))
#define MASK_INTERNAL (M(ROM_INTERNAL_PRIMARY) | M(ROM_ANDROID_INTERNAL) | M(ROM_UBUNTU_INTERNAL) | M(ROM_INSTALLER_INTERNAL) | M(ROM_UTOUCH_INTERNAL))
#define MASK_INSTALLER (M(ROM_INSTALLER_INTERNAL) | M(ROM_INSTALLER_USB_DIR) | M(ROM_INSTALLER_USB_IMG))
#define MASK_UTOUCH (M(ROM_UTOUCH_INTERNAL) | M(ROM_UTOUCH_USB_IMG) | M(ROM_UTOUCH_USB_DIR))
#define MASK_SAILFISH (M(ROM_SAILFISH_INTERNAL))
#define MASK_ALL 0xFFFFFFFF
#define INTERNAL_NAME "Internal"
#define REALDATA "/realdata"
#define MAX_ROM_NAME 26
#define INTERNAL_MEM_LOC_TXT "Internal memory"
// Not defined in android includes?
#define MS_RELATIME (1<<21)
#define MAX_BASE_FOLDER_CNT 5
// default image sizes
#ifndef BOARD_SYSTEMIMAGE_PARTITION_SIZE
#define SYS_IMG_DEFSIZE 640
#else
#define SYS_IMG_DEFSIZE (BOARD_SYSTEMIMAGE_PARTITION_SIZE/1024/1024)
#endif
#define DATA_IMG_DEFSIZE 1024
#define CACHE_IMG_DEFSIZE 436
#define SYS_IMG_MINSIZE 450
#define DATA_IMG_MINSIZE 150
#define CACHE_IMG_MINSIZE 50
#define SAILFISH_DATA_IMG_MINSIZE 1024
#define SAILFISH_DATA_IMG_DEFSIZE 1536
#define UB_DATA_IMG_MINSIZE 2048
#define UB_DATA_IMG_DEFSIZE 4095
#define MROM_SWAP_WITH_SECONDARY 0
#define MROM_SWAP_COPY_SECONDARY 1
#define MROM_SWAP_COPY_INTERNAL 2
#define MROM_SWAP_MOVE_INTERNAL 3
#define MROM_SWAP_DUPLICATE 4
#define MROM_AUTOBOOT_LAST 0x01
#define MROM_AUTOBOOT_CHECK_KEYS 0x04
#define MROM_AUTOBOOT_TRIGGER_DISABLED 0
#define MROM_AUTOBOOT_TRIGGER_TIME 1
#define MROM_AUTOBOOT_TRIGGER_KEYS 2
struct base_folder
{
base_folder(const std::string& name, int min_size, int size);
base_folder(const base_folder& other);
base_folder();
std::string name;
int min_size;
int size;
};
class EdifyHacker;
class MultiROM
{
public:
typedef std::map<std::string, base_folder> baseFolders;
struct config {
config();
std::string current_rom;
int auto_boot_seconds;
int auto_boot_type;
std::string auto_boot_rom;
int colors;
int brightness;
int enable_adb;
int hide_internal;
std::string int_display_name;
int rotation;
int force_generic_fb;
int anim_duration_coef_pct;
std::string unrecognized_opts;
};
static bool folderExists();
static std::string getRomsPath();
static std::string getPath();
static int getType(std::string name);
static std::string listRoms(uint32_t mask = MASK_ALL, bool with_bootimg_only = false);
static void setInstaller(MROMInstaller *i);
static MROMInstaller *getInstaller(MROMInstaller *i);
static std::string getBootDev() { return m_boot_dev; }
static bool hasFirmwareDev() { return m_has_firmware; }
static void updateSupportedSystems();
static bool installLocNeedsImages(const std::string& loc);
static void clearBaseFolders();
static const base_folder& addBaseFolder(const std::string& name, int min, int def);
static const base_folder& addBaseFolder(const base_folder& b);
static baseFolders& getBaseFolders();
static base_folder *getBaseFolder(const std::string& name);
static void updateImageVariables();
static bool move(std::string from, std::string to);
static bool erase(std::string name);
static bool restorecon(std::string name);
static bool flashZip(std::string rom, std::string file);
static bool flashORSZip(std::string file, int *wipe_cache);
static bool injectBoot(std::string img_path, bool only_if_older = false);
static bool injectBootDeprecated(std::string img_path, bool only_if_older = false);
static bool extractBootForROM(std::string base);
static int copyBoot(std::string& orig, std::string rom);
static bool wipe(std::string name, std::string what);
static bool initBackup(const std::string& name);
static void deinitBackup();
static config loadConfig();
static void saveConfig(const config& cfg);
static bool addROM(std::string zip, int os, std::string loc);
static std::string listInstallLocations();
static bool setRomsPath(std::string loc);
static bool patchInit(std::string name);
static bool disableFlashKernelAct(std::string name, std::string loc);
static bool fakeBootPartition(const char *fakeImg);
static void restoreBootPartition();
static void failsafeCheckPartition(const char *path);
static bool compareFiles(const char *path1, const char *path2);
static void executeCacheScripts();
static void startSystemImageUpgrader();
static bool ubuntuTouchProcessBoot(const std::string& root, const char *init_folder);
static bool ubuntuTouchProcess(const std::string& root, const std::string& name);
static bool sailfishProcessBoot(const std::string& root);
static bool sailfishProcess(const std::string& root, const std::string& name);
static bool copyInternal(const std::string& dest_name);
static bool wipeInternal();
static bool copySecondaryToInternal(const std::string& rom_name);
static bool duplicateSecondary(const std::string& src, const std::string& dst);
static std::string getRecoveryVersion();
private:
static void findPath();
static bool changeMounts(std::string base);
static void restoreMounts();
static bool prepareZIP(std::string& file, EdifyHacker *hacker, bool& restore_script);
static bool verifyZIP(const std::string& file, int &verify_status);
static std::string getNewRomName(std::string zip, std::string def);
static bool createDirs(std::string name, int type);
static bool compressRamdisk(const char *src, const char *dest, int cmpr);
static int decompressRamdisk(const char *src, const char *dest);
static bool installFromBackup(std::string name, std::string path, int type);
static int getType(int os, std::string loc);
static int getTrampolineVersion();
static int getTrampolineVersion(const std::string& path, bool silent = false);
static bool ubuntuExtractImage(std::string name, std::string img_path, std::string dest);
static bool patchUbuntuInit(std::string rootDir);
static bool ubuntuUpdateInitramfs(std::string rootDir);
static void setUpChroot(bool start, std::string rootDir);
static void ubuntuDisableFlashKernel(bool initChroot, std::string rootDir);
static bool mountUbuntuImage(std::string name, std::string& dest);
static bool createImage(const std::string& base, const char *img, int size);
static bool createImagesFromBase(const std::string& base);
static bool createDirsFromBase(const std::string& base);
static bool mountBaseImages(std::string base, std::string& dest);
static void umountBaseImages(const std::string& base);
static bool createFakeSystemImg();
static int system_args(const char *fmt, ...);
static void translateToRealdata(std::string& path);
static bool calculateMD5(const char *path, unsigned char *md5sum/*len: 16*/);
static void normalizeROMPath(std::string& path);
static void restoreROMPath();
static bool copyPartWithXAttrs(const std::string& src, const std::string& dst, const std::string& part, bool skipMedia = false);
static std::string m_path;
static std::string m_mount_rom_paths[2];
static std::string m_curr_roms_path;
static MROMInstaller *m_installer;
static baseFolders m_base_folders;
static int m_base_folder_cnt;
static std::string m_boot_dev;
static bool m_has_firmware;
};
#endif
//#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_mrom"
#include "../minzip/Zip.h"
#include "multirom_Zip.h"
//#include "../minzip/Bits.h"
#include "../minzip/Log.h"
//#include "../minzip/DirUtil.h"
#undef NDEBUG // do this after including Log.h
//#include <assert.h>
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;
}
#ifndef _MULTIROM_MINZIP_ZIP
#define _MULTIROM_MINZIP_ZIP
//#include "inline_magic.h"
//#include <stdlib.h>
//#include <utime.h>
//#include "Hash.h"
//#include "SysUtil.h"
#ifdef __cplusplus
extern "C" {
#endif
//#include <selinux/selinux.h>
//#include <selinux/label.h>
int read_data(ZipArchive *zip, const ZipEntry *entry, char** ppData, int* pLength);
#ifdef __cplusplus
}
#endif
#endif /*_MULTIROM_MINZIP_ZIP*/
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment