context BUGFIX check for directory and dupplicity of searchpath in ly_ctx_set_searchdir()
#include <limits.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <unistd.h>
#include "context.h"
@@ -63,25 +65,40 @@ static struct internal_modules_s {
API LY_ERR
ly_ctx_set_searchdir(struct ly_ctx *ctx, const char *search_dir)
{
+ struct stat st;
char *new_dir = NULL;
LY_ERR rc = LY_ESYS;
+ unsigned int u;
LY_CHECK_ARG_RET(ctx, ctx, LY_EINVAL);
if (search_dir) {
- LY_CHECK_ERR_GOTO(access(search_dir, R_OK | X_OK),
+ LY_CHECK_ERR_RET(access(search_dir, R_OK | X_OK),
LOGERR(ctx, LY_ESYS, "Unable to use search directory \"%s\" (%s)", search_dir, strerror(errno)),
- cleanup);
+ LY_EINVAL);
+ LY_CHECK_ERR_RET(stat(search_dir, &st),
+ LOGERR(ctx, LY_ESYS, "stat() failed for \"%s\" (%s)", search_dir, strerror(errno)),
+ LY_ESYS);
+ LY_CHECK_ERR_RET(!S_ISDIR(st.st_mode),
+ LOGERR(ctx, LY_ESYS, "Given search directory \"%s\" is not a directory.", search_dir),
+ LY_EINVAL);
new_dir = realpath(search_dir, NULL);
LY_CHECK_ERR_GOTO(!new_dir,
LOGERR(ctx, LY_ESYS, "realpath() call failed for \"%s\" (%s).", search_dir, strerror(errno)),
cleanup);
- if (ly_set_add(&ctx->search_paths, new_dir, 0) == -1) {
+ /* avoid path duplication */
+ for (u = 0; u < ctx->search_paths.count; ++u) {
+ if (!strcmp(new_dir, ctx->search_paths.objs[0])) {
+ free(new_dir);
+ return LY_SUCCESS;
+ }
+ }
+ if (ly_set_add(&ctx->search_paths, new_dir, LY_SET_OPT_USEASLIST) == -1) {
free(new_dir);
return LY_EMEM;
}
- rc = LY_SUCCESS;
+ return LY_SUCCESS;
} else {
/* consider that no change is not actually an error */
return LY_SUCCESS;
