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