• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #include "cJSON.h"
17 #include "init_param.h"
18 #include "init_utils.h"
19 #include "init_log.h"
20 #include "init_group_manager.h"
21 #include "init_service_manager.h"
22 #include "securec.h"
23 #include "modulemgr.h"
24 #include "init_module_engine.h"
25 
26 #define MAX_CMD_ARGC 10
27 static int g_cmdExecutorId = 0;
28 static int g_cmdId = 0;
AddCmdExecutor_(const char * cmdName,CmdExecutor execCmd,int careContext)29 int AddCmdExecutor_(const char *cmdName, CmdExecutor execCmd, int careContext)
30 {
31     INIT_ERROR_CHECK(cmdName != NULL, return -1, "Invalid input param");
32     INIT_LOGV("Add command '%s' executor.", cmdName);
33     PluginCmd *cmd = NULL;
34     InitGroupNode *groupNode = GetGroupNode(NODE_TYPE_CMDS, cmdName);
35     if (groupNode == NULL) {
36         groupNode = AddGroupNode(NODE_TYPE_CMDS, cmdName);
37         INIT_ERROR_CHECK(groupNode != NULL, return -1, "Failed to create group node");
38     }
39     cmd = groupNode->data.cmd;
40     if (cmd == NULL) {
41         cmd = (PluginCmd *)calloc(1, sizeof(PluginCmd));
42         INIT_ERROR_CHECK(cmd != NULL, return -1, "Failed to create cmd condition");
43         groupNode->data.cmd = cmd;
44         cmd->cmdId = g_cmdId++;
45         cmd->name = groupNode->name;
46         cmd->careContext = careContext;
47         OH_ListInit(&cmd->cmdExecutor);
48     }
49     if (execCmd == NULL) {
50         return 0;
51     }
52     PluginCmdExecutor *cmdExec = (PluginCmdExecutor *)calloc(1, sizeof(PluginCmdExecutor));
53     INIT_ERROR_CHECK(cmdExec != NULL, return -1, "Failed to create cmd listener");
54     OH_ListInit(&cmdExec->node);
55     cmdExec->id = ++g_cmdExecutorId;
56     cmdExec->execCmd = execCmd;
57     OH_ListAddTail(&cmd->cmdExecutor, &cmdExec->node);
58     return cmdExec->id;
59 }
60 
AddCareContextCmdExecutor(const char * cmdName,CmdExecutor execCmd)61 int AddCareContextCmdExecutor(const char *cmdName, CmdExecutor execCmd)
62 {
63     return AddCmdExecutor_(cmdName, execCmd, 1);
64 }
65 
AddCmdExecutor(const char * cmdName,CmdExecutor execCmd)66 int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd)
67 {
68     return AddCmdExecutor_(cmdName, execCmd, 0);
69 }
70 
RemoveCmdExecutor(const char * cmdName,int id)71 void RemoveCmdExecutor(const char *cmdName, int id)
72 {
73     INIT_ERROR_CHECK(cmdName != NULL, return, "Invalid input param");
74     InitGroupNode *groupNode = GetGroupNode(NODE_TYPE_CMDS, cmdName);
75     INIT_ERROR_CHECK(groupNode != NULL && groupNode->data.cmd != NULL,
76         return, "Can not find cmd %s", cmdName);
77 
78     PluginCmd *cmd = groupNode->data.cmd;
79     ListNode *node = cmd->cmdExecutor.next;
80     while (node != &cmd->cmdExecutor) {
81         PluginCmdExecutor *cmdExec = ListEntry(node, PluginCmdExecutor, node);
82         if (cmdExec->id == id) {
83             OH_ListRemove(&cmdExec->node);
84             free(cmdExec);
85             break;
86         }
87         node = node->next;
88     }
89     if (cmd->cmdExecutor.next != &cmd->cmdExecutor) {
90         return;
91     }
92     DelGroupNode(NODE_TYPE_CMDS, cmdName);
93     free(cmd);
94 }
95 
PluginExecCmd_(PluginCmd * cmd,const char * cmdContent)96 static void PluginExecCmd_(PluginCmd *cmd, const char *cmdContent)
97 {
98     const struct CmdArgs *ctx = GetCmdArg(cmdContent, " ", MAX_CMD_ARGC);
99     if (ctx == NULL) {
100         INIT_LOGE("Invalid arguments cmd: %s content: %s", cmd->name, cmdContent);
101         return;
102     } else if (ctx->argc > MAX_CMD_ARGC) {
103         INIT_LOGE("Invalid arguments cmd: %s content: %s argc: %d ",
104             cmd->name, cmdContent, ctx->argc);
105         FreeCmdArg((struct CmdArgs *)ctx);
106         return;
107     }
108     INIT_LOGV("PluginExecCmd_ index %s content: %s", cmd->name, cmdContent);
109     ListNode *node = cmd->cmdExecutor.next;
110     while (node != &cmd->cmdExecutor) {
111         PluginCmdExecutor *cmdExec = ListEntry(node, PluginCmdExecutor, node);
112         cmdExec->execCmd(cmdExec->id, cmd->name, ctx->argc, (const char **)ctx->argv);
113         node = node->next;
114     }
115     FreeCmdArg((struct CmdArgs *)ctx);
116 }
117 
PluginExecCmdByName(const char * name,const char * cmdContent)118 void PluginExecCmdByName(const char *name, const char *cmdContent)
119 {
120     INIT_ERROR_CHECK(name != NULL, return, "Invalid cmd for %s", cmdContent);
121     InitGroupNode *groupNode = GetGroupNode(NODE_TYPE_CMDS, name);
122     if (groupNode == NULL || groupNode->data.cmd == NULL) {
123         return;
124     }
125     PluginCmd *cmd = groupNode->data.cmd;
126     PluginExecCmd_(cmd, cmdContent);
127 }
128 
PluginExecCmd(const char * name,int argc,const char ** argv)129 int PluginExecCmd(const char *name, int argc, const char **argv)
130 {
131     INIT_ERROR_CHECK(name != NULL, return -1, "Invalid cmd ");
132     InitGroupNode *groupNode = GetGroupNode(NODE_TYPE_CMDS, name);
133     if (groupNode == NULL || groupNode->data.cmd == NULL) {
134         return -1;
135     }
136     PluginCmd *cmd = groupNode->data.cmd;
137     INIT_LOGV("PluginExecCmd index %s", cmd->name);
138     int ret = 0;
139     ListNode *node = cmd->cmdExecutor.next;
140     while (node != &cmd->cmdExecutor) {
141         PluginCmdExecutor *cmdExec = ListEntry(node, PluginCmdExecutor, node);
142         ret = cmdExec->execCmd(cmdExec->id, cmd->name, argc, argv);
143         node = node->next;
144     }
145     return ret;
146 }
147 
CompareCmdId(const HashNode * node,const void * key)148 static int CompareCmdId(const HashNode *node, const void *key)
149 {
150     InitGroupNode *groupNode = HASHMAP_ENTRY(node, InitGroupNode, hashNode);
151     if (groupNode == NULL || groupNode->data.cmd == NULL) {
152         return 1;
153     }
154     PluginCmd *cmd = groupNode->data.cmd;
155     return cmd->cmdId - *(int *)key;
156 }
157 
GetPluginCmdByIndex(int index)158 static PluginCmd *GetPluginCmdByIndex(int index)
159 {
160     int hashCode = (((unsigned int)index >> 16) & 0x0000ffff) - 1; // 16 left shift
161     int cmdId = ((unsigned int)index & 0x0000ffff);
162     HashNode *node = OH_HashMapFind(GetGroupHashMap(NODE_TYPE_CMDS),
163         hashCode, (const void *)&cmdId, CompareCmdId);
164     if (node == NULL) {
165         return NULL;
166     }
167     InitGroupNode *groupNode = HASHMAP_ENTRY(node, InitGroupNode, hashNode);
168     if (groupNode == NULL || groupNode->data.cmd == NULL) {
169         return NULL;
170     }
171     return groupNode->data.cmd;
172 }
173 
GetPluginCmdNameByIndex(int index)174 const char *GetPluginCmdNameByIndex(int index)
175 {
176     PluginCmd *cmd = GetPluginCmdByIndex(index);
177     if (cmd == NULL) {
178         return NULL;
179     }
180     return cmd->name;
181 }
182 
PluginExecCmdByCmdIndex(int index,const char * cmdContent,const ConfigContext * context)183 void PluginExecCmdByCmdIndex(int index, const char *cmdContent, const ConfigContext *context)
184 {
185     PluginCmd *cmd = GetPluginCmdByIndex(index);
186     if (cmd == NULL) {
187         INIT_LOGW("Cannot find plugin command with index %d", index);
188         return;
189     }
190     INIT_LOGV("Command: %s cmdContent: %s %d", cmd->name, cmdContent, cmd->careContext);
191     if (!cmd->careContext || !CheckExecuteInSubInit(context)) {
192         PluginExecCmd_(cmd, cmdContent);
193     } else {
194         ExecuteCmdInSubInit(context, cmd->name, cmdContent);
195     }
196 }
197 
PluginGetCmdIndex(const char * cmdStr,int * index)198 const char *PluginGetCmdIndex(const char *cmdStr, int *index)
199 {
200     char cmdName[MAX_CMD_NAME_LEN] = {};
201     int i = 0;
202     while ((i < MAX_CMD_NAME_LEN) && (*(cmdStr + i) != '\0') && (*(cmdStr + i) != ' ')) {
203         cmdName[i] = *(cmdStr + i);
204         i++;
205     }
206     if (i >= MAX_CMD_NAME_LEN) {
207         return NULL;
208     }
209     cmdName[i] = '\0';
210     InitGroupNode *groupNode = GetGroupNode(NODE_TYPE_CMDS, cmdName);
211     if (groupNode == NULL || groupNode->data.cmd == NULL) {
212         AddCmdExecutor(cmdName, NULL);
213     }
214     groupNode = GetGroupNode(NODE_TYPE_CMDS, cmdName);
215     INIT_ERROR_CHECK(groupNode != NULL && groupNode->data.cmd != NULL,
216         return NULL, "Failed to create pluginCmd %s", cmdName);
217 
218     PluginCmd *cmd = groupNode->data.cmd;
219     int hashCode = GenerateHashCode(cmdName);
220     hashCode = (hashCode < 0) ? -hashCode : hashCode;
221     hashCode = hashCode % GROUP_HASHMAP_BUCKET;
222     *index = ((hashCode + 1) << 16) | cmd->cmdId; // 16 left shift
223     return cmd->name;
224 }
225