1570af302Sopenharmony_ci/* 2570af302Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3570af302Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4570af302Sopenharmony_ci * you may not use this file except in compliance with the License. 5570af302Sopenharmony_ci * You may obtain a copy of the License at 6570af302Sopenharmony_ci * 7570af302Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8570af302Sopenharmony_ci * 9570af302Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10570af302Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11570af302Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12570af302Sopenharmony_ci * See the License for the specific language governing permissions and 13570af302Sopenharmony_ci * limitations under the License. 14570af302Sopenharmony_ci */ 15570af302Sopenharmony_ci 16570af302Sopenharmony_ci#include "ns_config.h" 17570af302Sopenharmony_ci 18570af302Sopenharmony_ci#include <ctype.h> 19570af302Sopenharmony_ci#include <stdarg.h> 20570af302Sopenharmony_ci 21570af302Sopenharmony_ci#include "ld_log.h" 22570af302Sopenharmony_ci/*---------------------------- Defines -------------------------------------*/ 23570af302Sopenharmony_ci#define MAX_LINE_SIZE (1024) 24570af302Sopenharmony_ci#define INI_INVALID_KEY ((char*)-1) 25570af302Sopenharmony_ci 26570af302Sopenharmony_ci#ifdef UNIT_TEST_STATIC 27570af302Sopenharmony_ci #define UT_STATIC 28570af302Sopenharmony_ci#else 29570af302Sopenharmony_ci #define UT_STATIC static 30570af302Sopenharmony_ci#endif 31570af302Sopenharmony_citypedef enum _line_status_ { 32570af302Sopenharmony_ci LINE_UNPROCESSED, 33570af302Sopenharmony_ci LINE_ERROR, 34570af302Sopenharmony_ci LINE_EMPTY, 35570af302Sopenharmony_ci LINE_COMMENT, 36570af302Sopenharmony_ci LINE_SECTION, 37570af302Sopenharmony_ci LINE_VALUE 38570af302Sopenharmony_ci} line_status; 39570af302Sopenharmony_ci 40570af302Sopenharmony_ci#define MAX_KEY_LEN 256 41570af302Sopenharmony_cistatic char g_key[MAX_KEY_LEN + 1] = {0}; 42570af302Sopenharmony_ci 43570af302Sopenharmony_cistatic char *config_key_join(const char *join, bool start) 44570af302Sopenharmony_ci{ 45570af302Sopenharmony_ci if (start) g_key[0] = 0; 46570af302Sopenharmony_ci size_t cnt = MAX_KEY_LEN - strlen(g_key); 47570af302Sopenharmony_ci return strncat(g_key, join, cnt); 48570af302Sopenharmony_ci} 49570af302Sopenharmony_ci 50570af302Sopenharmony_cistatic int default_error_callback(const char *format, ...) 51570af302Sopenharmony_ci{ 52570af302Sopenharmony_ci int ret = 0; 53570af302Sopenharmony_ci va_list argptr; 54570af302Sopenharmony_ci va_start(argptr, format); 55570af302Sopenharmony_ci /* do not print 56570af302Sopenharmony_ci ret = vfprintf(stderr, format, argptr); 57570af302Sopenharmony_ci */ 58570af302Sopenharmony_ci va_end(argptr); 59570af302Sopenharmony_ci return ret; 60570af302Sopenharmony_ci} 61570af302Sopenharmony_ci 62570af302Sopenharmony_cistatic int (*config_error_callback)(const char *, ...) = default_error_callback; 63570af302Sopenharmony_ci 64570af302Sopenharmony_cistatic void config_set_error_callback(int (*errback)(const char *, ...)) 65570af302Sopenharmony_ci{ 66570af302Sopenharmony_ci if (errback) { 67570af302Sopenharmony_ci config_error_callback = errback; 68570af302Sopenharmony_ci } else { 69570af302Sopenharmony_ci config_error_callback = default_error_callback; 70570af302Sopenharmony_ci } 71570af302Sopenharmony_ci} 72570af302Sopenharmony_ci 73570af302Sopenharmony_cistatic line_status config_line(char *line, char *section, char *key, char *value) 74570af302Sopenharmony_ci{ 75570af302Sopenharmony_ci size_t len; 76570af302Sopenharmony_ci char *split; 77570af302Sopenharmony_ci 78570af302Sopenharmony_ci if ((len = strcspn(line, "#;")) == 0) { 79570af302Sopenharmony_ci /* comment line */ 80570af302Sopenharmony_ci return LINE_COMMENT; 81570af302Sopenharmony_ci } 82570af302Sopenharmony_ci line[len] = 0; 83570af302Sopenharmony_ci if ((len = strtrim(line)) == 0) { 84570af302Sopenharmony_ci /* empty line */ 85570af302Sopenharmony_ci return LINE_EMPTY; 86570af302Sopenharmony_ci } 87570af302Sopenharmony_ci if (line[0] == '[' && line[len - 1] == ']') { 88570af302Sopenharmony_ci /* section name */ 89570af302Sopenharmony_ci memcpy(section, line + 1, len - 2); 90570af302Sopenharmony_ci section[len - 2] = 0; 91570af302Sopenharmony_ci strtrim(section); 92570af302Sopenharmony_ci return LINE_SECTION; 93570af302Sopenharmony_ci } 94570af302Sopenharmony_ci if (split = strchr(line, '=')) { 95570af302Sopenharmony_ci /* key and value */ 96570af302Sopenharmony_ci size_t klen, vlen; 97570af302Sopenharmony_ci klen = split - line; 98570af302Sopenharmony_ci vlen = len - klen - 1; 99570af302Sopenharmony_ci if (klen > 0) memcpy(key, line, klen); 100570af302Sopenharmony_ci if (vlen > 0) memcpy(value, split + 1, vlen); 101570af302Sopenharmony_ci key[klen] = 0; 102570af302Sopenharmony_ci value[vlen] = 0; 103570af302Sopenharmony_ci strtrim(key); 104570af302Sopenharmony_ci strtrim(value); 105570af302Sopenharmony_ci return LINE_VALUE; 106570af302Sopenharmony_ci } 107570af302Sopenharmony_ci return LINE_ERROR; 108570af302Sopenharmony_ci} 109570af302Sopenharmony_ci 110570af302Sopenharmony_ci#define SECTION_DEFAULT_SIZE 16 111570af302Sopenharmony_ci#define KV_DEFAULT_SIZE 64 112570af302Sopenharmony_ci 113570af302Sopenharmony_cistatic kvlist * kvlist_alloc(size_t size) 114570af302Sopenharmony_ci{ 115570af302Sopenharmony_ci kvlist *kvs; 116570af302Sopenharmony_ci 117570af302Sopenharmony_ci if (size < KV_DEFAULT_SIZE) size = KV_DEFAULT_SIZE; 118570af302Sopenharmony_ci 119570af302Sopenharmony_ci kvs = (kvlist *)__libc_calloc(1, sizeof *kvs); 120570af302Sopenharmony_ci if (kvs) { 121570af302Sopenharmony_ci kvs->key = (char **)__libc_calloc(size, sizeof *kvs->key); 122570af302Sopenharmony_ci kvs->val = (char **)__libc_calloc(size, sizeof *kvs->val); 123570af302Sopenharmony_ci if (kvs->key && kvs->val) { 124570af302Sopenharmony_ci kvs->size = size; 125570af302Sopenharmony_ci } else { 126570af302Sopenharmony_ci __libc_free(kvs->key); 127570af302Sopenharmony_ci __libc_free(kvs->val); 128570af302Sopenharmony_ci __libc_free(kvs); 129570af302Sopenharmony_ci kvs = NULL; 130570af302Sopenharmony_ci } 131570af302Sopenharmony_ci } 132570af302Sopenharmony_ci return kvs; 133570af302Sopenharmony_ci} 134570af302Sopenharmony_ci 135570af302Sopenharmony_ciUT_STATIC void kvlist_realloc(kvlist *kvs) 136570af302Sopenharmony_ci{ 137570af302Sopenharmony_ci if (!kvs) return; 138570af302Sopenharmony_ci size_t size = 2 * kvs->size; 139570af302Sopenharmony_ci if (size) { 140570af302Sopenharmony_ci char **keys, **vals; 141570af302Sopenharmony_ci keys = (char **)__libc_realloc(kvs->key, size * (sizeof *kvs->key)); 142570af302Sopenharmony_ci if (!keys) return; 143570af302Sopenharmony_ci kvs->key = keys; 144570af302Sopenharmony_ci vals = (char **)__libc_realloc(kvs->val, size * (sizeof *kvs->val)); 145570af302Sopenharmony_ci if (!vals) return; 146570af302Sopenharmony_ci kvs->val = vals; 147570af302Sopenharmony_ci kvs->size = size; 148570af302Sopenharmony_ci } 149570af302Sopenharmony_ci 150570af302Sopenharmony_ci return; 151570af302Sopenharmony_ci} 152570af302Sopenharmony_ci 153570af302Sopenharmony_cistatic void kvlist_free(kvlist *kvs) 154570af302Sopenharmony_ci{ 155570af302Sopenharmony_ci size_t i; 156570af302Sopenharmony_ci if (!kvs) return; 157570af302Sopenharmony_ci for (i = 0; i < kvs->num; i++) { 158570af302Sopenharmony_ci __libc_free(kvs->key[i]); 159570af302Sopenharmony_ci __libc_free(kvs->val[i]); 160570af302Sopenharmony_ci } 161570af302Sopenharmony_ci __libc_free(kvs->key); 162570af302Sopenharmony_ci __libc_free(kvs->val); 163570af302Sopenharmony_ci __libc_free(kvs); 164570af302Sopenharmony_ci} 165570af302Sopenharmony_ci 166570af302Sopenharmony_cistatic section_list *sections_alloc(size_t size) 167570af302Sopenharmony_ci{ 168570af302Sopenharmony_ci section_list *sections; 169570af302Sopenharmony_ci if (size < SECTION_DEFAULT_SIZE) size = SECTION_DEFAULT_SIZE; 170570af302Sopenharmony_ci 171570af302Sopenharmony_ci sections = (section_list *)__libc_calloc(1, sizeof *sections); 172570af302Sopenharmony_ci 173570af302Sopenharmony_ci if (sections) { 174570af302Sopenharmony_ci sections->names = (char**)__libc_calloc(size, sizeof *sections->names); 175570af302Sopenharmony_ci sections->kvs = (kvlist**)__libc_calloc(size, sizeof *sections->kvs); 176570af302Sopenharmony_ci if (sections->names && sections->kvs) { 177570af302Sopenharmony_ci sections->size = size; 178570af302Sopenharmony_ci } else { 179570af302Sopenharmony_ci __libc_free(sections->names); 180570af302Sopenharmony_ci __libc_free(sections->kvs); 181570af302Sopenharmony_ci __libc_free(sections); 182570af302Sopenharmony_ci sections = NULL; 183570af302Sopenharmony_ci } 184570af302Sopenharmony_ci } 185570af302Sopenharmony_ci return sections; 186570af302Sopenharmony_ci} 187570af302Sopenharmony_ci 188570af302Sopenharmony_ciUT_STATIC void sections_realloc(section_list *sections) 189570af302Sopenharmony_ci{ 190570af302Sopenharmony_ci if (!sections) return; 191570af302Sopenharmony_ci size_t size = 2 * sections->size; 192570af302Sopenharmony_ci if (size) { 193570af302Sopenharmony_ci char **names; 194570af302Sopenharmony_ci kvlist **kvs; 195570af302Sopenharmony_ci names = (char **)__libc_realloc(sections->names, size * (sizeof *sections->names)); 196570af302Sopenharmony_ci if (!names) return; 197570af302Sopenharmony_ci sections->names = names; 198570af302Sopenharmony_ci kvs = (kvlist **)__libc_realloc(sections->kvs, size * (sizeof *sections->kvs)); 199570af302Sopenharmony_ci if (!kvs) return; 200570af302Sopenharmony_ci sections->kvs = kvs; 201570af302Sopenharmony_ci sections->size = size; 202570af302Sopenharmony_ci } 203570af302Sopenharmony_ci return; 204570af302Sopenharmony_ci} 205570af302Sopenharmony_ci 206570af302Sopenharmony_cistatic void sections_free(section_list *sections) 207570af302Sopenharmony_ci{ 208570af302Sopenharmony_ci if (!sections) return; 209570af302Sopenharmony_ci for (size_t i = 0; i < sections->num; i++) { 210570af302Sopenharmony_ci __libc_free(sections->names[i]); 211570af302Sopenharmony_ci kvlist_free(sections->kvs[i]); 212570af302Sopenharmony_ci } 213570af302Sopenharmony_ci __libc_free(sections->names); 214570af302Sopenharmony_ci __libc_free(sections->kvs); 215570af302Sopenharmony_ci __libc_free(sections); 216570af302Sopenharmony_ci} 217570af302Sopenharmony_ci 218570af302Sopenharmony_cistatic void kvlist_set(kvlist *kvs, const char *key, const char *val) 219570af302Sopenharmony_ci{ 220570af302Sopenharmony_ci size_t i; 221570af302Sopenharmony_ci if (!kvs || !key || !val) return; 222570af302Sopenharmony_ci 223570af302Sopenharmony_ci for (i = 0; i < kvs->num; i++) { 224570af302Sopenharmony_ci if (!strcmp(kvs->key[i], key)) { 225570af302Sopenharmony_ci break; 226570af302Sopenharmony_ci } 227570af302Sopenharmony_ci } 228570af302Sopenharmony_ci 229570af302Sopenharmony_ci if (i < kvs->num) { 230570af302Sopenharmony_ci char * v = ld_strdup(val); 231570af302Sopenharmony_ci if (v) { 232570af302Sopenharmony_ci __libc_free(kvs->val[i]); 233570af302Sopenharmony_ci kvs->val[i] = v; 234570af302Sopenharmony_ci } 235570af302Sopenharmony_ci return; 236570af302Sopenharmony_ci } 237570af302Sopenharmony_ci if (kvs->num == kvs->size) { 238570af302Sopenharmony_ci kvlist_realloc(kvs); 239570af302Sopenharmony_ci } 240570af302Sopenharmony_ci if (kvs->num < kvs->size) { 241570af302Sopenharmony_ci kvs->key[kvs->num] = ld_strdup(key); 242570af302Sopenharmony_ci kvs->val[kvs->num] = ld_strdup(val); 243570af302Sopenharmony_ci if (kvs->key[kvs->num] && kvs->val[kvs->num]) { 244570af302Sopenharmony_ci kvs->num++; 245570af302Sopenharmony_ci } else { 246570af302Sopenharmony_ci __libc_free(kvs->key[kvs->num]); 247570af302Sopenharmony_ci __libc_free(kvs->val[kvs->num]); 248570af302Sopenharmony_ci } 249570af302Sopenharmony_ci } 250570af302Sopenharmony_ci return; 251570af302Sopenharmony_ci} 252570af302Sopenharmony_ci 253570af302Sopenharmony_cistatic void sections_set(section_list *sections, const char *name, const char *key, const char *val) 254570af302Sopenharmony_ci{ 255570af302Sopenharmony_ci kvlist* kvs = NULL; 256570af302Sopenharmony_ci if (!sections || !name || !key || !val) return; 257570af302Sopenharmony_ci 258570af302Sopenharmony_ci for(size_t i = 0; i < sections->num; i++) { 259570af302Sopenharmony_ci if (!strcmp(sections->names[i], name)) { 260570af302Sopenharmony_ci kvs = sections->kvs[i]; 261570af302Sopenharmony_ci break; 262570af302Sopenharmony_ci } 263570af302Sopenharmony_ci } 264570af302Sopenharmony_ci if (kvs) { 265570af302Sopenharmony_ci kvlist_set(kvs, key, val); 266570af302Sopenharmony_ci return; 267570af302Sopenharmony_ci } 268570af302Sopenharmony_ci 269570af302Sopenharmony_ci if (sections->num == sections->size) { 270570af302Sopenharmony_ci sections_realloc(sections); 271570af302Sopenharmony_ci } 272570af302Sopenharmony_ci 273570af302Sopenharmony_ci if (sections->num < sections->size) { 274570af302Sopenharmony_ci kvs = kvlist_alloc(0); 275570af302Sopenharmony_ci sections->names[sections->num] = ld_strdup(name); 276570af302Sopenharmony_ci sections->kvs[sections->num] = kvs; 277570af302Sopenharmony_ci if (sections->names[sections->num] && kvs) { 278570af302Sopenharmony_ci sections->num++; 279570af302Sopenharmony_ci kvlist_set(kvs, key, val); 280570af302Sopenharmony_ci } else { 281570af302Sopenharmony_ci __libc_free(sections->names[sections->num]); 282570af302Sopenharmony_ci kvlist_free(kvs); 283570af302Sopenharmony_ci } 284570af302Sopenharmony_ci } 285570af302Sopenharmony_ci} 286570af302Sopenharmony_ci 287570af302Sopenharmony_cistatic section_list *config_load(const char *filepath) 288570af302Sopenharmony_ci{ 289570af302Sopenharmony_ci FILE *file; 290570af302Sopenharmony_ci char line[MAX_LINE_SIZE + 1]; 291570af302Sopenharmony_ci char section[MAX_LINE_SIZE + 1]; 292570af302Sopenharmony_ci char key[MAX_LINE_SIZE + 1]; 293570af302Sopenharmony_ci char val[MAX_LINE_SIZE + 1]; 294570af302Sopenharmony_ci 295570af302Sopenharmony_ci size_t len; 296570af302Sopenharmony_ci int lineno = 0; 297570af302Sopenharmony_ci 298570af302Sopenharmony_ci section_list *sections; 299570af302Sopenharmony_ci 300570af302Sopenharmony_ci if ((file = fopen(filepath, "r")) == NULL) { 301570af302Sopenharmony_ci config_error_callback("config: cannot open %s\n", filepath); 302570af302Sopenharmony_ci return NULL; 303570af302Sopenharmony_ci } 304570af302Sopenharmony_ci 305570af302Sopenharmony_ci sections = sections_alloc(0); 306570af302Sopenharmony_ci if (!sections) { 307570af302Sopenharmony_ci fclose(file); 308570af302Sopenharmony_ci return NULL; 309570af302Sopenharmony_ci } 310570af302Sopenharmony_ci 311570af302Sopenharmony_ci memset(line, 0, sizeof line); 312570af302Sopenharmony_ci memset(section, 0, sizeof section); 313570af302Sopenharmony_ci memset(key, 0, sizeof key); 314570af302Sopenharmony_ci memset(val, 0, sizeof val); 315570af302Sopenharmony_ci 316570af302Sopenharmony_ci while (fgets(line, sizeof line, file)) { 317570af302Sopenharmony_ci lineno++; 318570af302Sopenharmony_ci len = strlen(line); 319570af302Sopenharmony_ci if (len == 0) continue; 320570af302Sopenharmony_ci 321570af302Sopenharmony_ci if (line[len - 1] != '\n' && !feof(file)) { 322570af302Sopenharmony_ci config_error_callback( 323570af302Sopenharmony_ci "config: input line too long in %s (%d)\n", filepath, lineno); 324570af302Sopenharmony_ci sections_free(sections); 325570af302Sopenharmony_ci fclose(file); 326570af302Sopenharmony_ci return NULL; 327570af302Sopenharmony_ci } 328570af302Sopenharmony_ci 329570af302Sopenharmony_ci if (line[len - 1] == '\n') { 330570af302Sopenharmony_ci line[len - 1] = 0; 331570af302Sopenharmony_ci len--; 332570af302Sopenharmony_ci } 333570af302Sopenharmony_ci 334570af302Sopenharmony_ci switch (config_line(line, section, key, val)) { 335570af302Sopenharmony_ci case LINE_EMPTY: 336570af302Sopenharmony_ci case LINE_COMMENT: 337570af302Sopenharmony_ci case LINE_SECTION: 338570af302Sopenharmony_ci break; 339570af302Sopenharmony_ci case LINE_VALUE: 340570af302Sopenharmony_ci sections_set(sections, section, key, val); 341570af302Sopenharmony_ci break; 342570af302Sopenharmony_ci case LINE_ERROR: 343570af302Sopenharmony_ci config_error_callback( 344570af302Sopenharmony_ci "config: syntax error in %s (%d):\n-> %s\n", 345570af302Sopenharmony_ci filepath, 346570af302Sopenharmony_ci lineno, 347570af302Sopenharmony_ci line); 348570af302Sopenharmony_ci break; 349570af302Sopenharmony_ci default: 350570af302Sopenharmony_ci break; 351570af302Sopenharmony_ci } 352570af302Sopenharmony_ci } 353570af302Sopenharmony_ci fclose(file); 354570af302Sopenharmony_ci return sections; 355570af302Sopenharmony_ci} 356570af302Sopenharmony_ci 357570af302Sopenharmony_cistatic ns_configor g_configor; 358570af302Sopenharmony_ci 359570af302Sopenharmony_ci/* const define */ 360570af302Sopenharmony_ci#define CONFIG_DEFAULT_FILE "/etc/ld-musl-namespace-arm.ini" /* default config file pathname */ 361570af302Sopenharmony_ci#define SECTION_DIR_MAP "section.dir.map" /* map of section and directory of app */ 362570af302Sopenharmony_ci#define ATTR_NS_PREFIX "namespace" /* prefix of namespace attribute */ 363570af302Sopenharmony_ci#define ATTR_NS_ASAN "asan" /* asan */ 364570af302Sopenharmony_ci#define ATTR_NS_LIB_PATHS "lib.paths" /* library search paths */ 365570af302Sopenharmony_ci#define ATTR_NS_PERMITTED_PATHS "permitted.paths" /* when separated, permitted dir paths of libs, including sub dirs */ 366570af302Sopenharmony_ci#define ATTR_NS_INHERITS "inherits" /* inherited namespace */ 367570af302Sopenharmony_ci#define ATTR_NS_SEPARATED "separated" /* if separated */ 368570af302Sopenharmony_ci#define ATTR_ADDED_NSLIST "added.nslist" /* all namespace names except default */ 369570af302Sopenharmony_ci#define ATTR_NS_DEFAULT "default" /* default namespace name */ 370570af302Sopenharmony_ci#define ATTR_NS_ACQUIESCENCE "acquiescence" /* acquiescence section name */ 371570af302Sopenharmony_ci#define ATTR_NS_ALLOWED_LIBS "allowed.libs" /* when separated, allowed library names */ 372570af302Sopenharmony_ci#define ATTR_NS_INHERIT_SHARED_LIBS "shared.libs" /* when inherited, shared library names */ 373570af302Sopenharmony_ci#define SECTION_DIR_MAP_SYSTEM "system" /* system path */ 374570af302Sopenharmony_ci#define SECTION_DIR_MAP_ASAN_SYSTEM "asan_system" /* asan system path */ 375570af302Sopenharmony_ci 376570af302Sopenharmony_ci/* get key-value list of section */ 377570af302Sopenharmony_cistatic kvlist *config_get_kvs(const char *sname) 378570af302Sopenharmony_ci{ 379570af302Sopenharmony_ci size_t i; 380570af302Sopenharmony_ci for (i = 0; i < g_configor.sections->num; i++) { 381570af302Sopenharmony_ci if (!strcmp(g_configor.sections->names[i], sname)) { 382570af302Sopenharmony_ci return g_configor.sections->kvs[i]; 383570af302Sopenharmony_ci } 384570af302Sopenharmony_ci } 385570af302Sopenharmony_ci return NULL; 386570af302Sopenharmony_ci} 387570af302Sopenharmony_ci 388570af302Sopenharmony_ci/* get value by acquiescence */ 389570af302Sopenharmony_cistatic char *config_get_value_by_acquiescence(kvlist *acquiescence_kvs, const char *key) 390570af302Sopenharmony_ci{ 391570af302Sopenharmony_ci if (!acquiescence_kvs) { 392570af302Sopenharmony_ci return NULL; 393570af302Sopenharmony_ci } 394570af302Sopenharmony_ci size_t i; 395570af302Sopenharmony_ci for (i = 0; i < acquiescence_kvs->num; i++) { 396570af302Sopenharmony_ci if (!strcmp(acquiescence_kvs->key[i], key)) { 397570af302Sopenharmony_ci return acquiescence_kvs->val[i]; 398570af302Sopenharmony_ci } 399570af302Sopenharmony_ci } 400570af302Sopenharmony_ci return NULL; 401570af302Sopenharmony_ci} 402570af302Sopenharmony_ci 403570af302Sopenharmony_ci/* get value by acquiescence lib path */ 404570af302Sopenharmony_cistatic char *config_get_acquiescence_lib_path(kvlist *acquiescence_kvs) 405570af302Sopenharmony_ci{ 406570af302Sopenharmony_ci if (!acquiescence_kvs) { 407570af302Sopenharmony_ci return NULL; 408570af302Sopenharmony_ci } 409570af302Sopenharmony_ci config_key_join(ATTR_NS_PREFIX, true); 410570af302Sopenharmony_ci config_key_join(".", false); 411570af302Sopenharmony_ci config_key_join(ATTR_NS_DEFAULT, false); 412570af302Sopenharmony_ci config_key_join(".", false); 413570af302Sopenharmony_ci char *key = config_key_join(ATTR_NS_LIB_PATHS, false); 414570af302Sopenharmony_ci return config_get_value_by_acquiescence(acquiescence_kvs, key); 415570af302Sopenharmony_ci} 416570af302Sopenharmony_ci 417570af302Sopenharmony_ci/* get value by acquiescence asan lib path */ 418570af302Sopenharmony_cistatic char *config_get_acquiescence_asan_lib_path(kvlist *acquiescence_kvs) 419570af302Sopenharmony_ci{ 420570af302Sopenharmony_ci if (!acquiescence_kvs) { 421570af302Sopenharmony_ci return NULL; 422570af302Sopenharmony_ci } 423570af302Sopenharmony_ci config_key_join(ATTR_NS_PREFIX, true); 424570af302Sopenharmony_ci config_key_join(".", false); 425570af302Sopenharmony_ci config_key_join(ATTR_NS_DEFAULT, false); 426570af302Sopenharmony_ci config_key_join(".", false); 427570af302Sopenharmony_ci config_key_join(ATTR_NS_ASAN, false); 428570af302Sopenharmony_ci config_key_join(".", false); 429570af302Sopenharmony_ci char *key = config_key_join(ATTR_NS_LIB_PATHS, false); 430570af302Sopenharmony_ci return config_get_value_by_acquiescence(acquiescence_kvs, key); 431570af302Sopenharmony_ci} 432570af302Sopenharmony_ci 433570af302Sopenharmony_ci/* get value by key */ 434570af302Sopenharmony_cistatic char *config_get_value(const char *key) 435570af302Sopenharmony_ci{ 436570af302Sopenharmony_ci if (!g_configor.kvs) { 437570af302Sopenharmony_ci return NULL; 438570af302Sopenharmony_ci } 439570af302Sopenharmony_ci size_t i; 440570af302Sopenharmony_ci for (i = 0; i < g_configor.kvs->num; i++) { 441570af302Sopenharmony_ci if (!strcmp(g_configor.kvs->key[i], key)) return g_configor.kvs->val[i]; 442570af302Sopenharmony_ci } 443570af302Sopenharmony_ci return NULL; 444570af302Sopenharmony_ci} 445570af302Sopenharmony_ci 446570af302Sopenharmony_ci/* get library search paths */ 447570af302Sopenharmony_cistatic char *config_get_lib_paths(const char *ns_name) 448570af302Sopenharmony_ci{ 449570af302Sopenharmony_ci if (ns_name == NULL) { 450570af302Sopenharmony_ci return NULL; 451570af302Sopenharmony_ci } 452570af302Sopenharmony_ci config_key_join(ATTR_NS_PREFIX, true); 453570af302Sopenharmony_ci config_key_join(".", false); 454570af302Sopenharmony_ci config_key_join(ns_name, false); 455570af302Sopenharmony_ci config_key_join(".", false); 456570af302Sopenharmony_ci char *key = config_key_join(ATTR_NS_LIB_PATHS, false); 457570af302Sopenharmony_ci return config_get_value(key); 458570af302Sopenharmony_ci} 459570af302Sopenharmony_ci 460570af302Sopenharmony_ci/* get asan library search paths */ 461570af302Sopenharmony_cistatic char *config_get_asan_lib_paths(const char *ns_name) 462570af302Sopenharmony_ci{ 463570af302Sopenharmony_ci if (ns_name == NULL) { 464570af302Sopenharmony_ci return NULL; 465570af302Sopenharmony_ci } 466570af302Sopenharmony_ci config_key_join(ATTR_NS_PREFIX, true); 467570af302Sopenharmony_ci config_key_join(".", false); 468570af302Sopenharmony_ci config_key_join(ns_name, false); 469570af302Sopenharmony_ci config_key_join(".", false); 470570af302Sopenharmony_ci config_key_join(ATTR_NS_ASAN, false); 471570af302Sopenharmony_ci config_key_join(".", false); 472570af302Sopenharmony_ci char *key = config_key_join(ATTR_NS_LIB_PATHS, false); 473570af302Sopenharmony_ci return config_get_value(key); 474570af302Sopenharmony_ci} 475570af302Sopenharmony_ci 476570af302Sopenharmony_ci/* parse config, success 0, failure <0 */ 477570af302Sopenharmony_cistatic int config_parse(const char *file_path, const char *exe_path) 478570af302Sopenharmony_ci{ 479570af302Sopenharmony_ci kvlist* dirkvs; 480570af302Sopenharmony_ci kvlist* acquiescence_kvs; 481570af302Sopenharmony_ci if (!exe_path) return -1; 482570af302Sopenharmony_ci g_configor.exe_path = ld_strdup(exe_path); 483570af302Sopenharmony_ci const char * fpath = CONFIG_DEFAULT_FILE; 484570af302Sopenharmony_ci if (file_path) fpath = file_path; 485570af302Sopenharmony_ci g_configor.file_path = ld_strdup(fpath); 486570af302Sopenharmony_ci g_configor.sections = config_load(fpath); 487570af302Sopenharmony_ci 488570af302Sopenharmony_ci if (!g_configor.sections) { 489570af302Sopenharmony_ci LD_LOGD("config_parse load ini config fail!"); 490570af302Sopenharmony_ci return -2; 491570af302Sopenharmony_ci } 492570af302Sopenharmony_ci dirkvs = config_get_kvs(SECTION_DIR_MAP); 493570af302Sopenharmony_ci acquiescence_kvs = config_get_kvs(ATTR_NS_ACQUIESCENCE); 494570af302Sopenharmony_ci if (!dirkvs || !acquiescence_kvs) { 495570af302Sopenharmony_ci LD_LOGD("config_parse get dirkvs or acquiescence_kvs fail!"); 496570af302Sopenharmony_ci return -3; /* no section directory map or acquiescence section found */ 497570af302Sopenharmony_ci } 498570af302Sopenharmony_ci g_configor.config_sys_path = config_get_acquiescence_lib_path(acquiescence_kvs); 499570af302Sopenharmony_ci g_configor.config_asan_sys_path = config_get_acquiescence_asan_lib_path(acquiescence_kvs); 500570af302Sopenharmony_ci size_t i; 501570af302Sopenharmony_ci char * sname = NULL; 502570af302Sopenharmony_ci for (i = 0; i < dirkvs->num; i++) { 503570af302Sopenharmony_ci strlist * paths = strsplit(dirkvs->val[i], ":"); 504570af302Sopenharmony_ci if (paths) { 505570af302Sopenharmony_ci size_t j; 506570af302Sopenharmony_ci for (j = 0; j < paths->num; j++) { 507570af302Sopenharmony_ci if (!strcmp(paths->strs[j], exe_path)) break; 508570af302Sopenharmony_ci } 509570af302Sopenharmony_ci if (j < paths->num) sname = dirkvs->key[i]; 510570af302Sopenharmony_ci } 511570af302Sopenharmony_ci strlist_free(paths); 512570af302Sopenharmony_ci if (sname) break; 513570af302Sopenharmony_ci } 514570af302Sopenharmony_ci if (!sname) { 515570af302Sopenharmony_ci /* No matched section found, use the default section. */ 516570af302Sopenharmony_ci sname = ATTR_NS_ACQUIESCENCE; 517570af302Sopenharmony_ci LD_LOGD("config_parse no section found!"); 518570af302Sopenharmony_ci } 519570af302Sopenharmony_ci if (!(g_configor.kvs = config_get_kvs(sname))) { 520570af302Sopenharmony_ci LD_LOGD("config_parse no section key-value list found!"); 521570af302Sopenharmony_ci return -5;/* no section key-value list found */ 522570af302Sopenharmony_ci } 523570af302Sopenharmony_ci 524570af302Sopenharmony_ci char *default_lib_paths = config_get_lib_paths(ATTR_NS_DEFAULT); 525570af302Sopenharmony_ci if (default_lib_paths) { 526570af302Sopenharmony_ci g_configor.config_sys_path = default_lib_paths; 527570af302Sopenharmony_ci } else { 528570af302Sopenharmony_ci LD_LOGW("config_parse get default lib paths fail! Config namespace default lib paths,please!"); 529570af302Sopenharmony_ci } 530570af302Sopenharmony_ci char *default_asan_lib_paths = config_get_asan_lib_paths(ATTR_NS_DEFAULT); 531570af302Sopenharmony_ci if (default_asan_lib_paths) { 532570af302Sopenharmony_ci g_configor.config_asan_sys_path = default_asan_lib_paths; 533570af302Sopenharmony_ci } else { 534570af302Sopenharmony_ci LD_LOGW("config_parse get default asan lib paths fail! Config namespace default asan lib paths,please!"); 535570af302Sopenharmony_ci } 536570af302Sopenharmony_ci return 0; 537570af302Sopenharmony_ci} 538570af302Sopenharmony_ci 539570af302Sopenharmony_ci/* get namespace names except default */ 540570af302Sopenharmony_cistatic strlist *config_get_namespaces() 541570af302Sopenharmony_ci{ 542570af302Sopenharmony_ci char *key = config_key_join(ATTR_ADDED_NSLIST, true); 543570af302Sopenharmony_ci char *val = config_get_value(key); 544570af302Sopenharmony_ci return strsplit(val, ","); 545570af302Sopenharmony_ci} 546570af302Sopenharmony_ci 547570af302Sopenharmony_ci/* get permitted paths */ 548570af302Sopenharmony_cistatic char *config_get_permitted_paths(const char *ns_name) 549570af302Sopenharmony_ci{ 550570af302Sopenharmony_ci if (ns_name == NULL) { 551570af302Sopenharmony_ci return NULL; 552570af302Sopenharmony_ci } 553570af302Sopenharmony_ci config_key_join(ATTR_NS_PREFIX, true); 554570af302Sopenharmony_ci config_key_join(".", false); 555570af302Sopenharmony_ci config_key_join(ns_name, false); 556570af302Sopenharmony_ci config_key_join(".", false); 557570af302Sopenharmony_ci char *key = config_key_join(ATTR_NS_PERMITTED_PATHS, false); 558570af302Sopenharmony_ci return config_get_value(key); 559570af302Sopenharmony_ci} 560570af302Sopenharmony_ci 561570af302Sopenharmony_ci/* get asan permitted paths */ 562570af302Sopenharmony_cistatic char *config_get_asan_permitted_paths(const char *ns_name) 563570af302Sopenharmony_ci{ 564570af302Sopenharmony_ci if (ns_name == NULL) { 565570af302Sopenharmony_ci return NULL; 566570af302Sopenharmony_ci } 567570af302Sopenharmony_ci config_key_join(ATTR_NS_PREFIX, true); 568570af302Sopenharmony_ci config_key_join(".", false); 569570af302Sopenharmony_ci config_key_join(ns_name, false); 570570af302Sopenharmony_ci config_key_join(".", false); 571570af302Sopenharmony_ci config_key_join(ATTR_NS_ASAN, false); 572570af302Sopenharmony_ci config_key_join(".", false); 573570af302Sopenharmony_ci char *key = config_key_join(ATTR_NS_PERMITTED_PATHS, false); 574570af302Sopenharmony_ci return config_get_value(key); 575570af302Sopenharmony_ci} 576570af302Sopenharmony_ci/* get inherited namespace names */ 577570af302Sopenharmony_cistatic strlist *config_get_inherits(const char *ns_name) 578570af302Sopenharmony_ci{ 579570af302Sopenharmony_ci if (ns_name == NULL) { 580570af302Sopenharmony_ci return NULL; 581570af302Sopenharmony_ci } 582570af302Sopenharmony_ci config_key_join(ATTR_NS_PREFIX, true); 583570af302Sopenharmony_ci config_key_join(".", false); 584570af302Sopenharmony_ci config_key_join(ns_name, false); 585570af302Sopenharmony_ci config_key_join(".", false); 586570af302Sopenharmony_ci char *key = config_key_join(ATTR_NS_INHERITS, false); 587570af302Sopenharmony_ci char *val = config_get_value(key); 588570af302Sopenharmony_ci return strsplit(val, ","); 589570af302Sopenharmony_ci} 590570af302Sopenharmony_ci/* get separated */ 591570af302Sopenharmony_cistatic bool config_get_separated(const char *ns_name) 592570af302Sopenharmony_ci{ 593570af302Sopenharmony_ci if (ns_name == NULL) { 594570af302Sopenharmony_ci return false; 595570af302Sopenharmony_ci } 596570af302Sopenharmony_ci config_key_join(ATTR_NS_PREFIX, true); 597570af302Sopenharmony_ci config_key_join(".", false); 598570af302Sopenharmony_ci config_key_join(ns_name, false); 599570af302Sopenharmony_ci config_key_join(".", false); 600570af302Sopenharmony_ci char *key = config_key_join(ATTR_NS_SEPARATED, false); 601570af302Sopenharmony_ci char *val = config_get_value(key); 602570af302Sopenharmony_ci strlwc(val); 603570af302Sopenharmony_ci if (val && !strcmp("true", val)) return true; 604570af302Sopenharmony_ci return false; /* default false */ 605570af302Sopenharmony_ci} 606570af302Sopenharmony_ci 607570af302Sopenharmony_ci/* get allowed libs */ 608570af302Sopenharmony_cistatic char *config_get_allowed_libs(const char *ns_name) 609570af302Sopenharmony_ci{ 610570af302Sopenharmony_ci if (ns_name == NULL) { 611570af302Sopenharmony_ci return NULL; 612570af302Sopenharmony_ci } 613570af302Sopenharmony_ci config_key_join(ATTR_NS_PREFIX, true); 614570af302Sopenharmony_ci config_key_join(".", false); 615570af302Sopenharmony_ci config_key_join(ns_name, false); 616570af302Sopenharmony_ci config_key_join(".", false); 617570af302Sopenharmony_ci char *key = config_key_join(ATTR_NS_ALLOWED_LIBS, false); 618570af302Sopenharmony_ci return config_get_value(key); 619570af302Sopenharmony_ci} 620570af302Sopenharmony_ci/* get shared libs by inherited namespace */ 621570af302Sopenharmony_cistatic char *config_get_inherit_shared_libs(const char *ns_name, const char *inherited_ns_name) 622570af302Sopenharmony_ci{ 623570af302Sopenharmony_ci if (ns_name == NULL || inherited_ns_name == NULL) { 624570af302Sopenharmony_ci return NULL; 625570af302Sopenharmony_ci } 626570af302Sopenharmony_ci config_key_join(ATTR_NS_PREFIX, true); 627570af302Sopenharmony_ci config_key_join(".", false); 628570af302Sopenharmony_ci config_key_join(ns_name, false); 629570af302Sopenharmony_ci config_key_join(".inherit.", false); 630570af302Sopenharmony_ci config_key_join(inherited_ns_name, false); 631570af302Sopenharmony_ci config_key_join(".", false); 632570af302Sopenharmony_ci char *key = config_key_join(ATTR_NS_INHERIT_SHARED_LIBS, false); 633570af302Sopenharmony_ci return config_get_value(key); 634570af302Sopenharmony_ci} 635570af302Sopenharmony_ci 636570af302Sopenharmony_ci/* The call time is after parse */ 637570af302Sopenharmony_cistatic char *config_get_sys_paths(void) 638570af302Sopenharmony_ci{ 639570af302Sopenharmony_ci return g_configor.config_sys_path; 640570af302Sopenharmony_ci} 641570af302Sopenharmony_cistatic char *config_get_asan_sys_paths(void) 642570af302Sopenharmony_ci{ 643570af302Sopenharmony_ci return g_configor.config_asan_sys_path; 644570af302Sopenharmony_ci} 645570af302Sopenharmony_cins_configor *configor_init() 646570af302Sopenharmony_ci{ 647570af302Sopenharmony_ci memset(&g_configor, 0, sizeof g_configor); 648570af302Sopenharmony_ci g_configor.set_error_callback = config_set_error_callback; 649570af302Sopenharmony_ci g_configor.parse = config_parse; 650570af302Sopenharmony_ci g_configor.get_namespaces = config_get_namespaces; 651570af302Sopenharmony_ci g_configor.get_lib_paths = config_get_lib_paths; 652570af302Sopenharmony_ci g_configor.get_asan_lib_paths = config_get_asan_lib_paths; 653570af302Sopenharmony_ci g_configor.get_permitted_paths = config_get_permitted_paths; 654570af302Sopenharmony_ci g_configor.get_asan_permitted_paths = config_get_asan_permitted_paths; 655570af302Sopenharmony_ci g_configor.get_separated = config_get_separated; 656570af302Sopenharmony_ci g_configor.get_inherits = config_get_inherits; 657570af302Sopenharmony_ci g_configor.get_allowed_libs = config_get_allowed_libs; 658570af302Sopenharmony_ci g_configor.get_inherit_shared_libs = config_get_inherit_shared_libs; 659570af302Sopenharmony_ci g_configor.get_sys_paths = config_get_sys_paths; 660570af302Sopenharmony_ci g_configor.get_asan_sys_paths = config_get_asan_sys_paths; 661570af302Sopenharmony_ci g_configor.config_sys_path = NULL; // init it in config_parse. 662570af302Sopenharmony_ci g_configor.config_asan_sys_path = NULL; // init it in config_parse. 663570af302Sopenharmony_ci return &g_configor; 664570af302Sopenharmony_ci} 665570af302Sopenharmony_ci 666570af302Sopenharmony_civoid configor_free() 667570af302Sopenharmony_ci{ 668570af302Sopenharmony_ci if (g_configor.sections) { 669570af302Sopenharmony_ci sections_free(g_configor.sections); 670570af302Sopenharmony_ci g_configor.sections = NULL; 671570af302Sopenharmony_ci } 672570af302Sopenharmony_ci if (g_configor.file_path) { 673570af302Sopenharmony_ci __libc_free(g_configor.file_path); 674570af302Sopenharmony_ci g_configor.file_path = NULL; 675570af302Sopenharmony_ci } 676570af302Sopenharmony_ci if (g_configor.exe_path) { 677570af302Sopenharmony_ci __libc_free(g_configor.exe_path); 678570af302Sopenharmony_ci g_configor.exe_path = NULL; 679570af302Sopenharmony_ci } 680570af302Sopenharmony_ci}