1 /*
2  * Copyright (c) 2020-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 #include "init_jobs_internal.h"
16 
17 #include <string.h>
18 #include <unistd.h>
19 
20 #include "init_cmds.h"
21 #include "init_log.h"
22 #include "securec.h"
23 
24 #define JOBS_ARR_NAME_IN_JSON "jobs"
25 #define CMDS_ARR_NAME_IN_JSON "cmds"
26 #define MAX_JOBS_COUNT 100
27 
28 static Job *g_jobs = NULL;
29 static int g_jobCnt = 0;
30 
DumpAllJobs(void)31 void DumpAllJobs(void)
32 {
33     INIT_LOGV("Start to dump all jobs...");
34     for (int i = 0; i < g_jobCnt; i++) {
35         INIT_LOGV("\tjob name: %s", g_jobs[i].name);
36         if (g_jobs[i].cmdLines == NULL) {
37             continue;
38         }
39         INIT_LOGV("\tlist all commands:");
40         for (int j = 0; j < g_jobs[i].cmdLines->cmdNum; j++) {
41             CmdLine *cmd = &g_jobs[i].cmdLines->cmds[j];
42             INIT_LOGV("\t\tcommand: %s %s", GetCmdKey(cmd->cmdIndex), cmd->cmdContent);
43         }
44     }
45     INIT_LOGV("Finish dump all jobs");
46 }
47 
GetJobName(const cJSON * jobItem,Job * resJob)48 static int GetJobName(const cJSON *jobItem, Job *resJob)
49 {
50     char *jobNameStr = cJSON_GetStringValue(cJSON_GetObjectItem(jobItem, "name"));
51     if (jobNameStr == NULL) {
52         return 0;
53     }
54 
55     if (strcpy_s(resJob->name, MAX_JOB_NAME_LEN, jobNameStr) != EOK) {
56         INIT_LOGE("Get job name \"%s\" failed", jobNameStr);
57         return 0;
58     }
59     resJob->name[strlen(jobNameStr)] = '\0';
60     return 1;
61 }
62 
ParseJob(const cJSON * jobItem,Job * resJob)63 static void ParseJob(const cJSON *jobItem, Job *resJob)
64 {
65     if (!GetJobName(jobItem, resJob)) {
66         INIT_LOGE("get JobName failed");
67         (void)memset_s(resJob, sizeof(*resJob), 0, sizeof(*resJob));
68         return;
69     }
70 
71     cJSON *cmdsItem = cJSON_GetObjectItem(jobItem, CMDS_ARR_NAME_IN_JSON);
72     if (!cJSON_IsArray(cmdsItem)) {
73         INIT_LOGE("job %s is not an array", resJob->name);
74         return;
75     }
76     int ret = GetCmdLinesFromJson(cmdsItem, &resJob->cmdLines);
77     if (ret != 0) {
78         INIT_LOGE("ParseJob, failed to get cmds for job!");
79         return;
80     }
81     return;
82 }
83 
ParseAllJobs(const cJSON * fileRoot,const ConfigContext * context)84 void ParseAllJobs(const cJSON *fileRoot, const ConfigContext *context)
85 {
86     if (fileRoot == NULL) {
87         INIT_LOGE("ParseAllJobs, input fileRoot is NULL!");
88         return;
89     }
90 
91     cJSON *jobArr = cJSON_GetObjectItemCaseSensitive(fileRoot, JOBS_ARR_NAME_IN_JSON);
92     if (!cJSON_IsArray(jobArr)) {
93         INIT_LOGE("ParseAllJobs, job item is not array!");
94         return;
95     }
96 
97     int jobArrSize = cJSON_GetArraySize(jobArr);
98     if (jobArrSize <= 0 || jobArrSize > MAX_JOBS_COUNT) {
99         INIT_LOGE("ParseAllJobs, jobs count %d is invalid, should be positive and not exceeding %d.",
100             jobArrSize, MAX_JOBS_COUNT);
101         return;
102     }
103 
104     Job *retJobs = (Job *)realloc(g_jobs, sizeof(Job) * (g_jobCnt + jobArrSize));
105     if (retJobs == NULL) {
106         INIT_LOGE("ParseAllJobs, malloc failed! job arrSize %d.", jobArrSize);
107         return;
108     }
109 
110     Job *tmp = retJobs + g_jobCnt;
111     if (memset_s(tmp, sizeof(Job) * jobArrSize, 0, sizeof(Job) * jobArrSize) != EOK) {
112         INIT_LOGE("ParseAllJobs, memset_s failed.");
113         free(retJobs);
114         retJobs = NULL;
115         return;
116     }
117 
118     for (int i = 0; i < jobArrSize; ++i) {
119         cJSON *jobItem = cJSON_GetArrayItem(jobArr, i);
120         ParseJob(jobItem, &(tmp[i]));
121     }
122     g_jobs = retJobs;
123     g_jobCnt += jobArrSize;
124 }
125 
DoJob(const char * jobName)126 void DoJob(const char *jobName)
127 {
128     if (jobName == NULL) {
129         INIT_LOGE("DoJob, input jobName NULL!");
130         return;
131     }
132 
133     INIT_LOGV("Call job with name %s", jobName);
134     for (int i = 0; i < g_jobCnt; ++i) {
135         if (strncmp(jobName, g_jobs[i].name, strlen(g_jobs[i].name)) == 0) {
136             CmdLines *cmdLines = g_jobs[i].cmdLines;
137             if (cmdLines == NULL) {
138                 continue;
139             }
140             for (int j = 0; j < cmdLines->cmdNum; ++j) {
141                 DoCmdByIndex(cmdLines->cmds[j].cmdIndex, cmdLines->cmds[j].cmdContent, NULL);
142             }
143         }
144     }
145 }
146 
ReleaseAllJobs(void)147 void ReleaseAllJobs(void)
148 {
149     if (g_jobs == NULL) {
150         return;
151     }
152 
153     for (int i = 0; i < g_jobCnt; ++i) {
154         if (g_jobs[i].cmdLines != NULL) {
155             free(g_jobs[i].cmdLines);
156         }
157     }
158 
159     free(g_jobs);
160     g_jobs = NULL;
161     g_jobCnt = 0;
162 }
163 
DoJobNow(const char * jobName)164 int DoJobNow(const char *jobName)
165 {
166     return 0;
167 }
168