• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 struct RBMiscUpdateMessage {
30     char command[MAX_COMMAND_SIZE];
31     char update[MAX_UPDATE_SIZE];
32     char reserved[MAX_RESERVED_SIZE];
33 };
34 
RBMiscWriteUpdaterMessage(const char * path,const struct RBMiscUpdateMessage * boot)35 static 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 
RBMiscReadUpdaterMessage(const char * path,struct RBMiscUpdateMessage * boot)52 static 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 
GetRebootReasonFromMisc(char * reason,size_t size)73 int 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 
UpdateMiscMessage(const char * valueData,const char * cmd,const char * cmdExt,const char * boot)84 int 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