1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2021 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 16d9f0492fSopenharmony_ci#include "ueventd_read_cfg.h" 17d9f0492fSopenharmony_ci 18d9f0492fSopenharmony_ci#include <ctype.h> 19d9f0492fSopenharmony_ci#include <string.h> 20d9f0492fSopenharmony_ci#include <stdbool.h> 21d9f0492fSopenharmony_ci#include <stdlib.h> 22d9f0492fSopenharmony_ci#include <unistd.h> 23d9f0492fSopenharmony_ci#include <errno.h> 24d9f0492fSopenharmony_ci#include <fcntl.h> 25d9f0492fSopenharmony_ci#include <sys/stat.h> 26d9f0492fSopenharmony_ci#include "init_utils.h" 27d9f0492fSopenharmony_ci#include "list.h" 28d9f0492fSopenharmony_ci#include "ueventd_utils.h" 29d9f0492fSopenharmony_ci#include "securec.h" 30d9f0492fSopenharmony_ci#define INIT_LOG_TAG "ueventd" 31d9f0492fSopenharmony_ci#include "init_log.h" 32d9f0492fSopenharmony_ci 33d9f0492fSopenharmony_ci// default item count in config files 34d9f0492fSopenharmony_ci#define DEFAULTITEMCOUNT (50) 35d9f0492fSopenharmony_ci#define MAX_CONFIGURE_SIZE (1024 * 1024 * 16) 36d9f0492fSopenharmony_ci 37d9f0492fSopenharmony_citypedef enum SECTION { 38d9f0492fSopenharmony_ci SECTION_INVALID = -1, 39d9f0492fSopenharmony_ci SECTION_DEVICE = 0, 40d9f0492fSopenharmony_ci SECTION_SYSFS, 41d9f0492fSopenharmony_ci SECTION_FIRMWARE 42d9f0492fSopenharmony_ci} SECTION; 43d9f0492fSopenharmony_ci 44d9f0492fSopenharmony_citypedef int (*ParseConfigFunc)(char *); 45d9f0492fSopenharmony_citypedef struct FunctionMapper { 46d9f0492fSopenharmony_ci const char *name; 47d9f0492fSopenharmony_ci ParseConfigFunc func; 48d9f0492fSopenharmony_ci} FUNCTIONMAPPER; 49d9f0492fSopenharmony_ci 50d9f0492fSopenharmony_cistruct ListNode g_devices = { 51d9f0492fSopenharmony_ci .next = &g_devices, 52d9f0492fSopenharmony_ci .prev = &g_devices, 53d9f0492fSopenharmony_ci}; 54d9f0492fSopenharmony_ci 55d9f0492fSopenharmony_cistruct ListNode g_sysDevices = { 56d9f0492fSopenharmony_ci .next = &g_sysDevices, 57d9f0492fSopenharmony_ci .prev = &g_sysDevices, 58d9f0492fSopenharmony_ci}; 59d9f0492fSopenharmony_ci 60d9f0492fSopenharmony_cistruct ListNode g_firmwares = { 61d9f0492fSopenharmony_ci .next = &g_firmwares, 62d9f0492fSopenharmony_ci .prev = &g_firmwares, 63d9f0492fSopenharmony_ci}; 64d9f0492fSopenharmony_ci 65d9f0492fSopenharmony_cistatic int ParseDeviceConfig(char *p) 66d9f0492fSopenharmony_ci{ 67d9f0492fSopenharmony_ci INIT_LOGV("Parse device config info: %s", p); 68d9f0492fSopenharmony_ci char **items = NULL; 69d9f0492fSopenharmony_ci int count = -1; 70d9f0492fSopenharmony_ci // format: <device node> <mode> <uid> <gid> <parameter> 71d9f0492fSopenharmony_ci const int expectedCount = 5; 72d9f0492fSopenharmony_ci 73d9f0492fSopenharmony_ci INIT_CHECK_ONLY_ELOG(!INVALIDSTRING(p), "Invalid argument"); 74d9f0492fSopenharmony_ci items = SplitStringExt(p, " ", &count, expectedCount); 75d9f0492fSopenharmony_ci if ((count != expectedCount) && (count != expectedCount - 1)) { 76d9f0492fSopenharmony_ci INIT_LOGE("Ignore invalid item: %s", p); 77d9f0492fSopenharmony_ci FreeStringVector(items, count); 78d9f0492fSopenharmony_ci return 0; 79d9f0492fSopenharmony_ci } 80d9f0492fSopenharmony_ci 81d9f0492fSopenharmony_ci struct DeviceUdevConf *config = calloc(1, sizeof(struct DeviceUdevConf)); 82d9f0492fSopenharmony_ci if (config == NULL) { 83d9f0492fSopenharmony_ci errno = ENOMEM; 84d9f0492fSopenharmony_ci FreeStringVector(items, count); 85d9f0492fSopenharmony_ci return -1; 86d9f0492fSopenharmony_ci } 87d9f0492fSopenharmony_ci config->name = strdup(items[0]); // device node 88d9f0492fSopenharmony_ci INIT_ERROR_CHECK(config->name != NULL, FreeStringVector(items, count); 89d9f0492fSopenharmony_ci free(config); return -1, "failed dup config name"); 90d9f0492fSopenharmony_ci errno = 0; 91d9f0492fSopenharmony_ci config->mode = strtoul(items[1], NULL, OCTAL_BASE); // mode 92d9f0492fSopenharmony_ci INIT_ERROR_CHECK(errno == 0, config->mode = DEVMODE, 93d9f0492fSopenharmony_ci "Invalid mode in config file for device node %s. use default mode", config->name); 94d9f0492fSopenharmony_ci config->uid = (uid_t)DecodeUid(items[2]); // uid 95d9f0492fSopenharmony_ci config->gid = (gid_t)DecodeGid(items[3]); // gid 96d9f0492fSopenharmony_ci if (count == expectedCount) { 97d9f0492fSopenharmony_ci config->parameter = strdup(items[4]); // device parameter 98d9f0492fSopenharmony_ci INIT_ERROR_CHECK(config->parameter != NULL, FreeStringVector(items, count); 99d9f0492fSopenharmony_ci free((void*)config->name); free(config); return -1, "failed dup parameter"); 100d9f0492fSopenharmony_ci } else { 101d9f0492fSopenharmony_ci config->parameter = NULL; 102d9f0492fSopenharmony_ci } 103d9f0492fSopenharmony_ci OH_ListInit(&config->paramNode); 104d9f0492fSopenharmony_ci OH_ListAddTail(&g_devices, &config->list); 105d9f0492fSopenharmony_ci FreeStringVector(items, count); 106d9f0492fSopenharmony_ci return 0; 107d9f0492fSopenharmony_ci} 108d9f0492fSopenharmony_ci 109d9f0492fSopenharmony_cistatic int ParseSysfsConfig(char *p) 110d9f0492fSopenharmony_ci{ 111d9f0492fSopenharmony_ci INIT_LOGV("Parse sysfs config info: %s", p); 112d9f0492fSopenharmony_ci char **items = NULL; 113d9f0492fSopenharmony_ci int count = -1; 114d9f0492fSopenharmony_ci // format: <syspath> <attribute> <mode> <uid> <gid> 115d9f0492fSopenharmony_ci const int expectedCount = 5; 116d9f0492fSopenharmony_ci 117d9f0492fSopenharmony_ci INIT_CHECK_ONLY_ELOG(!INVALIDSTRING(p), "Invalid argument"); 118d9f0492fSopenharmony_ci items = SplitStringExt(p, " ", &count, expectedCount); 119d9f0492fSopenharmony_ci if (count != expectedCount) { 120d9f0492fSopenharmony_ci INIT_LOGE("Ignore invalid item: %s", p); 121d9f0492fSopenharmony_ci FreeStringVector(items, count); 122d9f0492fSopenharmony_ci return 0; 123d9f0492fSopenharmony_ci } 124d9f0492fSopenharmony_ci struct SysUdevConf *config = calloc(1, sizeof(struct SysUdevConf)); 125d9f0492fSopenharmony_ci if (config == NULL) { 126d9f0492fSopenharmony_ci errno = ENOMEM; 127d9f0492fSopenharmony_ci FreeStringVector(items, count); 128d9f0492fSopenharmony_ci return -1; 129d9f0492fSopenharmony_ci } 130d9f0492fSopenharmony_ci config->sysPath = strdup(items[0]); // sys path 131d9f0492fSopenharmony_ci INIT_ERROR_CHECK(config->sysPath != NULL, FreeStringVector(items, count); 132d9f0492fSopenharmony_ci free(config); return -1, "failed to dup syspath"); 133d9f0492fSopenharmony_ci config->attr = strdup(items[1]); // attribute 134d9f0492fSopenharmony_ci INIT_ERROR_CHECK(config->attr != NULL, FreeStringVector(items, count); 135d9f0492fSopenharmony_ci free((void*)config->sysPath); free(config); return -1, "failed to dup attr"); 136d9f0492fSopenharmony_ci errno = 0; 137d9f0492fSopenharmony_ci config->mode = strtoul(items[2], NULL, OCTAL_BASE); // mode 138d9f0492fSopenharmony_ci INIT_ERROR_CHECK(errno == 0, config->mode = DEVMODE, 139d9f0492fSopenharmony_ci "Invalid mode in config file for sys path %s. use default mode", config->sysPath); 140d9f0492fSopenharmony_ci config->uid = (uid_t)DecodeUid(items[3]); // uid 141d9f0492fSopenharmony_ci config->gid = (gid_t)DecodeGid(items[4]); // gid 142d9f0492fSopenharmony_ci OH_ListAddTail(&g_sysDevices, &config->list); 143d9f0492fSopenharmony_ci FreeStringVector(items, count); 144d9f0492fSopenharmony_ci return 0; 145d9f0492fSopenharmony_ci} 146d9f0492fSopenharmony_ci 147d9f0492fSopenharmony_cistatic int ParseFirmwareConfig(char *p) 148d9f0492fSopenharmony_ci{ 149d9f0492fSopenharmony_ci INIT_LOGV("Parse firmware config info: %s", p); 150d9f0492fSopenharmony_ci INIT_ERROR_CHECK(!INVALIDSTRING(p), return -1, "Invalid argument"); 151d9f0492fSopenharmony_ci 152d9f0492fSopenharmony_ci // Sanity checks 153d9f0492fSopenharmony_ci struct stat st = {}; 154d9f0492fSopenharmony_ci INIT_ERROR_CHECK(stat(p, &st) == 0, return -1, "Invalid firmware file: %s, err = %d", p, errno); 155d9f0492fSopenharmony_ci INIT_ERROR_CHECK(S_ISDIR(st.st_mode), return -1, "Expect directory in firmware config"); 156d9f0492fSopenharmony_ci struct FirmwareUdevConf *config = calloc(1, sizeof(struct FirmwareUdevConf)); 157d9f0492fSopenharmony_ci INIT_CHECK(config != NULL, errno = ENOMEM; 158d9f0492fSopenharmony_ci return -1); 159d9f0492fSopenharmony_ci config->fmPath = strdup(p); 160d9f0492fSopenharmony_ci INIT_ERROR_CHECK(config->fmPath != NULL, free(config); return -1, "failed to dup fmpath"); 161d9f0492fSopenharmony_ci OH_ListAddTail(&g_firmwares, &config->list); 162d9f0492fSopenharmony_ci return 0; 163d9f0492fSopenharmony_ci} 164d9f0492fSopenharmony_ci 165d9f0492fSopenharmony_cistatic SECTION GetSection(const char *section) 166d9f0492fSopenharmony_ci{ 167d9f0492fSopenharmony_ci INIT_CHECK_RETURN_VALUE(!INVALIDSTRING(section), SECTION_INVALID); 168d9f0492fSopenharmony_ci if (STRINGEQUAL(section, "device")) { 169d9f0492fSopenharmony_ci return SECTION_DEVICE; 170d9f0492fSopenharmony_ci } else if (STRINGEQUAL(section, "sysfs")) { 171d9f0492fSopenharmony_ci return SECTION_SYSFS; 172d9f0492fSopenharmony_ci } else if (STRINGEQUAL(section, "firmware")) { 173d9f0492fSopenharmony_ci return SECTION_FIRMWARE; 174d9f0492fSopenharmony_ci } else { 175d9f0492fSopenharmony_ci return SECTION_INVALID; 176d9f0492fSopenharmony_ci } 177d9f0492fSopenharmony_ci} 178d9f0492fSopenharmony_ci 179d9f0492fSopenharmony_cistatic const FUNCTIONMAPPER funcMapper[3] = { 180d9f0492fSopenharmony_ci {"device", ParseDeviceConfig}, 181d9f0492fSopenharmony_ci {"sysfs", ParseSysfsConfig}, 182d9f0492fSopenharmony_ci {"firmware", ParseFirmwareConfig} 183d9f0492fSopenharmony_ci}; 184d9f0492fSopenharmony_ci 185d9f0492fSopenharmony_ciParseConfigFunc callback; 186d9f0492fSopenharmony_ciint ParseUeventConfig(char *buffer) 187d9f0492fSopenharmony_ci{ 188d9f0492fSopenharmony_ci char *section = NULL; 189d9f0492fSopenharmony_ci char *right = NULL; 190d9f0492fSopenharmony_ci char *p = buffer; 191d9f0492fSopenharmony_ci SECTION type; 192d9f0492fSopenharmony_ci 193d9f0492fSopenharmony_ci INIT_CHECK_RETURN_VALUE(!INVALIDSTRING(buffer), -1); 194d9f0492fSopenharmony_ci if (*p == '[') { 195d9f0492fSopenharmony_ci p++; 196d9f0492fSopenharmony_ci if ((right = strchr(p, ']')) == NULL) { 197d9f0492fSopenharmony_ci INIT_LOGE("Invalid line \"%s\", miss ']'", buffer); 198d9f0492fSopenharmony_ci return -1; 199d9f0492fSopenharmony_ci } 200d9f0492fSopenharmony_ci *right = '\0'; // Replace ']' with '\0'; 201d9f0492fSopenharmony_ci section = p; 202d9f0492fSopenharmony_ci INIT_LOGV("section is [%s]", section); 203d9f0492fSopenharmony_ci if ((type = GetSection(section)) == SECTION_INVALID) { 204d9f0492fSopenharmony_ci INIT_LOGE("Invalid section \" %s \"", section); 205d9f0492fSopenharmony_ci callback = NULL; // reset callback 206d9f0492fSopenharmony_ci return -1; 207d9f0492fSopenharmony_ci } 208d9f0492fSopenharmony_ci callback = funcMapper[type].func; 209d9f0492fSopenharmony_ci return 0; 210d9f0492fSopenharmony_ci } 211d9f0492fSopenharmony_ci return (callback != NULL) ? callback(p) : -1; 212d9f0492fSopenharmony_ci} 213d9f0492fSopenharmony_ci 214d9f0492fSopenharmony_cistatic void DoUeventConfigParse(char *buffer, size_t length) 215d9f0492fSopenharmony_ci{ 216d9f0492fSopenharmony_ci char **items = NULL; 217d9f0492fSopenharmony_ci int count = -1; 218d9f0492fSopenharmony_ci const int maxItemCount = DEFAULTITEMCOUNT; 219d9f0492fSopenharmony_ci 220d9f0492fSopenharmony_ci items = SplitStringExt(buffer, "\n", &count, maxItemCount); 221d9f0492fSopenharmony_ci INIT_LOGV("Dump items count = %d", count); 222d9f0492fSopenharmony_ci for (int i = 0; i < count; i++) { 223d9f0492fSopenharmony_ci char *p = items[i]; 224d9f0492fSopenharmony_ci // Skip lead white space 225d9f0492fSopenharmony_ci while (isspace(*p)) { 226d9f0492fSopenharmony_ci p++; 227d9f0492fSopenharmony_ci } 228d9f0492fSopenharmony_ci 229d9f0492fSopenharmony_ci // Skip comment or empty line 230d9f0492fSopenharmony_ci if (*p == '\0' || *p == '#') { 231d9f0492fSopenharmony_ci continue; 232d9f0492fSopenharmony_ci } 233d9f0492fSopenharmony_ci int rc = ParseUeventConfig(p); 234d9f0492fSopenharmony_ci if (rc < 0) { 235d9f0492fSopenharmony_ci INIT_LOGE("Parse uevent config from %s failed", p); 236d9f0492fSopenharmony_ci } 237d9f0492fSopenharmony_ci } 238d9f0492fSopenharmony_ci // release memory 239d9f0492fSopenharmony_ci FreeStringVector(items, count); 240d9f0492fSopenharmony_ci} 241d9f0492fSopenharmony_ci 242d9f0492fSopenharmony_civoid ParseUeventdConfigFile(const char *file) 243d9f0492fSopenharmony_ci{ 244d9f0492fSopenharmony_ci INIT_CHECK_ONLY_RETURN(!INVALIDSTRING(file)); 245d9f0492fSopenharmony_ci char *config = GetRealPath(file); 246d9f0492fSopenharmony_ci INIT_CHECK_ONLY_RETURN(config != NULL); 247d9f0492fSopenharmony_ci int fd = open(config, O_RDONLY | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 248d9f0492fSopenharmony_ci free(config); 249d9f0492fSopenharmony_ci INIT_ERROR_CHECK(fd >= 0, return, "Read from %s failed", file); 250d9f0492fSopenharmony_ci 251d9f0492fSopenharmony_ci struct stat st; 252d9f0492fSopenharmony_ci if (fstat(fd, &st) < 0) { 253d9f0492fSopenharmony_ci INIT_LOGE("Failed to get file stat. err = %d", errno); 254d9f0492fSopenharmony_ci close(fd); 255d9f0492fSopenharmony_ci return; 256d9f0492fSopenharmony_ci } 257d9f0492fSopenharmony_ci 258d9f0492fSopenharmony_ci // st_size should never be less than 0 259d9f0492fSopenharmony_ci if (st.st_size < 0 || st.st_size > MAX_CONFIGURE_SIZE) { 260d9f0492fSopenharmony_ci INIT_LOGE("Invalid configure file with size"); 261d9f0492fSopenharmony_ci close(fd); 262d9f0492fSopenharmony_ci return; 263d9f0492fSopenharmony_ci } 264d9f0492fSopenharmony_ci size_t size = (size_t)st.st_size; 265d9f0492fSopenharmony_ci char *buffer = malloc(size + 1); 266d9f0492fSopenharmony_ci if (buffer == NULL) { 267d9f0492fSopenharmony_ci INIT_LOGE("Failed to malloc memory. err = %d", errno); 268d9f0492fSopenharmony_ci close(fd); 269d9f0492fSopenharmony_ci return; 270d9f0492fSopenharmony_ci } 271d9f0492fSopenharmony_ci 272d9f0492fSopenharmony_ci if (read(fd, buffer, size) != (ssize_t)size) { 273d9f0492fSopenharmony_ci INIT_LOGE("Read from file %s failed. err = %d", file, errno); 274d9f0492fSopenharmony_ci free(buffer); 275d9f0492fSopenharmony_ci buffer = NULL; 276d9f0492fSopenharmony_ci close(fd); 277d9f0492fSopenharmony_ci return; 278d9f0492fSopenharmony_ci } 279d9f0492fSopenharmony_ci 280d9f0492fSopenharmony_ci buffer[size] = '\0'; 281d9f0492fSopenharmony_ci DoUeventConfigParse(buffer, size); 282d9f0492fSopenharmony_ci free(buffer); 283d9f0492fSopenharmony_ci buffer = NULL; 284d9f0492fSopenharmony_ci close(fd); 285d9f0492fSopenharmony_ci} 286d9f0492fSopenharmony_ci 287d9f0492fSopenharmony_ci// support '*' to match all characters 288d9f0492fSopenharmony_ci// '?' match one character. 289d9f0492fSopenharmony_cibool IsMatch(const char *target, const char *pattern) 290d9f0492fSopenharmony_ci{ 291d9f0492fSopenharmony_ci INIT_CHECK_RETURN_VALUE(target != NULL, false); 292d9f0492fSopenharmony_ci INIT_CHECK_RETURN_VALUE(pattern != NULL, true); 293d9f0492fSopenharmony_ci 294d9f0492fSopenharmony_ci const char *t = target; 295d9f0492fSopenharmony_ci const char *p = pattern; 296d9f0492fSopenharmony_ci const char *plast = NULL; 297d9f0492fSopenharmony_ci bool reMatch = false; 298d9f0492fSopenharmony_ci while (*t != '\0') { 299d9f0492fSopenharmony_ci if (*t == *p) { 300d9f0492fSopenharmony_ci t++; 301d9f0492fSopenharmony_ci p++; 302d9f0492fSopenharmony_ci continue; 303d9f0492fSopenharmony_ci } 304d9f0492fSopenharmony_ci 305d9f0492fSopenharmony_ci // Match one character. 306d9f0492fSopenharmony_ci if (*p == '?') { 307d9f0492fSopenharmony_ci p++; 308d9f0492fSopenharmony_ci t++; 309d9f0492fSopenharmony_ci continue; 310d9f0492fSopenharmony_ci } 311d9f0492fSopenharmony_ci 312d9f0492fSopenharmony_ci if (*p == '\0') { 313d9f0492fSopenharmony_ci return reMatch; 314d9f0492fSopenharmony_ci } 315d9f0492fSopenharmony_ci 316d9f0492fSopenharmony_ci if (*p == '*') { 317d9f0492fSopenharmony_ci reMatch = true; 318d9f0492fSopenharmony_ci // Met '*', record where we will start over. 319d9f0492fSopenharmony_ci // plast point to next character that we will compare it again. 320d9f0492fSopenharmony_ci plast = ++p; 321d9f0492fSopenharmony_ci t++; 322d9f0492fSopenharmony_ci continue; 323d9f0492fSopenharmony_ci } 324d9f0492fSopenharmony_ci 325d9f0492fSopenharmony_ci if (reMatch) { 326d9f0492fSopenharmony_ci // Start over. 327d9f0492fSopenharmony_ci p = plast; 328d9f0492fSopenharmony_ci t++; 329d9f0492fSopenharmony_ci } else { 330d9f0492fSopenharmony_ci return false; 331d9f0492fSopenharmony_ci } 332d9f0492fSopenharmony_ci } 333d9f0492fSopenharmony_ci 334d9f0492fSopenharmony_ci while (*p == '*') { 335d9f0492fSopenharmony_ci p++; 336d9f0492fSopenharmony_ci } 337d9f0492fSopenharmony_ci return (*p == '\0'); 338d9f0492fSopenharmony_ci} 339d9f0492fSopenharmony_ci 340d9f0492fSopenharmony_cistruct DeviceUdevConf *GetDeviceUdevConfByDevNode(const char *devNode) 341d9f0492fSopenharmony_ci{ 342d9f0492fSopenharmony_ci if (INVALIDSTRING(devNode)) { 343d9f0492fSopenharmony_ci return NULL; 344d9f0492fSopenharmony_ci } 345d9f0492fSopenharmony_ci 346d9f0492fSopenharmony_ci struct ListNode *node = NULL; 347d9f0492fSopenharmony_ci if (!ListEmpty(g_devices)) { 348d9f0492fSopenharmony_ci ForEachListEntry(&g_devices, node) { 349d9f0492fSopenharmony_ci struct DeviceUdevConf *config = ListEntry(node, struct DeviceUdevConf, list); 350d9f0492fSopenharmony_ci if (IsMatch(devNode, config->name)) { 351d9f0492fSopenharmony_ci return config; 352d9f0492fSopenharmony_ci } 353d9f0492fSopenharmony_ci } 354d9f0492fSopenharmony_ci } 355d9f0492fSopenharmony_ci 356d9f0492fSopenharmony_ci return NULL; 357d9f0492fSopenharmony_ci} 358d9f0492fSopenharmony_ci 359d9f0492fSopenharmony_ciint GetDeviceNodePermissions(const char *devNode, uid_t *uid, gid_t *gid, mode_t *mode) 360d9f0492fSopenharmony_ci{ 361d9f0492fSopenharmony_ci if (INVALIDSTRING(devNode)) { 362d9f0492fSopenharmony_ci return -1; 363d9f0492fSopenharmony_ci } 364d9f0492fSopenharmony_ci 365d9f0492fSopenharmony_ci struct ListNode *node = NULL; 366d9f0492fSopenharmony_ci if (!ListEmpty(g_devices)) { 367d9f0492fSopenharmony_ci ForEachListEntry(&g_devices, node) { 368d9f0492fSopenharmony_ci struct DeviceUdevConf *config = ListEntry(node, struct DeviceUdevConf, list); 369d9f0492fSopenharmony_ci if (IsMatch(devNode, config->name)) { 370d9f0492fSopenharmony_ci *uid = config->uid; 371d9f0492fSopenharmony_ci *gid = config->gid; 372d9f0492fSopenharmony_ci *mode = config->mode; 373d9f0492fSopenharmony_ci return 0; 374d9f0492fSopenharmony_ci } 375d9f0492fSopenharmony_ci } 376d9f0492fSopenharmony_ci } 377d9f0492fSopenharmony_ci return -1; 378d9f0492fSopenharmony_ci} 379d9f0492fSopenharmony_ci 380d9f0492fSopenharmony_civoid ChangeSysAttributePermissions(const char *sysPath) 381d9f0492fSopenharmony_ci{ 382d9f0492fSopenharmony_ci if (INVALIDSTRING(sysPath)) { 383d9f0492fSopenharmony_ci return; 384d9f0492fSopenharmony_ci } 385d9f0492fSopenharmony_ci 386d9f0492fSopenharmony_ci struct ListNode *node = NULL; 387d9f0492fSopenharmony_ci struct SysUdevConf *config = NULL; 388d9f0492fSopenharmony_ci int matched = 0; 389d9f0492fSopenharmony_ci if (!ListEmpty(g_sysDevices)) { 390d9f0492fSopenharmony_ci ForEachListEntry(&g_sysDevices, node) { 391d9f0492fSopenharmony_ci config = ListEntry(node, struct SysUdevConf, list); 392d9f0492fSopenharmony_ci if (STRINGEQUAL(config->sysPath, sysPath)) { 393d9f0492fSopenharmony_ci matched = 1; 394d9f0492fSopenharmony_ci break; 395d9f0492fSopenharmony_ci } 396d9f0492fSopenharmony_ci } 397d9f0492fSopenharmony_ci } 398d9f0492fSopenharmony_ci 399d9f0492fSopenharmony_ci if (matched == 0) { 400d9f0492fSopenharmony_ci return; 401d9f0492fSopenharmony_ci } 402d9f0492fSopenharmony_ci char sysAttr[SYSPATH_SIZE] = {}; 403d9f0492fSopenharmony_ci if (snprintf_s(sysAttr, SYSPATH_SIZE, SYSPATH_SIZE - 1, "/sys%s/%s", config->sysPath, config->attr) == -1) { 404d9f0492fSopenharmony_ci INIT_LOGE("Failed to build sys attribute for sys path %s, attr: %s", config->sysPath, config->attr); 405d9f0492fSopenharmony_ci return; 406d9f0492fSopenharmony_ci } 407d9f0492fSopenharmony_ci if (chown(sysAttr, config->uid, config->gid) < 0) { 408d9f0492fSopenharmony_ci INIT_LOGE("chown for file %s failed, err = %d", sysAttr, errno); 409d9f0492fSopenharmony_ci } 410d9f0492fSopenharmony_ci 411d9f0492fSopenharmony_ci if (chmod(sysAttr, config->mode) < 0) { 412d9f0492fSopenharmony_ci INIT_LOGE("[uevent][error] chmod for file %s failed, err = %d", sysAttr, errno); 413d9f0492fSopenharmony_ci } 414d9f0492fSopenharmony_ci} 415d9f0492fSopenharmony_ci 416d9f0492fSopenharmony_cistatic void FreeDeviceConfig(ListNode *node) 417d9f0492fSopenharmony_ci{ 418d9f0492fSopenharmony_ci struct DeviceUdevConf *config = ListEntry(node, struct DeviceUdevConf, list); 419d9f0492fSopenharmony_ci free((void *)config->name); 420d9f0492fSopenharmony_ci free((void *)config->parameter); 421d9f0492fSopenharmony_ci OH_ListRemove(&config->paramNode); 422d9f0492fSopenharmony_ci free(config); 423d9f0492fSopenharmony_ci} 424d9f0492fSopenharmony_ci 425d9f0492fSopenharmony_cistatic void FreeSysUdevConf(ListNode *node) 426d9f0492fSopenharmony_ci{ 427d9f0492fSopenharmony_ci struct SysUdevConf *config = ListEntry(node, struct SysUdevConf, list); 428d9f0492fSopenharmony_ci free((void *)config->sysPath); 429d9f0492fSopenharmony_ci free((void *)config->attr); 430d9f0492fSopenharmony_ci free(config); 431d9f0492fSopenharmony_ci} 432d9f0492fSopenharmony_ci 433d9f0492fSopenharmony_cistatic void FreeFirmwareUdevConf(ListNode *node) 434d9f0492fSopenharmony_ci{ 435d9f0492fSopenharmony_ci struct FirmwareUdevConf *config = ListEntry(node, struct FirmwareUdevConf, list); 436d9f0492fSopenharmony_ci free((void *)config->fmPath); 437d9f0492fSopenharmony_ci free(config); 438d9f0492fSopenharmony_ci} 439d9f0492fSopenharmony_ci 440d9f0492fSopenharmony_civoid CloseUeventConfig(void) 441d9f0492fSopenharmony_ci{ 442d9f0492fSopenharmony_ci OH_ListRemoveAll(&g_devices, FreeDeviceConfig); 443d9f0492fSopenharmony_ci OH_ListRemoveAll(&g_sysDevices, FreeSysUdevConf); 444d9f0492fSopenharmony_ci OH_ListRemoveAll(&g_firmwares, FreeFirmwareUdevConf); 445d9f0492fSopenharmony_ci}