|
4 | 4 | * @author Michal Vasko <[email protected]>
|
5 | 5 | * @brief Context implementations
|
6 | 6 | *
|
7 |
| - * Copyright (c) 2015 - 2023 CESNET, z.s.p.o. |
| 7 | + * Copyright (c) 2015 - 2024 CESNET, z.s.p.o. |
8 | 8 | *
|
9 | 9 | * This source code is licensed under BSD 3-Clause License (the "License").
|
10 | 10 | * You may not use this file except in compliance with the License.
|
@@ -81,57 +81,75 @@ static struct internal_modules_s {
|
81 | 81 | LIBYANG_API_DEF LY_ERR
|
82 | 82 | ly_ctx_set_searchdir(struct ly_ctx *ctx, const char *search_dir)
|
83 | 83 | {
|
| 84 | + int rc = LY_SUCCESS; |
84 | 85 | struct stat st;
|
85 | 86 | char *new_dir = NULL;
|
| 87 | + uint32_t i; |
| 88 | + LY_ARRAY_COUNT_TYPE u; |
| 89 | + struct lys_module *mod; |
86 | 90 |
|
87 | 91 | LY_CHECK_ARG_RET(ctx, ctx, LY_EINVAL);
|
88 | 92 |
|
89 |
| - if (search_dir) { |
90 |
| - new_dir = realpath(search_dir, NULL); |
91 |
| - LY_CHECK_ERR_RET(!new_dir, |
92 |
| - LOGERR(ctx, LY_ESYS, "Unable to use search directory \"%s\" (%s).", search_dir, strerror(errno)), |
93 |
| - LY_EINVAL); |
94 |
| - if (strcmp(search_dir, new_dir)) { |
95 |
| - LOGVRB("Search directory string \"%s\" canonized to \"%s\".", search_dir, new_dir); |
96 |
| - } |
97 |
| - LY_CHECK_ERR_RET(access(new_dir, R_OK | X_OK), |
98 |
| - LOGERR(ctx, LY_ESYS, "Unable to fully access search directory \"%s\" (%s).", new_dir, strerror(errno)); free(new_dir), |
99 |
| - LY_EINVAL); |
100 |
| - LY_CHECK_ERR_RET(stat(new_dir, &st), |
101 |
| - LOGERR(ctx, LY_ESYS, "stat() failed for \"%s\" (%s).", new_dir, strerror(errno)); free(new_dir), |
102 |
| - LY_ESYS); |
103 |
| - LY_CHECK_ERR_RET(!S_ISDIR(st.st_mode), |
104 |
| - LOGERR(ctx, LY_ESYS, "Given search directory \"%s\" is not a directory.", new_dir); free(new_dir), |
105 |
| - LY_EINVAL); |
106 |
| - /* avoid path duplication */ |
107 |
| - for (uint32_t u = 0; u < ctx->search_paths.count; ++u) { |
108 |
| - if (!strcmp(new_dir, ctx->search_paths.objs[u])) { |
109 |
| - free(new_dir); |
110 |
| - return LY_EEXIST; |
111 |
| - } |
112 |
| - } |
113 |
| - if (ly_set_add(&ctx->search_paths, new_dir, 1, NULL)) { |
114 |
| - free(new_dir); |
115 |
| - return LY_EMEM; |
| 93 | + if (!search_dir) { |
| 94 | + /* fine, ignore */ |
| 95 | + goto cleanup; |
| 96 | + } |
| 97 | + |
| 98 | + new_dir = realpath(search_dir, NULL); |
| 99 | + if (!new_dir) { |
| 100 | + LOGERR(ctx, LY_ESYS, "Unable to use search directory \"%s\" (%s).", search_dir, strerror(errno)), |
| 101 | + rc = LY_EINVAL; |
| 102 | + goto cleanup; |
| 103 | + } |
| 104 | + if (strcmp(search_dir, new_dir)) { |
| 105 | + LOGVRB("Search directory string \"%s\" canonized to \"%s\".", search_dir, new_dir); |
| 106 | + } |
| 107 | + |
| 108 | + if (access(new_dir, R_OK | X_OK)) { |
| 109 | + LOGERR(ctx, LY_ESYS, "Unable to fully access search directory \"%s\" (%s).", new_dir, strerror(errno)); |
| 110 | + rc = LY_EINVAL; |
| 111 | + goto cleanup; |
| 112 | + } |
| 113 | + if (stat(new_dir, &st)) { |
| 114 | + LOGERR(ctx, LY_ESYS, "stat() failed for \"%s\" (%s).", new_dir, strerror(errno)); |
| 115 | + rc = LY_ESYS; |
| 116 | + goto cleanup; |
| 117 | + } |
| 118 | + if (!S_ISDIR(st.st_mode)) { |
| 119 | + LOGERR(ctx, LY_ESYS, "Given search directory \"%s\" is not a directory.", new_dir); |
| 120 | + rc = LY_EINVAL; |
| 121 | + goto cleanup; |
| 122 | + } |
| 123 | + |
| 124 | + /* avoid path duplication */ |
| 125 | + for (i = 0; i < ctx->search_paths.count; ++i) { |
| 126 | + if (!strcmp(new_dir, ctx->search_paths.objs[i])) { |
| 127 | + rc = LY_EEXIST; |
| 128 | + goto cleanup; |
116 | 129 | }
|
| 130 | + } |
| 131 | + if (ly_set_add(&ctx->search_paths, new_dir, 1, NULL)) { |
| 132 | + rc = LY_EMEM; |
| 133 | + goto cleanup; |
| 134 | + } |
117 | 135 |
|
118 |
| - /* new searchdir - reset latests flags (possibly new revisions available) */ |
119 |
| - for (uint32_t v = 0; v < ctx->list.count; ++v) { |
120 |
| - struct lys_module *mod = ctx->list.objs[v]; |
| 136 | + /* new searchdir - reset latests flags (possibly new revisions available) */ |
| 137 | + for (i = 0; i < ctx->list.count; ++i) { |
| 138 | + mod = ctx->list.objs[i]; |
121 | 139 |
|
122 |
| - mod->latest_revision &= ~LYS_MOD_LATEST_SEARCHDIRS; |
123 |
| - if (mod->parsed && mod->parsed->includes) { |
124 |
| - for (LY_ARRAY_COUNT_TYPE u = 0; u < LY_ARRAY_COUNT(mod->parsed->includes); ++u) { |
125 |
| - mod->parsed->includes[u].submodule->latest_revision &= ~LYS_MOD_LATEST_SEARCHDIRS; |
126 |
| - } |
| 140 | + mod->latest_revision &= ~LYS_MOD_LATEST_SEARCHDIRS; |
| 141 | + if (mod->parsed && mod->parsed->includes) { |
| 142 | + for (u = 0; u < LY_ARRAY_COUNT(mod->parsed->includes); ++u) { |
| 143 | + mod->parsed->includes[u].submodule->latest_revision &= ~LYS_MOD_LATEST_SEARCHDIRS; |
127 | 144 | }
|
128 | 145 | }
|
| 146 | + } |
129 | 147 |
|
130 |
| - return LY_SUCCESS; |
131 |
| - } else { |
132 |
| - /* consider that no change is not actually an error */ |
133 |
| - return LY_SUCCESS; |
| 148 | +cleanup: |
| 149 | + if (rc) { |
| 150 | + free(new_dir); |
134 | 151 | }
|
| 152 | + return rc; |
135 | 153 | }
|
136 | 154 |
|
137 | 155 | LIBYANG_API_DEF const char * const *
|
|
0 commit comments