1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci#include <errno.h> 16d9f0492fSopenharmony_ci#include <limits.h> 17d9f0492fSopenharmony_ci#include <stdlib.h> 18d9f0492fSopenharmony_ci#include <sys/mount.h> 19d9f0492fSopenharmony_ci 20d9f0492fSopenharmony_ci#include "reboot_adp.h" 21d9f0492fSopenharmony_ci#include "fs_manager/fs_manager.h" 22d9f0492fSopenharmony_ci#include "init_utils.h" 23d9f0492fSopenharmony_ci#include "securec.h" 24d9f0492fSopenharmony_ci 25d9f0492fSopenharmony_ci#define MAX_COMMAND_SIZE 32 26d9f0492fSopenharmony_ci#define MAX_UPDATE_SIZE 1280 27d9f0492fSopenharmony_ci#define MAX_RESERVED_SIZE 736 28d9f0492fSopenharmony_ci 29d9f0492fSopenharmony_cistruct RBMiscUpdateMessage { 30d9f0492fSopenharmony_ci char command[MAX_COMMAND_SIZE]; 31d9f0492fSopenharmony_ci char update[MAX_UPDATE_SIZE]; 32d9f0492fSopenharmony_ci char reserved[MAX_RESERVED_SIZE]; 33d9f0492fSopenharmony_ci}; 34d9f0492fSopenharmony_ci 35d9f0492fSopenharmony_cistatic int RBMiscWriteUpdaterMessage(const char *path, const struct RBMiscUpdateMessage *boot) 36d9f0492fSopenharmony_ci{ 37d9f0492fSopenharmony_ci char *realPath = GetRealPath(path); 38d9f0492fSopenharmony_ci BEGET_CHECK_RETURN_VALUE(realPath != NULL, -1); 39d9f0492fSopenharmony_ci int ret = -1; 40d9f0492fSopenharmony_ci FILE *fp = fopen(realPath, "rb+"); 41d9f0492fSopenharmony_ci free(realPath); 42d9f0492fSopenharmony_ci realPath = NULL; 43d9f0492fSopenharmony_ci if (fp != NULL) { 44d9f0492fSopenharmony_ci size_t writeLen = fwrite(boot, sizeof(struct RBMiscUpdateMessage), 1, fp); 45d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(writeLen == 1, ret = -1, "Failed to write misc for reboot"); 46d9f0492fSopenharmony_ci (void)fclose(fp); 47d9f0492fSopenharmony_ci ret = 0; 48d9f0492fSopenharmony_ci } 49d9f0492fSopenharmony_ci return ret; 50d9f0492fSopenharmony_ci} 51d9f0492fSopenharmony_ci 52d9f0492fSopenharmony_cistatic int RBMiscReadUpdaterMessage(const char *path, struct RBMiscUpdateMessage *boot) 53d9f0492fSopenharmony_ci{ 54d9f0492fSopenharmony_ci int ret = -1; 55d9f0492fSopenharmony_ci FILE *fp = NULL; 56d9f0492fSopenharmony_ci char *realPath = GetRealPath(path); 57d9f0492fSopenharmony_ci if (realPath != NULL) { 58d9f0492fSopenharmony_ci fp = fopen(realPath, "rb"); 59d9f0492fSopenharmony_ci free(realPath); 60d9f0492fSopenharmony_ci realPath = NULL; 61d9f0492fSopenharmony_ci } else { 62d9f0492fSopenharmony_ci fp = fopen(path, "rb"); 63d9f0492fSopenharmony_ci } 64d9f0492fSopenharmony_ci if (fp != NULL) { 65d9f0492fSopenharmony_ci size_t readLen = fread(boot, 1, sizeof(struct RBMiscUpdateMessage), fp); 66d9f0492fSopenharmony_ci (void)fclose(fp); 67d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(readLen > 0, ret = -1, "Failed to read misc for reboot"); 68d9f0492fSopenharmony_ci ret = 0; 69d9f0492fSopenharmony_ci } 70d9f0492fSopenharmony_ci return ret; 71d9f0492fSopenharmony_ci} 72d9f0492fSopenharmony_ci 73d9f0492fSopenharmony_ciint GetRebootReasonFromMisc(char *reason, size_t size) 74d9f0492fSopenharmony_ci{ 75d9f0492fSopenharmony_ci char miscFile[PATH_MAX] = {0}; 76d9f0492fSopenharmony_ci int ret = GetBlockDevicePath("/misc", miscFile, PATH_MAX); 77d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to get misc path"); 78d9f0492fSopenharmony_ci struct RBMiscUpdateMessage msg; 79d9f0492fSopenharmony_ci ret = RBMiscReadUpdaterMessage(miscFile, &msg); 80d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to get misc info"); 81d9f0492fSopenharmony_ci return strcpy_s(reason, size, msg.command); 82d9f0492fSopenharmony_ci} 83d9f0492fSopenharmony_ci 84d9f0492fSopenharmony_ciint UpdateMiscMessage(const char *valueData, const char *cmd, const char *cmdExt, const char *boot) 85d9f0492fSopenharmony_ci{ 86d9f0492fSopenharmony_ci char miscFile[PATH_MAX] = {0}; 87d9f0492fSopenharmony_ci int ret = GetBlockDevicePath("/misc", miscFile, PATH_MAX); 88d9f0492fSopenharmony_ci // no misc do not updater, so return ok 89d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, return 0, "Failed to get misc path for %s.", valueData); 90d9f0492fSopenharmony_ci 91d9f0492fSopenharmony_ci // "updater" or "updater:" 92d9f0492fSopenharmony_ci struct RBMiscUpdateMessage msg; 93d9f0492fSopenharmony_ci ret = RBMiscReadUpdaterMessage(miscFile, &msg); 94d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to get misc info for %s.", cmd); 95d9f0492fSopenharmony_ci 96d9f0492fSopenharmony_ci if (boot != NULL) { 97d9f0492fSopenharmony_ci ret = snprintf_s(msg.command, MAX_COMMAND_SIZE, MAX_COMMAND_SIZE - 1, "%s", boot); 98d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret > 0, return -1, "Failed to format cmd for %s.", cmd); 99d9f0492fSopenharmony_ci msg.command[MAX_COMMAND_SIZE - 1] = 0; 100d9f0492fSopenharmony_ci } else { 101d9f0492fSopenharmony_ci ret = memset_s(msg.command, MAX_COMMAND_SIZE, 0, MAX_COMMAND_SIZE); 102d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to format cmd for %s.", cmd); 103d9f0492fSopenharmony_ci } 104d9f0492fSopenharmony_ci 105d9f0492fSopenharmony_ci if (strncmp(cmd, "updater", strlen("updater")) != 0) { 106d9f0492fSopenharmony_ci if ((cmdExt != NULL) && (valueData != NULL) && (strncmp(valueData, cmdExt, strlen(cmdExt)) == 0)) { 107d9f0492fSopenharmony_ci const char *p = valueData + strlen(cmdExt); 108d9f0492fSopenharmony_ci ret = snprintf_s(msg.update, MAX_UPDATE_SIZE, MAX_UPDATE_SIZE - 1, "%s", p); 109d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret > 0, return -1, "Failed to format param for %s.", cmd); 110d9f0492fSopenharmony_ci msg.update[MAX_UPDATE_SIZE - 1] = 0; 111d9f0492fSopenharmony_ci } else { 112d9f0492fSopenharmony_ci ret = memset_s(msg.update, MAX_UPDATE_SIZE, 0, MAX_UPDATE_SIZE); 113d9f0492fSopenharmony_ci BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to format update for %s.", cmd); 114d9f0492fSopenharmony_ci } 115d9f0492fSopenharmony_ci } 116d9f0492fSopenharmony_ci 117d9f0492fSopenharmony_ci if (RBMiscWriteUpdaterMessage(miscFile, &msg) == 0) { 118d9f0492fSopenharmony_ci return 0; 119d9f0492fSopenharmony_ci } 120d9f0492fSopenharmony_ci return -1; 121d9f0492fSopenharmony_ci} 122