Войти

Показать полную графическую версию : Объясните готовый код


blackeangel
07-01-2017, 10:06
#include "file_contexts.h"

#include "mbutil/autoclose/file.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <cstdlib>

#include <getopt.h>


#define SELINUX_MAGIC_COMPILED_FCONTEXT 0xf97cff8a

#define SELINUX_COMPILED_FCONTEXT_NOPCRE_VERS 1
#define SELINUX_COMPILED_FCONTEXT_PCRE_VERS 2
#define SELINUX_COMPILED_FCONTEXT_MODE 3
#define SELINUX_COMPILED_FCONTEXT_PREFIX_LEN 4

#define SELINUX_COMPILED_FCONTEXT_MAX_VERS \
SELINUX_COMPILED_FCONTEXT_PREFIX_LEN

namespace mb
{

typedef std::vector<std::pair<std::string, std::string>> ContextsList;

typedef std::unique_ptr<char, void (*)(void *)> ScopedCharPtr;

static bool skip_pcre(FILE *fp)
{
size_t n;
uint32_t entry_len;

// Skip PCRE regex
n = fread(&entry_len, 1, sizeof(entry_len), fp);
if (n != sizeof(entry_len) || entry_len == 0) {
return false;
}

if (fseek(fp, entry_len, SEEK_CUR) != 0) {
return false;
}

// Skip PCRE study data
n = fread(&entry_len, 1, sizeof(entry_len), fp);
if (n != sizeof(entry_len) || entry_len == 0) {
return false;
}

if (fseek(fp, entry_len, SEEK_CUR) != 0) {
return false;
}

return true;
}

static bool load_file(FILE *fp, ContextsList *list)
{
size_t n;
uint32_t magic;
uint32_t version;
uint32_t entry_len;
uint32_t stem_map_len;
uint32_t regex_array_len;

// Check magic
n = fread(&magic, 1, sizeof(magic), fp);
if (n != sizeof(magic) || magic != SELINUX_MAGIC_COMPILED_FCONTEXT) {
return false;
}

// Check version
n = fread(&version, 1, sizeof(version), fp);
if (n != sizeof(version) || version > SELINUX_COMPILED_FCONTEXT_MAX_VERS) {
return false;
}

// Skip regex version
if (version >= SELINUX_COMPILED_FCONTEXT_PCRE_VERS) {
n = fread(&entry_len, 1, sizeof(entry_len), fp);
if (n != sizeof(entry_len)) {
return false;
}

if (fseek(fp, entry_len, SEEK_CUR) != 0) {
return false;
}
}

// Skip stem map
n = fread(&stem_map_len, 1, sizeof(stem_map_len), fp);
if (n != sizeof(stem_map_len) || stem_map_len == 0) {
return false;
}

for (uint32_t i = 0; i < stem_map_len; ++i) {
uint32_t stem_len;

// Length does not include NULL-terminator
n = fread(&stem_len, 1, sizeof(stem_len), fp);
if (n != sizeof(stem_len) || stem_len == 0) {
return false;
}

if (stem_len < UINT32_MAX) {
if (fseek(fp, stem_len + 1, SEEK_CUR) != 0) {
return false;
}
} else {
return false;
}
}

// Load regexes
n = fread(&regex_array_len, 1, sizeof(regex_array_len), fp);
if (n != sizeof(regex_array_len) || regex_array_len == 0) {
return false;
}

for (uint32_t i = 0; i < regex_array_len; ++i) {
// Read context string
n = fread(&entry_len, 1, sizeof(entry_len), fp);
if (n != sizeof(uint32_t) || entry_len == 0) {
return false;
}

ScopedCharPtr context(static_cast<char *>(malloc(entry_len)), &free);
if (!context) {
return false;
}

n = fread(context.get(), 1, entry_len, fp);
if (n != entry_len) {
return false;
}

if (context.get()[entry_len - 1] != '\0') {
return false;
}

// Read regex string
n = fread(&entry_len, 1, sizeof(entry_len), fp);
if (n != sizeof(entry_len) || entry_len == 0) {
return false;
}

ScopedCharPtr regex(static_cast<char *>(malloc(entry_len)), &free);
if (!regex) {
return false;
}

n = fread(regex.get(), 1, entry_len, fp);
if (n != entry_len) {
return false;
}

if (regex.get()[entry_len - 1] != '\0') {
return false;
}

// Skip mode
if (version >= SELINUX_COMPILED_FCONTEXT_MODE) {
if (fseek(fp, sizeof(uint32_t), SEEK_CUR) != 0) {
return false;
}
} else {
if (fseek(fp, sizeof(mode_t), SEEK_CUR) != 0) {
return false;
}
}

// Skip stem ID
if (fseek(fp, sizeof(uint32_t), SEEK_CUR) != 0) {
return false;
}

// Skip meta chars
if (fseek(fp, sizeof(uint32_t), SEEK_CUR) != 0) {
return false;
}

if (version >= SELINUX_COMPILED_FCONTEXT_PREFIX_LEN) {
// Skip prefix length
if (fseek(fp, sizeof(uint32_t), SEEK_CUR) != 0) {
return false;
}
}

// Skip PCRE stuff
if (!skip_pcre(fp)) {
return false;
}

list->emplace_back(context.get(), regex.get());
}

return true;
}

FileContextsResult patch_file_contexts(const char *source_path,
const char *target_path)
{
ContextsList list;

autoclose::file fp_old(autoclose::fopen(source_path, "rb"));
if (!fp_old) {
return FileContextsResult::ERRNO;
}

if (!load_file(fp_old.get(), &list)) {
return FileContextsResult::PARSE_ERROR;
}

fp_old.reset();

autoclose::file fp_new(autoclose::fopen(target_path, "w"));
if (!fp_new) {
return FileContextsResult::ERRNO;
}

for (auto const &pair : list) {
auto const &context = pair.first;
auto const &regex = pair.second;

if (fputs(regex.c_str(), fp_new.get()) == EOF
|| fputc(' ', fp_new.get()) == EOF
|| fputs(context.c_str(), fp_new.get()) == EOF
|| fputc('\n', fp_new.get()) == EOF) {
return FileContextsResult::ERRNO;
}
}

return FileContextsResult::OK;
}

static void file_contexts_usage(FILE *stream)
{
fprintf(stream,
"Usage: file_contexts [OPTION]... <input> <output>\n\n"
"Options:\n"
" -h, --help Display this help message\n");
}

int file_contexts_main(int argc, char *argv[])
{
int opt;

static const char *short_options = "h";

static struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{0, 0, 0, 0}
};

int long_index = 0;

while ((opt = getopt_long(argc, argv, short_options,
long_options, &long_index)) != -1) {
switch (opt) {
case 'h':
file_contexts_usage(stdout);
return EXIT_SUCCESS;

default:
file_contexts_usage(stderr);
return EXIT_FAILURE;
}
}

if (argc - optind != 2) {
file_contexts_usage(stderr);
return EXIT_FAILURE;
}

const char *input = argv[optind];
const char *output = argv[optind + 1];

auto ret = patch_file_contexts(input, output);
return ret == FileContextsResult::OK ? EXIT_SUCCESS : EXIT_FAILURE;
}
}

blackeangel
07-01-2017, 10:07
Объясните пожалуйста так, чтобы смог переписать на другом яп

Iska
07-01-2017, 11:36
blackeangel, Вы хоть бы ссылку привели на место. откуда код брали.

blackeangel
07-01-2017, 11:41
blackeangel, Вы хоть бы ссылку привели на место. откуда код брали.
Проект

https://github.com/chenxiaolong/DualBootPatcher/tree/6663c6eec2502d87ae56b43861e90124ff825c88
Сам файл
https://github.com/chenxiaolong/DualBootPatcher/blob/6663c6eec2502d87ae56b43861e90124ff825c88/mbtool/file_contexts.cpp
Инклуды
https://github.com/chenxiaolong/DualBootPatcher/blob/master/libmbutil/include/mbutil/autoclose/file.h
https://github.com/chenxiaolong/DualBootPatcher/blob/6663c6eec2502d87ae56b43861e90124ff825c88/mbtool/file_contexts.h

lxa85
07-01-2017, 20:17
blackeangel, и какой финальный смысл всего этого действия?
Зачем нужен другой ЯП? Зачем вам вообще DualBoot нужен?
Мое первое предположение - курсовой (или диплом) в институте, и вы явно не знаете чем заняться. ИМХО

blackeangel
08-01-2017, 18:59
blackeangel, и какой финальный смысл всего этого действия?
Зачем нужен другой ЯП? Зачем вам вообще DualBoot нужен?
Мое первое предположение - курсовой (или диплом) в институте, и вы явно не знаете чем заняться. ИМХО

Финальный смысл - конверт файла под виндус, а не как тут под андроид.

Уже отучился, так что спасибо за предложение ;-)

lxa85
09-01-2017, 22:16
Уже отучился, так что спасибо за предложение ;-) »
Приятно слышать :)
Финальный смысл - конверт файла под виндус, а не как тут под андроид. »
Смысл по прежнему ускользает.
Про какой Windows мы говорим?
И там есть приписка, мол
See the docs/ directory for instructions on building for Linux, Windows, and Android.
I'm proud to present the first dual boot project for the Qualcomm-based Samsung Galaxy S4! This project started off as a feature in my ROM, but not anymore. This will allow any number of ROMs to be installed at the same time. It works by patching the secondary ROM's installation scripts and boot image to load the ROM files from an alternate location (/system/multiboot, /cache/multiboot, and /data/multiboot). Because of the way this is implemented, no changes to the primary ROM are necessary :D
Переводя вышесказанное, я по прежнему не понимаю целей проекта :(

blackeangel
10-01-2017, 16:10
lxa85, да, там написано как собрать проект под той или иной системой. Но там не будет файлов с расширением .exe это раз. На выходе все равно будут бинарники под андроид. Потом там надо ставить кучу лишнего и тяжелого софта. Потом мне нужен лишь один файл, который сам и есть конвертер.
Сам этот проект - возможность запускать несколько прошивок на одном смарте, но к моей задаче никакого отношения это не имеет.

Но по счастью для всех, все таки не вникая в код, переписал на vb6.0. Совсем по другому принципу шел. Все равно спасибо за участие.
Весь код у меня занял 66 строк.

lxa85
10-01-2017, 17:46
Ничего не понял, но прикольно :)
Весь код у меня занял 66 строк. »
blackeangel, :up Удачи :)

pingUIN
15-02-2017, 18:47
Но по счастью для всех, все таки не вникая в код, переписал на vb6.0. Совсем по другому принципу шел. Все равно спасибо за участие.
Весь код у меня занял 66 строк. »
Поделитесь результатом?
Любопытно взглянуть :)

SerfCompanydotcom
16-02-2017, 15:55
Совсем другой принцип работы. Интересно (http://SerfCompany.com)




© OSzone.net 2001-2012