提交 af6d736d 编写于 作者: C chengjinsong

codex

Signed-off-by: Nchengjinsong <chengjinsong2@huawei.com>
上级 e171b6a3
......@@ -123,7 +123,6 @@ static int SendCmdMessage(const CmdAgent *agent, uint16_t type, const char *cmd,
BEGET_LOGE("[control_fd] Invalid parameter");
return -1;
}
int ret = 0;
BufferHandle handle = NULL;
uint32_t bufferSize = sizeof(CmdMessage) + strlen(cmd) + PTY_PATH_SIZE + 1;
handle = LE_CreateBuffer(LE_GetDefaultLoop(), bufferSize);
......@@ -132,7 +131,7 @@ static int SendCmdMessage(const CmdAgent *agent, uint16_t type, const char *cmd,
CmdMessage *message = (CmdMessage *)buff;
message->msgSize = bufferSize;
message->type = type;
ret = strcpy_s(message->ptyName, PTY_PATH_SIZE - 1, ptyName);
int ret = strcpy_s(message->ptyName, PTY_PATH_SIZE - 1, ptyName);
BEGET_ERROR_CHECK(ret == 0, LE_FreeBuffer(LE_GetDefaultLoop(), agent->task, handle);
return -1, "[control_fd] Failed to copy pty name %s", ptyName);
ret = strcpy_s(message->cmd, bufferSize - sizeof(CmdMessage) - PTY_PATH_SIZE, cmd);
......
......@@ -42,7 +42,7 @@ static void CmdOnRecvMessage(const TaskHandle task, const uint8_t *buffer, uint3
// parse msg to exec
CmdMessage *msg = (CmdMessage *)buffer;
if ((msg->type < 0) || (msg->type >= ACTION_MAX) || (msg->cmd[0] == '\0') || (msg->ptyName[0] == '\0')) {
if ((msg->type >= ACTION_MAX) || (msg->cmd[0] == '\0') || (msg->ptyName[0] == '\0')) {
BEGET_LOGE("[control_fd] Received msg is invaild");
return;
}
......@@ -61,7 +61,9 @@ static void CmdOnRecvMessage(const TaskHandle task, const uint8_t *buffer, uint3
(void)dup2(fd, STDOUT_FILENO);
(void)dup2(fd, STDERR_FILENO); // Redirect fd to 0, 1, 2
(void)close(fd);
g_controlFdFunc(msg->type, msg->cmd, NULL);
if (g_controlFdFunc != NULL) {
g_controlFdFunc(msg->type, msg->cmd, NULL);
}
exit(0);
} else if (agent->pid < 0) {
BEGET_LOGE("[control_fd] Failed fork service");
......
......@@ -432,7 +432,7 @@ int LoadFscryptPolicy(char *buf, size_t size)
BEGET_LOGE("LoadFscryptPolicy:buf or fscrypt policy is empty");
return -ENOMEM;
}
if (size <= 0) {
if (size == 0) {
BEGET_LOGE("LoadFscryptPloicy:size is invalid");
return -EINVAL;
}
......@@ -532,9 +532,8 @@ static int ParseRequiredMountInfo(const char *item, Fstab *fstab)
BEGET_CHECK(!(item == NULL || *item == '\0' || fstab == NULL), return -1);
char *p = NULL;
const char *q = item;
if ((p = strstr(item, "=")) != NULL) {
q = item + strlen(OHOS_REQUIRED_MOUNT_PREFIX); // Get partition name
const char *q = item + strlen(OHOS_REQUIRED_MOUNT_PREFIX); // Get partition name
BEGET_CHECK(!(q == NULL || *q == '\0' || (p - q) <= 0), return -1);
BEGET_ERROR_CHECK(strncpy_s(partName, NAME_SIZE -1, q, p - q) == EOK,
return -1, "Failed to copy required partition name");
......
......@@ -42,11 +42,10 @@ const off_t MISC_PARTITION_ACTIVE_SLOT_SIZE = 4;
bool IsSupportedFilesystem(const char *fsType)
{
static const char *supportedFilesystem[] = {"ext4", "f2fs", NULL};
bool supported = false;
int index = 0;
if (fsType != NULL) {
static const char *supportedFilesystem[] = {"ext4", "f2fs", NULL};
int index = 0;
while (supportedFilesystem[index] != NULL) {
if (strcmp(supportedFilesystem[index++], fsType) == 0) {
supported = true;
......@@ -90,8 +89,8 @@ int DoFormat(const char *devPath, const char *fsType)
return -1;
}
int ret = 0;
char blockSizeBuffer[BLOCK_SIZE_BUFFER] = {0};
if (strcmp(fsType, "ext4") == 0) {
char blockSizeBuffer[BLOCK_SIZE_BUFFER] = {0};
const unsigned int blockSize = 4096;
if (snprintf_s(blockSizeBuffer, BLOCK_SIZE_BUFFER, BLOCK_SIZE_BUFFER - 1, "%u", blockSize) == -1) {
BEGET_LOGE("Failed to build block size buffer");
......@@ -171,7 +170,7 @@ static int DoResizeF2fs(const char* device, const unsigned long long size)
}
int ret = 0;
if (size <= 0) {
if (size == 0) {
char *cmd[] = {
file, (char *)device, NULL
};
......@@ -223,7 +222,7 @@ static int DoResizeExt(const char* device, const unsigned long long size)
}
int ret = 0;
if (size <= 0) {
if (size == 0) {
char *cmd[] = {
file, "-f", (char *)device, NULL
};
......
......@@ -20,8 +20,8 @@
namespace OHOS {
namespace system {
int GetStringParameter(const std::string key, std::string &value, const std::string def = "");
int GetIntParameter(const std::string key, int def);
int GetStringParameter(const std::string &key, std::string &value, const std::string def = "");
int GetIntParameter(const std::string &key, int def);
}
}
......
......@@ -47,16 +47,8 @@ static int DoReboot_(const char *option)
ret = snprintf_s(value, MAX_REBOOT_OPTION_SIZE, MAX_REBOOT_OPTION_SIZE - 1, "reboot,%s", option);
BEGET_ERROR_CHECK(ret >= 0, return -1, "Failed to copy boot option \" %s \"", option);
if (strcmp(option, DEVICE_CMD_SUSPEND) == 0) {
ret = SystemSetParameter(STARTUP_DEVICE_CTL, DEVICE_CMD_STOP);
BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to set stop param");
} else if (strcmp(option, DEVICE_CMD_FREEZE) == 0) {
ret = SystemSetParameter(STARTUP_DEVICE_CTL, DEVICE_CMD_STOP);
BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to set stop param");
} else {
ret = SystemSetParameter(STARTUP_DEVICE_CTL, DEVICE_CMD_STOP);
BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to set stop param");
}
ret = SystemSetParameter(STARTUP_DEVICE_CTL, DEVICE_CMD_STOP);
BEGET_ERROR_CHECK(ret == 0, return -1, "Failed to set stop param");
ret = SystemSetParameter(DOREBOOT_PARAM, value);
BEGET_ERROR_CHECK(ret == 0, return -1, "Set parameter to trigger reboot command \" %s \" failed", value);
return 0;
......
......@@ -99,7 +99,7 @@ bool GetBoolParameter(const std::string& key, bool def)
return def;
}
int GetStringParameter(const std::string key, std::string &value, const std::string def)
int GetStringParameter(const std::string &key, std::string &value, const std::string def)
{
uint32_t size = 0;
int ret = SystemReadParam(key.c_str(), NULL, &size);
......@@ -173,7 +173,7 @@ std::string GetDeviceType(void)
return std::string(type);
}
int GetIntParameter(const std::string key, int def)
int GetIntParameter(const std::string &key, int def)
{
return GetIntParameter(key, def, INT_MIN, INT_MAX);
}
......
......@@ -64,7 +64,7 @@ static void ClearLogo(int fd)
static void WriteLogoContent(int fd, const std::string &logoPath, uint32_t size)
{
if (fd < 0 || logoPath.empty() || size <= 0) {
if (fd < 0 || logoPath.empty() || size == 0) {
std::cout << "path is null or size illegal\n";
return;
}
......
......@@ -94,14 +94,14 @@ static void EnterExec(const std::string &processName)
const std::string sep = " ";
OHOS::SplitStr(tmpName, sep, vtr, true, false);
if ((vtr.size() > MAX_PROCESS_ARGC) || (vtr.size() <= 0)) {
if ((vtr.size() > MAX_PROCESS_ARGC) || (vtr.size() == 0)) {
std::cout << "Service parameters is error." << std::endl;
return;
}
char *argv[MAX_PROCESS_ARGC] = {};
std::vector<std::string>::iterator it;
int i = 0;
for (it = vtr.begin(); it != vtr.end(); it++) {
for (it = vtr.begin(); it != vtr.end(); ++it) {
argv[i] = (char *)(*it).c_str();
std::cout << std::string(argv[i]) << std::endl;
i++;
......
......@@ -561,7 +561,7 @@ static const char *GetRealCmdName(const char *name)
}
i++;
}
if ((last != 0) && (name + last != NULL)) {
if (last != 0) {
return name + last + 1;
} else {
return name;
......
......@@ -111,7 +111,7 @@ int GetServiceCaps(const cJSON *curArrItem, Service *service)
caps = (unsigned int)cJSON_GetNumberValue(capJson);
} else if (cJSON_IsString(capJson)) {
capStr = cJSON_GetStringValue(capJson);
if (capStr == NULL || strlen(capStr) <= 0) { // check all errors
if (capStr == NULL || strlen(capStr) == 0) { // check all errors
INIT_LOGE("service=%s, parse item[%d] as string, error.", service->name, i);
break;
}
......
......@@ -74,7 +74,6 @@ static void DoLoadCfg(const struct CmdArgs *ctx)
{
char buf[LOADCFG_BUF_SIZE] = { 0 };
size_t maxLoop = 0;
int len;
if (!CheckValidCfg(ctx->argv[0])) {
INIT_LOGE("CheckCfg file %s Failed", ctx->argv[0]);
return;
......@@ -90,7 +89,7 @@ static void DoLoadCfg(const struct CmdArgs *ctx)
while (fgets(buf, LOADCFG_BUF_SIZE - 1, fp) != NULL && maxLoop < LOADCFG_MAX_LOOP) {
maxLoop++;
len = strlen(buf);
int len = strlen(buf);
if (len < 1) {
continue;
}
......
......@@ -135,23 +135,20 @@ static void SendFdsInfo(int sock, Service *service)
static void HandlerGetFds(int sock, Service *service)
{
const char *errorInfo = NULL;
if (sock < 0 || service == NULL) {
INIT_LOGE("Get fd from init with invalid parameter");
errorInfo = "Invalid parameter";
SendErrorInfo(sock, "Invalid parameter", "");
return;
}
if (service->fds == NULL || service->fdCount == 0) {
INIT_LOGE("Service \' %s \' does not have any held fds", service->name);
errorInfo = "Service without any fds";
SendErrorInfo(sock, "Service without any fds", service->name);
return;
}
if (errorInfo != NULL) {
SendErrorInfo(sock, errorInfo, service->name);
} else {
// Send fds back to service
SendFdsInfo(sock, service);
}
// Send fds back to service
SendFdsInfo(sock, service);
}
static int CheckFdHolderPermission(Service *service, pid_t requestPid)
......
......@@ -196,8 +196,7 @@ static void DoLoadDefaultParams(const struct CmdArgs *ctx)
static void DoSyncExec(const struct CmdArgs *ctx)
{
// format: syncexec /xxx/xxx/xxx xxx
INIT_ERROR_CHECK(ctx != NULL && ctx->argv[0] != NULL, return,
"DoSyncExec: invalid arguments to exec \"%s\"", ctx->argv[0]);
INIT_ERROR_CHECK(ctx != NULL && ctx->argv[0] != NULL, return, "DoSyncExec: invalid arguments");
SyncExecCommand(ctx->argc, ctx->argv);
return;
}
......@@ -205,8 +204,7 @@ static void DoSyncExec(const struct CmdArgs *ctx)
static void DoExec(const struct CmdArgs *ctx)
{
// format: exec /xxx/xxx/xxx xxx
INIT_ERROR_CHECK(ctx != NULL && ctx->argv[0] != NULL, return,
"DoExec: invalid arguments to exec \"%s\"", ctx->argv[0]);
INIT_ERROR_CHECK(ctx != NULL && ctx->argv[0] != NULL, return, "DoExec: invalid arguments");
pid_t pid = fork();
INIT_ERROR_CHECK(pid >= 0, return, "DoExec: failed to fork child process to exec \"%s\"", ctx->argv[0]);
......
......@@ -71,7 +71,7 @@ static void BootchartLogHeader(void)
struct tm *now = localtime(&tm);
PLUGIN_CHECK(now != NULL, return, "Failed to get local time");
size_t size = strftime(date, sizeof(date), "%F %T", now);
PLUGIN_CHECK(size >= 0, return, "Failed to strftime");
PLUGIN_CHECK(size > 0, return, "Failed to strftime");
struct utsname uts;
if (uname(&uts) == -1) {
return;
......@@ -224,12 +224,11 @@ static int DoBootchartStart(void)
PLUGIN_LOGI("bootcharting has been start");
return 0;
}
int ret = 0;
g_bootchartCtrl = malloc(sizeof(BootchartCtrl));
PLUGIN_CHECK(g_bootchartCtrl != NULL, return -1, "Failed to alloc mem for bootchart");
g_bootchartCtrl->bufferSize = DEFAULT_BUFFER;
ret = pthread_mutex_init(&(g_bootchartCtrl->mutex), NULL);
int ret = pthread_mutex_init(&(g_bootchartCtrl->mutex), NULL);
PLUGIN_CHECK(ret == 0, BootchartDestory();
return -1, "Failed to init mutex");
ret = pthread_cond_init(&(g_bootchartCtrl->cond), NULL);
......
......@@ -371,6 +371,7 @@ INIT_LOCAL_API int AddSecurityLabel(const ParamAuditData *auditData)
} else {
#ifdef STARTUP_INIT_TEST
ParamSecurityNode *label = (ParamSecurityNode *)GetTrieNode(workSpace, node->labelIndex);
PARAM_CHECK(label != NULL, return -1, "Failed to get trie node");
label->mode = auditData->dacData.mode;
label->uid = auditData->dacData.uid;
label->gid = auditData->dacData.gid;
......
......@@ -23,9 +23,10 @@
int ConnectServer(int fd, const char *servername)
{
PARAM_CHECK(fd >= 0, return -1, "Invalid fd %d", fd);
PARAM_CHECK(servername != NULL, return -1, "Invalid servername");
int opt = 1;
int ret = setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt));
PARAM_CHECK(servername != NULL, return -1, "Invalid servername");
PARAM_CHECK(ret == 0, return -1, "Failed to set socket option");
struct sockaddr_un addr;
/* fill socket address structure with server's address */
ret = memset_s(&addr, sizeof(addr), 0, sizeof(addr));
......
......@@ -84,8 +84,8 @@ int ParamServiceStop(void);
int ParamServiceStart(void);
int ParamTaskClose(const ParamTaskPtr stream);
int ParamServerCreate(ParamTaskPtr *server, const ParamStreamInfo *info);
int ParamStreamCreate(ParamTaskPtr *client, ParamTaskPtr server, const ParamStreamInfo *info, uint16_t userDataSize);
int ParamServerCreate(ParamTaskPtr *stream, const ParamStreamInfo *streamInfo);
int ParamStreamCreate(ParamTaskPtr *stream, ParamTaskPtr server, const ParamStreamInfo *streamInfo, uint16_t userDataSize);
int ParamTaskSendMsg(const ParamTaskPtr stream, const ParamMessage *msg);
int ParamEventTaskCreate(ParamTaskPtr *stream, LE_ProcessAsyncEvent eventProcess);
......
......@@ -132,14 +132,13 @@ static int GetClientSocket(int timeout)
static int StartRequest(int clientFd, ParamMessage *request, int timeout)
{
int ret = 0;
ssize_t sendLen = send(clientFd, (char *)request, request->msgSize, 0);
if (errno == EINVAL || errno == EACCES) {
return PARAM_CODE_INVALID_SOCKET;
}
PARAM_CHECK(sendLen >= 0, return PARAM_CODE_FAIL_CONNECT, "Failed to send message err: %d", errno);
PARAM_LOGV("sendMessage sendLen fd %d %zd", clientFd, sendLen);
ret = ReadMessage(clientFd, (char *)request, timeout);
int ret = ReadMessage(clientFd, (char *)request, timeout);
if (ret == 0) {
ret = ProcessRecvMsg(request);
}
......
......@@ -59,9 +59,6 @@ static int DacCheckParamPermission(const ParamSecurityLabel *srcLabel, const cha
#if defined(__LITEOS_A__)
uid_t uid = getuid();
return uid <= SYS_UID_INDEX ? DAC_RESULT_PERMISSION : DAC_RESULT_FORBIDED;
#endif
#if defined(__LITEOS_M__)
return DAC_RESULT_PERMISSION;
#endif
return DAC_RESULT_PERMISSION;
}
......
......@@ -139,7 +139,7 @@ static int DumpTrieDataNodeTraversal(const WorkSpace *workSpace, const ParamTrie
ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, current->dataIndex);
if (entry != NULL) {
PARAM_DUMP("\tparameter length info [%u, %u] \n\t param: %s \n",
entry->keyLength, entry->valueLength, (entry != NULL) ? entry->data : "null");
entry->keyLength, entry->valueLength, entry->data);
}
}
if (current->labelIndex != 0 && verbose) {
......
......@@ -226,7 +226,7 @@ int LoadPersistParams(void)
}
#endif
if (g_persistWorkSpace.persistParamOps.load != NULL) {
ret = g_persistWorkSpace.persistParamOps.load();
(void)g_persistWorkSpace.persistParamOps.load();
PARAM_SET_FLAG(g_persistWorkSpace.flags, WORKSPACE_FLAGS_LOADED);
}
// save new persist param
......
......@@ -78,7 +78,7 @@ static int ReadSnFromFile(const char *name, const char *file)
PARAM_LOGV("**** name %s, value %s", name, data);
int ret = WriteParam(name, data, NULL, 0);
free(data);
PARAM_CHECK(ret == 0, return ret, "Failed to write param %s %s", name, data);
PARAM_CHECK(ret == 0, return ret, "Failed to write param %s", name);
return ret;
}
......@@ -113,7 +113,6 @@ static int SnDealFun(const char *name, const char *value, int res)
INIT_LOCAL_API int LoadParamFromCmdLine(void)
{
int ret;
static const cmdLineInfo cmdLines[] = {
{OHOS_BOOT"hardware", CommonDealFun
},
......@@ -133,6 +132,7 @@ INIT_LOCAL_API int LoadParamFromCmdLine(void)
return -1, "Failed to read file %s", BOOT_CMD_LINE);
for (size_t i = 0; i < ARRAY_LENGTH(cmdLines); i++) {
int ret = 0;
#ifdef BOOT_EXTENDED_CMDLINE
ret = GetParamValueFromBuffer(cmdLines[i].name, BOOT_EXTENDED_CMDLINE, value, PARAM_CONST_VALUE_LEN_MAX);
if (ret != 0) {
......
......@@ -187,7 +187,7 @@ static int ComputeSubCondition(const LogicCalculator *calculator, LogicData *dat
// check name
if ((calculator->inputName != NULL) && (strcmp(calculator->conditionName, calculator->inputName) == 0)) {
return CompareValue(calculator->conditionContent, calculator->inputContent);
} else if (calculator->conditionName != NULL && strlen(calculator->conditionName) > 0) {
} else if (strlen(calculator->conditionName) > 0) {
uint32_t len = SUPPORT_DATA_BUFFER_MAX;
ret = SystemReadParam(calculator->conditionName, calculator->readContent, &len);
if (ret != 0) {
......
......@@ -46,7 +46,7 @@ private:
: callback_(callback), context_(context) {}
~ParameterChangeListener() = default;
bool IsEqual(ParameterChangePtr callback, void *context)
bool IsEqual(ParameterChangePtr callback, void *context) const
{
return (callback == callback_ && context == context_);
}
......
......@@ -203,8 +203,10 @@ void WatcherManager::WatcherGroup::ProcessParameterChange(const std::string &nam
// walk watcher
ListNode *node = nullptr;
ForEachListEntry(&watchers_, node) {
ParamWatcher *watcher = (ParamWatcher *)node;
watcher->ProcessParameterChange(name, value);
if (node != nullptr) {
ParamWatcher *watcher = (ParamWatcher *)node;
watcher->ProcessParameterChange(name, value);
}
}
}
......@@ -291,14 +293,12 @@ int WatcherManager::GetServerFd(bool retry)
if (serverFd_ != INVALID_SOCKET) {
return serverFd_;
}
int ret = 0;
int32_t retryCount = 0;
do {
serverFd_ = socket(PF_UNIX, SOCK_STREAM, 0);
int flags = fcntl(serverFd_, F_GETFL, 0);
(void)fcntl(serverFd_, F_SETFL, flags & ~O_NONBLOCK);
ret = ConnectServer(serverFd_, CLIENT_PIPE_NAME);
if (ret == 0) {
if (ConnectServer(serverFd_, CLIENT_PIPE_NAME) == 0) {
break;
}
close(serverFd_);
......
......@@ -71,7 +71,7 @@ public:
}
~ParamWatcher() = default;
uint32_t GetWatcherId()
uint32_t GetWatcherId() const
{
return watcherId_;
}
......@@ -83,7 +83,7 @@ public:
{
return &groupNode_;
}
sptr<IWatcher> GetRemoteWatcher()
sptr<IWatcher> GetRemoteWatcher() const
{
return watcher_;
}
......
......@@ -83,7 +83,6 @@ void OH_ListRemove(struct ListNode *item)
void OH_ListAddWithOrder(struct ListNode *head, struct ListNode *item, ListCompareProc compareProc)
{
ListNode *match;
int ret;
if (head == NULL || item == NULL || compareProc == NULL) {
return;
......@@ -91,8 +90,7 @@ void OH_ListAddWithOrder(struct ListNode *head, struct ListNode *item, ListCompa
match = head->next;
while ((match != NULL) && (match != head)) {
ret = compareProc(match, item);
if (ret > 0) {
if (compareProc(match, item) > 0) {
break;
}
match = match->next;
......@@ -153,7 +151,6 @@ ListNode *OH_ListFind(const ListNode *head, void *data, ListTraversalProc compar
*/
int OH_ListTraversal(ListNode *head, void *data, ListTraversalProc traversalProc, unsigned int flags)
{
int ret;
ListNode *match;
ListNode *next;
......@@ -172,7 +169,7 @@ int OH_ListTraversal(ListNode *head, void *data, ListTraversalProc traversalProc
} else {
next = match->next;
}
ret = traversalProc(match, data);
int ret = traversalProc(match, data);
if ((ret != 0) && IS_STOP_WHEN_ERROR(flags)) {
return ret;
}
......
......@@ -50,7 +50,8 @@ static int TestHashNodeFunction(const HashNode *node)
{
TestHashNode *testNode = HASHMAP_ENTRY(node, TestHashNode, node);
int code = 0;
for (size_t i = 0; i < strlen(testNode->name); i++) {
size_t nameLen = strlen(testNode->name);
for (size_t i = 0; i < nameLen; i++) {
code += testNode->name[i] - 'A';
}
return code;
......@@ -60,7 +61,8 @@ static int TestHashKeyFunction(const void *key)
{
int code = 0;
char *buff = const_cast<char *>(static_cast<const char *>(key));
for (size_t i = 0; i < strlen(buff); i++) {
size_t buffLen = strlen(buff);
for (size_t i = 0; i < buffLen; i++) {
code += buff[i] - 'A';
}
return code;
......
......@@ -67,7 +67,7 @@ static void *ThreadRun(void *data)
char paramName[PARAM_NAME_LEN_MAX] = {0};
while (1) {
pthread_mutex_lock(&(parameterCtrl->lock));
while (parameterCtrl->empty) {
if (parameterCtrl->empty) {
struct timespec abstime = {};
struct timeval now = {};
const long timeout = 5000; // wait time 5000ms
......@@ -76,7 +76,6 @@ static void *ThreadRun(void *data)
abstime.tv_sec = now.tv_sec + nsec / 1000000000 + timeout / 1000; // 1000 unit 1000000000 unit nsec
abstime.tv_nsec = nsec % 1000000000; // 1000000000 unit nsec
pthread_cond_timedwait(&(parameterCtrl->hasData), &(parameterCtrl->lock), &abstime);
break;
}
if (parameterCtrl->shutdown) {
break;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册