• 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)29 int AddCmdExecutor(const char *cmdName, CmdExecutor execCmd)
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         OH_ListInit(&cmd->cmdExecutor);
47     }
48     if (execCmd == NULL) {
49         return 0;
50     }
51     PluginCmdExecutor *cmdExec = (PluginCmdExecutor *)calloc(1, sizeof(PluginCmdExecutor));
52     INIT_ERROR_CHECK(cmdExec != NULL, return -1, "Failed to create cmd listener");
53     OH_ListInit(&cmdExec->node);
54     cmdExec->id = ++g_cmdExecutorId;
55     cmdExec->execCmd = execCmd;
56     OH_ListAddTail(&cmd->cmdExecutor, &cmdExec->node);
57     return cmdExec->id;
58 }
59 
RemoveCmdExecutor(const char * cmdName,int id)60 void RemoveCmdExecutor(const char *cmdName, int id)
61 {
62     INIT_ERROR_CHECK(cmdName != NULL, return, "Invalid input param");
63     InitGroupNode *groupNode = GetGroupNode(NODE_TYPE_CMDS, cmdName);
64     INIT_ERROR_CHECK(groupNode != NULL && groupNode->data.cmd != NULL,
65         return, "Can not find cmd %s", cmdName);
66 
67     PluginCmd *cmd = groupNode->data.cmd;
68     ListNode *node = cmd->cmdExecutor.next;
69     while (node != &cmd->cmdExecutor) {
70         PluginCmdExecutor *cmdExec = ListEntry(node, PluginCmdExecutor, node);
71         if (cmdExec->id == id) {
72             OH_ListRemove(&cmdExec->node);
73             free(cmdExec);
74             break;
75         }
76         node = node->next;
77     }
78     if (cmd->cmdExecutor.next != &cmd->cmdExecutor) {
79         return;
80     }
81     DelGroupNode(NODE_TYPE_CMDS, cmdName);
82     free(cmd);
83 }
84 
PluginExecCmd_(PluginCmd * cmd,const char * cmdContent)85 void PluginExecCmd_(PluginCmd *cmd, const char *cmdContent)
86 {
87     const struct CmdArgs *ctx = GetCmdArg(cmdContent, " ", MAX_CMD_ARGC);
88     if (ctx == NULL) {
89         INIT_LOGE("Invalid arguments cmd: %s content: %s", cmd->name, cmdContent);
90         return;
91     } else if (ctx->argc > MAX_CMD_ARGC) {
92         INIT_LOGE("Invalid arguments cmd: %s content: %s argc: %d ",
93             cmd->name, cmdContent, ctx->argc);
94         FreeCmdArg((struct CmdArgs *)ctx);
95         return;
96     }
97     INIT_LOGV("PluginExecCmd_ index %s content: %s", cmd->name, cmdContent);
98     ListNode *node = cmd->cmdExecutor.next;
99     while (node != &cmd->cmdExecutor) {
100         PluginCmdExecutor *cmdExec = ListEntry(node, PluginCmdExecutor, node);
101         cmdExec->execCmd(cmdExec->id, cmd->name, ctx->argc, (const char **)ctx->argv);
102         node = node->next;
103     }
104     FreeCmdArg((struct CmdArgs *)ctx);
105 }
106 
PluginExecCmdByName(const char * name,const char * cmdContent)107 void PluginExecCmdByName(const char *name, const char *cmdContent)
108 {
109     INIT_ERROR_CHECK(name != NULL, return, "Invalid cmd for %s", cmdContent);
110     InitGroupNode *groupNode = GetGroupNode(NODE_TYPE_CMDS, name);
111     if (groupNode == NULL || groupNode->data.cmd == NULL) {
112         return;
113     }
114     PluginCmd *cmd = groupNode->data.cmd;
115     PluginExecCmd_(cmd, cmdContent);
116 }
117 
PluginExecCmd(const char * name,int argc,const char ** argv)118 int PluginExecCmd(const char *name, int argc, const char **argv)
119 {
120     INIT_ERROR_CHECK(name != NULL, return -1, "Invalid cmd ");
121     InitGroupNode *groupNode = GetGroupNode(NODE_TYPE_CMDS, name);
122     if (groupNode == NULL || groupNode->data.cmd == NULL) {
123         return -1;
124     }
125     PluginCmd *cmd = groupNode->data.cmd;
126     INIT_LOGV("PluginExecCmd index %s", cmd->name);
127     int ret = 0;
128     ListNode *node = cmd->cmdExecutor.next;
129     while (node != &cmd->cmdExecutor) {
130         PluginCmdExecutor *cmdExec = ListEntry(node, PluginCmdExecutor, node);
131         ret = cmdExec->execCmd(cmdExec->id, cmd->name, argc, argv);
132         node = node->next;
133     }
134     return ret;
135 }
136 
CompareCmdId(const HashNode * node,const void * key)137 static int CompareCmdId(const HashNode *node, const void *key)
138 {
139     InitGroupNode *groupNode = HASHMAP_ENTRY(node, InitGroupNode, hashNode);
140     if (groupNode == NULL || groupNode->data.cmd == NULL) {
141         return 1;
142     }
143     PluginCmd *cmd = groupNode->data.cmd;
144     return cmd->cmdId - *(int *)key;
145 }
146 
GetPluginCmdByIndex(int index)147 static PluginCmd *GetPluginCmdByIndex(int index)
148 {
149     int hashCode = (((unsigned int)index >> 16) & 0x0000ffff) - 1; // 16 left shift
150     int cmdId = ((unsigned int)index & 0x0000ffff);
151     HashNode *node = OH_HashMapFind(GetGroupHashMap(NODE_TYPE_CMDS),
152         hashCode, (const void *)&cmdId, CompareCmdId);
153     if (node == NULL) {
154         return NULL;
155     }
156     InitGroupNode *groupNode = HASHMAP_ENTRY(node, InitGroupNode, hashNode);
157     if (groupNode == NULL || groupNode->data.cmd == NULL) {
158         return NULL;
159     }
160     return groupNode->data.cmd;
161 }
162 
GetPluginCmdNameByIndex(int index)163 const char *GetPluginCmdNameByIndex(int index)
164 {
165     PluginCmd *cmd = GetPluginCmdByIndex(index);
166     if (cmd == NULL) {
167         return NULL;
168     }
169     return cmd->name;
170 }
171 
PluginExecCmdByCmdIndex(int index,const char * cmdContent)172 void PluginExecCmdByCmdIndex(int index, const char *cmdContent)
173 {
174     PluginCmd *cmd = GetPluginCmdByIndex(index);
175     if (cmd == NULL) {
176         INIT_LOGW("Cannot find plugin command with index %d", index);
177         return;
178     }
179     INIT_LOGV("Command: %s cmdContent: %s", cmd->name, cmdContent);
180     PluginExecCmd_(cmd, cmdContent);
181 }
182 
PluginGetCmdIndex(const char * cmdStr,int * index)183 const char *PluginGetCmdIndex(const char *cmdStr, int *index)
184 {
185     char cmdName[MAX_CMD_NAME_LEN] = {};
186     int i = 0;
187     while ((i < MAX_CMD_NAME_LEN) && (*(cmdStr + i) != '\0') && (*(cmdStr + i) != ' ')) {
188         cmdName[i] = *(cmdStr + i);
189         i++;
190     }
191     if (i >= MAX_CMD_NAME_LEN) {
192         return NULL;
193     }
194     cmdName[i] = '\0';
195     InitGroupNode *groupNode = GetGroupNode(NODE_TYPE_CMDS, cmdName);
196     if (groupNode == NULL || groupNode->data.cmd == NULL) {
197         AddCmdExecutor(cmdName, NULL);
198     }
199     groupNode = GetGroupNode(NODE_TYPE_CMDS, cmdName);
200     INIT_ERROR_CHECK(groupNode != NULL && groupNode->data.cmd != NULL,
201         return NULL, "Failed to create pluginCmd %s", cmdName);
202 
203     PluginCmd *cmd = groupNode->data.cmd;
204     int hashCode = GenerateHashCode(cmdName);
205     hashCode = (hashCode < 0) ? -hashCode : hashCode;
206     hashCode = hashCode % GROUP_HASHMAP_BUCKET;
207     *index = ((hashCode + 1) << 16) | cmd->cmdId; // 16 left shift
208     return cmd->name;
209 }
210