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; }
// The update binary ask us to install a firmware file on reboot. Set // that up. Takes ownership of type and filename. static int handle_firmware_update(char* type, char* filename, ZipArchive* zip) { unsigned int data_size; const ZipEntry* entry = NULL; if (strncmp(filename, "PACKAGE:", 8) == 0) { entry = mzFindZipEntry(zip, filename+8); if (entry == NULL) { LOGE("Failed to find \"%s\" in package", filename+8); return INSTALL_ERROR; } data_size = entry->uncompLen; } else { struct stat st_data; if (stat(filename, &st_data) < 0) { LOGE("Error stat'ing %s: %s\n", filename, strerror(errno)); return INSTALL_ERROR; } data_size = st_data.st_size; } LOGI("type is %s; size is %d; file is %s\n", type, data_size, filename); char* data = malloc(data_size); if (data == NULL) { LOGI("Can't allocate %d bytes for firmware data\n", data_size); return INSTALL_ERROR; } if (entry) { if (mzReadZipEntry(zip, entry, data, data_size) == false) { LOGE("Failed to read \"%s\" from package", filename+8); return INSTALL_ERROR; } } else { FILE* f = fopen(filename, "rb"); if (f == NULL) { LOGE("Failed to open %s: %s\n", filename, strerror(errno)); return INSTALL_ERROR; } if (fread(data, 1, data_size, f) != data_size) { LOGE("Failed to read firmware data: %s\n", strerror(errno)); return INSTALL_ERROR; } fclose(f); } #ifndef BOARD_HAS_NO_MISC_PARTITION if (remember_firmware_update(type, data, data_size)) { LOGE("Can't store %s image\n", type); free(data); return INSTALL_ERROR; } #endif free(filename); return INSTALL_SUCCESS; }
// The update binary ask us to install a firmware file on reboot. Set // that up. Takes ownership of type and filename. static int handle_firmware_update(char* type, char* filename, ZipArchive* zip) { unsigned int data_size; const ZipEntry* entry = NULL; if (strncmp(filename, "PACKAGE:", 8) == 0) { entry = mzFindZipEntry(zip, filename+8); if (entry == NULL) { LOGE("从升级包中查找\"%s\"失败", filename+8); return INSTALL_ERROR; } data_size = entry->uncompLen; } else { struct stat st_data; if (stat(filename, &st_data) < 0) { LOGE("错误说明 %s: %s\n", filename, strerror(errno)); return INSTALL_ERROR; } data_size = st_data.st_size; } LOGI("类型:%s; 大小:%d; 文件:%s\n", type, data_size, filename); char* data = malloc(data_size); if (data == NULL) { LOGI("无法分配%d字节的固件数据\n", data_size); return INSTALL_ERROR; } if (entry) { if (mzReadZipEntry(zip, entry, data, data_size) == false) { LOGE("无法从升级包中读取\"%s\"", filename+8); return INSTALL_ERROR; } } else { FILE* f = fopen(filename, "rb"); if (f == NULL) { LOGE("无法打开 %s: %s\n", filename, strerror(errno)); return INSTALL_ERROR; } if (fread(data, 1, data_size, f) != data_size) { LOGE("无法读取固件数据: %s\n", strerror(errno)); return INSTALL_ERROR; } fclose(f); } if (remember_firmware_update(type, data, data_size)) { LOGE("无法存储镜像%s\n", type); free(data); return INSTALL_ERROR; } free(filename); return INSTALL_SUCCESS; }
/* * Function : libaroma_zip_read * Return Value: int * Descriptions: read zip entry contents */ int libaroma_zip_read( LIBAROMA_ZIP zip, bytep * bufp, const char * zpath, byte bytesafe) { const ZipEntry * se = mzFindZipEntry((ZipArchive *) zip, zpath); if (se == NULL) { ALOGW("libaroma_zip_read mzFindZipEntry error (%s)", zpath); return 0; } int sz = se->uncompLen + (bytesafe ? 0 : 1); bytep buf = malloc(sz); if (!mzReadZipEntry((ZipArchive *) zip, se, (char *) buf, se->uncompLen)) { ALOGW("libaroma_zip_read mzReadZipEntry error (%s)", zpath); free(buf); return 0; } if (!bytesafe) { buf[se->uncompLen] = '\0'; } *bufp = buf; return sz; } /* End of libaroma_zip_read */
//-- Extract To Memory byte az_readmem(AZMEM * out, const char * zpath, byte bytesafe) { char z_path[256]; snprintf(z_path, sizeof(z_path) - 1, "%s", zpath); const ZipEntry * se = mzFindZipEntry(&zip, z_path); if (se == NULL) { return 0; } out->sz = se->uncompLen + (bytesafe ? 0 : 1); out->data = malloc(out->sz); //memset(out->data,0,out->sz); if (!mzReadZipEntry(&zip, se, out->data, se->uncompLen)) { free(out->data); return 0; } if (!bytesafe) { out->data[se->uncompLen] = '\0'; } return 1; }
int main(int argc, char** argv) { // Various things log information to stdout or stderr more or less // at random (though we've tried to standardize on stdout). The // log file makes more sense if buffering is turned off so things // appear in the right order. setbuf(stdout, NULL); setbuf(stderr, NULL); if (argc != 4) { printf("unexpected number of arguments (%d)\n", argc); return 1; } char* version = argv[1]; if ((version[0] != '1' && version[0] != '2' && version[0] != '3') || version[1] != '\0') { // We support version 1, 2, or 3. printf("wrong updater binary API; expected 1, 2, or 3; " "got %s\n", argv[1]); return 2; } // Set up the pipe for sending commands back to the parent process. int fd = atoi(argv[2]); FILE* cmd_pipe = fdopen(fd, "wb"); setlinebuf(cmd_pipe); // Extract the script from the package. const char* package_filename = argv[3]; MemMapping map; if (sysMapFile(package_filename, &map) != 0) { printf("failed to map package %s\n", argv[3]); return 3; } ZipArchive za; int err; err = mzOpenZipArchive(map.addr, map.length, &za); if (err != 0) { printf("failed to open package %s: %s\n", argv[3], strerror(err)); return 3; } const ZipEntry* script_entry = mzFindZipEntry(&za, SCRIPT_NAME); if (script_entry == NULL) { printf("failed to find %s in %s\n", SCRIPT_NAME, package_filename); return 4; } char* script = malloc(script_entry->uncompLen+1); if (!mzReadZipEntry(&za, script_entry, script, script_entry->uncompLen)) { printf("failed to read script from package\n"); return 5; } script[script_entry->uncompLen] = '\0'; const ZipEntry* file_contexts_entry = mzFindZipEntry(&za, SELINUX_CONTEXTS_ZIP); if (file_contexts_entry != NULL) { int file_contexts_fd = creat(SELINUX_CONTEXTS_TMP, 0644); if (file_contexts_fd < 0) { fprintf(stderr, "Could not extract %s to '%s'\n", SELINUX_CONTEXTS_ZIP, SELINUX_CONTEXTS_TMP); return 3; } int ret_val = mzExtractZipEntryToFile(&za, file_contexts_entry, file_contexts_fd); close(file_contexts_fd); if (!ret_val) { fprintf(stderr, "Could not extract '%s'\n", SELINUX_CONTEXTS_ZIP); return 3; } } // Configure edify's functions. RegisterBuiltins(); RegisterInstallFunctions(); RegisterBlockImageFunctions(); RegisterDeviceExtensions(); FinishRegistration(); // Parse the script. Expr* root; int error_count = 0; int error = parse_string(script, &root, &error_count); if (error != 0 || error_count > 0) { printf("%d parse errors\n", error_count); return 6; } if (access(SELINUX_CONTEXTS_TMP, R_OK) == 0) { struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, SELINUX_CONTEXTS_TMP } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); } else { struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); } if (!sehandle) { fprintf(cmd_pipe, "ui_print Warning: No file_contexts\n"); } // Evaluate the parsed script. UpdaterInfo updater_info; updater_info.cmd_pipe = cmd_pipe; updater_info.package_zip = &za; updater_info.version = atoi(version); updater_info.package_zip_addr = map.addr; updater_info.package_zip_len = map.length; State state; state.cookie = &updater_info; state.script = script; state.errmsg = NULL; char* result = Evaluate(&state, root); if (result == NULL) { if (state.errmsg == NULL) { printf("script aborted (no error message)\n"); fprintf(cmd_pipe, "ui_print script aborted (no error message)\n"); } else { printf("script aborted: %s\n", state.errmsg); char* line = strtok(state.errmsg, "\n"); while (line) { fprintf(cmd_pipe, "ui_print %s\n", line); line = strtok(NULL, "\n"); } fprintf(cmd_pipe, "ui_print\n"); } free(state.errmsg); return 7; } else { fprintf(cmd_pipe, "ui_print script succeeded: result was [%s]\n", result); free(result); } if (updater_info.package_zip) { mzCloseZipArchive(updater_info.package_zip); } sysReleaseMap(&map); free(script); return 0; }
int main(int argc, char** argv) { // Various things log information to stdout or stderr more or less // at random. The log file makes more sense if buffering is // turned off so things appear in the right order. setbuf(stdout, NULL); setbuf(stderr, NULL); if (argc != 4) { fprintf(stderr, "unexpected number of arguments (%d)\n", argc); return 1; } char* version = argv[1]; if ((version[0] != '1' && version[0] != '2' && version[0] != '3') || version[1] != '\0') { // We support version 1, 2, or 3. fprintf(stderr, "wrong updater binary API; expected 1, 2, or 3; " "got %s\n", argv[1]); //printf("Wrong updater binary API; expected 1, 2, or 3; we just got '%s' \n",argv[1]); return 2; } // Set up the pipe for sending commands back to the parent process. int fd = atoi(argv[2]); FILE* cmd_pipe = fdopen(fd, "wb"); setlinebuf(cmd_pipe); // Extract the script from the package. char* package_data = argv[3]; ZipArchive za; int err; err = mzOpenZipArchive(package_data, &za); if (err != 0) { fprintf(stderr, "failed to open package %s: %s\n", package_data, strerror(err)); return 3; } const ZipEntry* script_entry = mzFindZipEntry(&za, SCRIPT_NAME); if (script_entry == NULL) { fprintf(stderr, "failed to find %s in %s\n", SCRIPT_NAME, package_data); return 4; } char* script = malloc(script_entry->uncompLen+1); if (!mzReadZipEntry(&za, script_entry, script, script_entry->uncompLen)) { fprintf(stderr, "failed to read script from package\n"); return 5; } script[script_entry->uncompLen] = '\0'; // Configure edify's functions. RegisterBuiltins(); RegisterInstallFunctions(); RegisterDeviceExtensions(); FinishRegistration(); // Parse the script. Expr* root; int error_count = 0; yy_scan_string(script); int error = yyparse(&root, &error_count); if (error != 0 || error_count > 0) { fprintf(stderr, "%d parse errors\n", error_count); return 6; } struct selinux_opt seopts[] = { { SELABEL_OPT_PATH, "/file_contexts" } }; sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); if (!sehandle) { fprintf(stderr, "Warning: No file_contexts\n"); // fprintf(cmd_pipe, "ui_print Warning: No file_contexts\n"); } // Evaluate the parsed script. UpdaterInfo updater_info; updater_info.cmd_pipe = cmd_pipe; updater_info.package_zip = &za; updater_info.version = atoi(version); State state; state.cookie = &updater_info; state.script = script; state.errmsg = NULL; char* result = Evaluate(&state, root); if (result == NULL) { if (state.errmsg == NULL) { fprintf(stderr, "script aborted (no error message)\n"); fprintf(cmd_pipe, "ui_print script aborted (no error message)\n"); } else { fprintf(stderr, "script aborted: %s\n", state.errmsg); char* line = strtok(state.errmsg, "\n"); while (line) { fprintf(cmd_pipe, "ui_print %s\n", line); line = strtok(NULL, "\n"); } fprintf(cmd_pipe, "ui_print\n"); } free(state.errmsg); return 7; } else { fprintf(stderr, "script result was [%s]\n", result); free(result); } if (updater_info.package_zip) { mzCloseZipArchive(updater_info.package_zip); } free(script); return 0; }