
/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <fcntl.h>

#include "escape.h"
#include "extract-word.h"
#include "fd-util.h"
#include "open-file.h"
#include "path-util.h"
#include "string-table.h"
#include "string-util.h"

int open_file_parse(const char *v, OpenFile **ret) {
        _cleanup_free_ char *options = NULL;
        _cleanup_(open_file_freep) OpenFile *of = NULL;
        int r;

        assert(v);
        assert(ret);

        of = new0(OpenFile, 1);
        if (!of)
                return -ENOMEM;

        r = extract_many_words(&v, ":", EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_CUNESCAPE, &of->path, &of->fdname, &options, NULL);
        if (r < 0)
                return r;
        if (r == 0)
                return -EINVAL;

        /* Enforce that at most 3 colon-separated words are present */
        if (!isempty(v))
                return -EINVAL;

        for (const char *p = options;;) {
                OpenFileFlag flag;
                _cleanup_free_ char *word = NULL;

                r = extract_first_word(&p, &word, ",", 0);
                if (r < 0)
                        return r;
                if (r == 0)
                        break;

                flag = open_file_flags_from_string(word);
                if (flag < 0)
                        return flag;

                if ((flag & of->flags) != 0)
                        return -EINVAL;

                of->flags |= flag;
        }

        if (isempty(of->fdname)) {
                of->fdname = mfree(of->fdname);
                r = path_extract_filename(of->path, &of->fdname);
                if (r < 0)
                        return r;
        }

        r = open_file_validate(of);
        if (r < 0)
                return r;

        *ret = TAKE_PTR(of);

        return 0;
}

int open_file_validate(const OpenFile *of) {
        assert(of);

        if (!path_is_valid(of->path) || !path_is_absolute(of->path))
                return -EINVAL;

        if (!fdname_is_valid(of->fdname))
                return -EINVAL;

        if ((FLAGS_SET(of->flags, OPENFILE_READ_ONLY) + FLAGS_SET(of->flags, OPENFILE_APPEND) +
             FLAGS_SET(of->flags, OPENFILE_TRUNCATE)) > 1)
                return -EINVAL;

        if ((of->flags & ~_OPENFILE_MASK_PUBLIC) != 0)
                return -EINVAL;

        return 0;
}

int open_file_to_string(const OpenFile *of, char **ret) {
        _cleanup_free_ char *options = NULL, *fname = NULL, *s = NULL;
        bool has_fdname = false;
        int r;

        assert(of);
        assert(ret);

        s = shell_escape(of->path, ":");
        if (!s)
                return -ENOMEM;

        r = path_extract_filename(of->path, &fname);
        if (r < 0)
                return r;

        has_fdname = !streq(fname, of->fdname);
        if (has_fdname)
                if (!strextend(&s, ":", of->fdname))
                        return -ENOMEM;

        for (OpenFileFlag flag = OPENFILE_READ_ONLY; flag < _OPENFILE_MAX; flag <<= 1)
                if (FLAGS_SET(of->flags, flag) && !strextend_with_separator(&options, ",", open_file_flags_to_string(flag)))
                        return -ENOMEM;

        if (options)
                if (!(has_fdname ? strextend(&s, ":", options) : strextend(&s, "::", options)))
                        return -ENOMEM;

        *ret = TAKE_PTR(s);

        return 0;
}

OpenFile *open_file_free(OpenFile *of) {
        if (!of)
                return NULL;

        free(of->path);
        free(of->fdname);
        return mfree(of);
}

void open_file_free_many(OpenFile **head) {
        OpenFile *of;

        while ((of = *head)) {
                LIST_REMOVE(open_files, *head, of);
                of = open_file_free(of);
        }
}

static const char * const open_file_flags_table[_OPENFILE_MAX] = {
        [OPENFILE_READ_ONLY] = "read-only",
        [OPENFILE_APPEND]    = "append",
        [OPENFILE_TRUNCATE]  = "truncate",
        [OPENFILE_GRACEFUL]  = "graceful",
};

DEFINE_STRING_TABLE_LOOKUP(open_file_flags, OpenFileFlag);
