1d9f0492fSopenharmony_ci/*
2d9f0492fSopenharmony_ci* Copyright (c) 2022 Huawei Device Co., Ltd.
3d9f0492fSopenharmony_ci* Licensed under the Apache License, Version 2.0 (the "License");
4d9f0492fSopenharmony_ci* you may not use this file except in compliance with the License.
5d9f0492fSopenharmony_ci* You may obtain a copy of the License at
6d9f0492fSopenharmony_ci*
7d9f0492fSopenharmony_ci*     http://www.apache.org/licenses/LICENSE-2.0
8d9f0492fSopenharmony_ci*
9d9f0492fSopenharmony_ci* Unless required by applicable law or agreed to in writing, software
10d9f0492fSopenharmony_ci* distributed under the License is distributed on an "AS IS" BASIS,
11d9f0492fSopenharmony_ci* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d9f0492fSopenharmony_ci* See the License for the specific language governing permissions and
13d9f0492fSopenharmony_ci* limitations under the License.
14d9f0492fSopenharmony_ci*/
15d9f0492fSopenharmony_ci#include <errno.h>
16d9f0492fSopenharmony_ci#include <stdio.h>
17d9f0492fSopenharmony_ci#include <stdlib.h>
18d9f0492fSopenharmony_ci#include <grp.h>
19d9f0492fSopenharmony_ci#include <pwd.h>
20d9f0492fSopenharmony_ci#include <dirent.h>
21d9f0492fSopenharmony_ci
22d9f0492fSopenharmony_ci#include "begetctl.h"
23d9f0492fSopenharmony_ci#include "init_utils.h"
24d9f0492fSopenharmony_ci#include "init_param.h"
25d9f0492fSopenharmony_ci#include "securec.h"
26d9f0492fSopenharmony_ci#include "shell_utils.h"
27d9f0492fSopenharmony_ci#include "parameter.h"
28d9f0492fSopenharmony_ci
29d9f0492fSopenharmony_ci#define BEGETCTRL_INIT_CMD "ohos.servicectrl.cmd"
30d9f0492fSopenharmony_ci
31d9f0492fSopenharmony_ci/**
32d9f0492fSopenharmony_ci * @brief 通用的命令通道,注册函数完成参数校验,调用HandleCmd进行处理
33d9f0492fSopenharmony_ci * init进程使用 initCmd 按命令字进行处理
34d9f0492fSopenharmony_ci */
35d9f0492fSopenharmony_cistatic int HandleCmd(BShellHandle shell, const char *cmdName, int argc, char **argv)
36d9f0492fSopenharmony_ci{
37d9f0492fSopenharmony_ci    BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
38d9f0492fSopenharmony_ci    BSH_LOGI("initCmd %s argc %d", cmdName, argc);
39d9f0492fSopenharmony_ci    // format args
40d9f0492fSopenharmony_ci    if (argc == 0) {
41d9f0492fSopenharmony_ci        return SystemSetParameter(BEGETCTRL_INIT_CMD, cmdName);
42d9f0492fSopenharmony_ci    }
43d9f0492fSopenharmony_ci    char value[PARAM_VALUE_LEN_MAX] = { 0 };
44d9f0492fSopenharmony_ci    int ret = sprintf_s(value, sizeof(value) - 1, "%s ", cmdName);
45d9f0492fSopenharmony_ci    BSH_CHECK(ret > 0, return BSH_INVALID_PARAM, "Failed to format cmdName");
46d9f0492fSopenharmony_ci    for (int i = 0; i < argc; i++) {
47d9f0492fSopenharmony_ci        ret = strcat_s(value, sizeof(value), argv[i]);
48d9f0492fSopenharmony_ci        BSH_CHECK(ret == 0, return BSH_INVALID_PARAM, "Failed to format name");
49d9f0492fSopenharmony_ci        ret = strcat_s(value, sizeof(value), " ");
50d9f0492fSopenharmony_ci        BSH_CHECK(ret == 0, return BSH_INVALID_PARAM, "Failed to format name");
51d9f0492fSopenharmony_ci    }
52d9f0492fSopenharmony_ci    return SystemSetParameter(BEGETCTRL_INIT_CMD, value);
53d9f0492fSopenharmony_ci}
54d9f0492fSopenharmony_ci
55d9f0492fSopenharmony_cistatic int SetInitLogLevelFromParam(BShellHandle shell, int argc, char **argv)
56d9f0492fSopenharmony_ci{
57d9f0492fSopenharmony_ci    if (argc != 2) { // 2 is set log level parameter number
58d9f0492fSopenharmony_ci        char *helpArgs[] = {"set", NULL};
59d9f0492fSopenharmony_ci        BShellCmdHelp(shell, 1, helpArgs);
60d9f0492fSopenharmony_ci        return 0;
61d9f0492fSopenharmony_ci    }
62d9f0492fSopenharmony_ci    errno = 0;
63d9f0492fSopenharmony_ci    unsigned int level = strtoul(argv[1], 0, 10); // 10 is decimal
64d9f0492fSopenharmony_ci    if (errno != 0) {
65d9f0492fSopenharmony_ci        printf("Failed to transform %s to unsigned int. \n", argv[1]);
66d9f0492fSopenharmony_ci        return -1;
67d9f0492fSopenharmony_ci    }
68d9f0492fSopenharmony_ci    if ((level >= INIT_DEBUG) && (level <= INIT_FATAL)) {
69d9f0492fSopenharmony_ci        const char *logLevelStr[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" };
70d9f0492fSopenharmony_ci        int ret = HandleCmd(shell, "setloglevel", argc - 1, &argv[1]);
71d9f0492fSopenharmony_ci        if (ret != 0) {
72d9f0492fSopenharmony_ci            printf("Failed to set log level %s. \n", logLevelStr[level]);
73d9f0492fSopenharmony_ci        } else {
74d9f0492fSopenharmony_ci            printf("Success to set log level %s. \n", logLevelStr[level]);
75d9f0492fSopenharmony_ci        }
76d9f0492fSopenharmony_ci    } else {
77d9f0492fSopenharmony_ci        printf("%s is invalid. \n", argv[1]);
78d9f0492fSopenharmony_ci    }
79d9f0492fSopenharmony_ci    return 0;
80d9f0492fSopenharmony_ci}
81d9f0492fSopenharmony_ci
82d9f0492fSopenharmony_cistatic int32_t GetInitLogLevelFromParam(BShellHandle shell, int argc, char **argv)
83d9f0492fSopenharmony_ci{
84d9f0492fSopenharmony_ci    int level = GetIntParameter(INIT_DEBUG_LEVEL, (int)INIT_ERROR);
85d9f0492fSopenharmony_ci    if ((level >= INIT_DEBUG) && (level <= INIT_FATAL)) {
86d9f0492fSopenharmony_ci        const char *logLevelStr[] = { "DEBUG", "INFO", "WARNING", "ERROR", "FATAL" };
87d9f0492fSopenharmony_ci        printf("Init log level: %s \n", logLevelStr[level]);
88d9f0492fSopenharmony_ci    }
89d9f0492fSopenharmony_ci    return 0;
90d9f0492fSopenharmony_ci}
91d9f0492fSopenharmony_ci
92d9f0492fSopenharmony_cistatic int32_t GetUidByName(BShellHandle shell, int argc, char **argv)
93d9f0492fSopenharmony_ci{
94d9f0492fSopenharmony_ci    if (argc != 2) { // 2 is dac get uid parameter number
95d9f0492fSopenharmony_ci        char *helpArgs[] = {"dac", NULL};
96d9f0492fSopenharmony_ci        BShellCmdHelp(shell, 1, helpArgs);
97d9f0492fSopenharmony_ci        return 0;
98d9f0492fSopenharmony_ci    }
99d9f0492fSopenharmony_ci    struct passwd *data = getpwnam(argv[1]);
100d9f0492fSopenharmony_ci    if (data == NULL) {
101d9f0492fSopenharmony_ci        printf("getpwnam uid failed\n");
102d9f0492fSopenharmony_ci    } else {
103d9f0492fSopenharmony_ci        printf("getpwnam uid %s : %u\n", argv[1], data->pw_uid);
104d9f0492fSopenharmony_ci    }
105d9f0492fSopenharmony_ci
106d9f0492fSopenharmony_ci    data = NULL;
107d9f0492fSopenharmony_ci    while ((data = getpwent()) != NULL) {
108d9f0492fSopenharmony_ci        if ((data->pw_name != NULL) && (strcmp(data->pw_name, argv[1]) == 0)) {
109d9f0492fSopenharmony_ci            printf("getpwent uid %s : %u\n", argv[1], data->pw_uid);
110d9f0492fSopenharmony_ci            break;
111d9f0492fSopenharmony_ci        }
112d9f0492fSopenharmony_ci    }
113d9f0492fSopenharmony_ci    endpwent();
114d9f0492fSopenharmony_ci    return 0;
115d9f0492fSopenharmony_ci}
116d9f0492fSopenharmony_ci
117d9f0492fSopenharmony_cistatic void ShowUserInGroup(struct group *data)
118d9f0492fSopenharmony_ci{
119d9f0492fSopenharmony_ci    int index = 0;
120d9f0492fSopenharmony_ci    printf("users in this group:");
121d9f0492fSopenharmony_ci    while (data->gr_mem[index]) { // user in this group
122d9f0492fSopenharmony_ci        printf(" %s", data->gr_mem[index]);
123d9f0492fSopenharmony_ci        index++;
124d9f0492fSopenharmony_ci    }
125d9f0492fSopenharmony_ci    printf("\n");
126d9f0492fSopenharmony_ci    return;
127d9f0492fSopenharmony_ci}
128d9f0492fSopenharmony_ci
129d9f0492fSopenharmony_cistatic int32_t GetGidByName(BShellHandle shell, int argc, char **argv)
130d9f0492fSopenharmony_ci{
131d9f0492fSopenharmony_ci    if (argc != 2) { // 2 is dac get gid parameter number
132d9f0492fSopenharmony_ci        char *helpArgs[] = {"dac", NULL};
133d9f0492fSopenharmony_ci        BShellCmdHelp(shell, 1, helpArgs);
134d9f0492fSopenharmony_ci        return 0;
135d9f0492fSopenharmony_ci    }
136d9f0492fSopenharmony_ci    struct group *data = getgrnam(argv[1]);
137d9f0492fSopenharmony_ci    if (data == NULL) {
138d9f0492fSopenharmony_ci        printf("getgrnam gid failed\n");
139d9f0492fSopenharmony_ci    } else {
140d9f0492fSopenharmony_ci        printf("getgrnam gid %s : %u\n", argv[1], data->gr_gid);
141d9f0492fSopenharmony_ci        ShowUserInGroup(data);
142d9f0492fSopenharmony_ci    }
143d9f0492fSopenharmony_ci
144d9f0492fSopenharmony_ci    data = NULL;
145d9f0492fSopenharmony_ci    while ((data = getgrent()) != NULL) {
146d9f0492fSopenharmony_ci        if ((data->gr_name != NULL) && (strcmp(data->gr_name, argv[1]) == 0)) {
147d9f0492fSopenharmony_ci            printf("getgrent gid %s : %u\n", argv[1], data->gr_gid);
148d9f0492fSopenharmony_ci            ShowUserInGroup(data);
149d9f0492fSopenharmony_ci            break;
150d9f0492fSopenharmony_ci        }
151d9f0492fSopenharmony_ci    }
152d9f0492fSopenharmony_ci    endgrent();
153d9f0492fSopenharmony_ci    return 0;
154d9f0492fSopenharmony_ci}
155d9f0492fSopenharmony_ci
156d9f0492fSopenharmony_ciMODULE_CONSTRUCTOR(void)
157d9f0492fSopenharmony_ci{
158d9f0492fSopenharmony_ci    const CmdInfo infos[] = {
159d9f0492fSopenharmony_ci        {"set", SetInitLogLevelFromParam,
160d9f0492fSopenharmony_ci            "set init log level 0:debug, 1:info, 2:warning, 3:err, 4:fatal", "set log level", "set log level"},
161d9f0492fSopenharmony_ci        {"get", GetInitLogLevelFromParam, "get init log level", "get log level", "get log level"},
162d9f0492fSopenharmony_ci        {"dac", GetGidByName, "get dac gid by group name", "dac gid groupname", "dac gid"},
163d9f0492fSopenharmony_ci        {"dac", GetUidByName, "get dac uid by user name", "dac uid username", "dac uid"},
164d9f0492fSopenharmony_ci    };
165d9f0492fSopenharmony_ci    for (size_t i = 0; i < sizeof(infos) / sizeof(infos[0]); i++) {
166d9f0492fSopenharmony_ci        BShellEnvRegisterCmd(GetShellHandle(), &infos[i]);
167d9f0492fSopenharmony_ci    }
168d9f0492fSopenharmony_ci}