2 /* SPDX-License-Identifier: LGPL-2.1-or-later */
7 #include "extract-word.h"
10 #include "path-util.h"
11 #include "string-table.h"
12 #include "string-util.h"
14 int open_file_parse(const char *v
, OpenFile
**ret
) {
15 _cleanup_free_
char *options
= NULL
;
16 _cleanup_(open_file_freep
) OpenFile
*of
= NULL
;
22 of
= new0(OpenFile
, 1);
26 r
= extract_many_words(&v
, ":", EXTRACT_DONT_COALESCE_SEPARATORS
|EXTRACT_CUNESCAPE
, &of
->path
, &of
->fdname
, &options
);
32 /* Enforce that at most 3 colon-separated words are present */
36 for (const char *p
= options
;;) {
38 _cleanup_free_
char *word
= NULL
;
40 r
= extract_first_word(&p
, &word
, ",", 0);
46 flag
= open_file_flags_from_string(word
);
50 if ((flag
& of
->flags
) != 0)
56 if (isempty(of
->fdname
)) {
57 of
->fdname
= mfree(of
->fdname
);
58 r
= path_extract_filename(of
->path
, &of
->fdname
);
63 r
= open_file_validate(of
);
72 int open_file_validate(const OpenFile
*of
) {
75 if (!path_is_valid(of
->path
) || !path_is_absolute(of
->path
))
78 if (!fdname_is_valid(of
->fdname
))
81 if ((FLAGS_SET(of
->flags
, OPENFILE_READ_ONLY
) + FLAGS_SET(of
->flags
, OPENFILE_APPEND
) +
82 FLAGS_SET(of
->flags
, OPENFILE_TRUNCATE
)) > 1)
85 if ((of
->flags
& ~_OPENFILE_MASK_PUBLIC
) != 0)
91 int open_file_to_string(const OpenFile
*of
, char **ret
) {
92 _cleanup_free_
char *options
= NULL
, *fname
= NULL
, *s
= NULL
;
93 bool has_fdname
= false;
99 s
= shell_escape(of
->path
, ":");
103 r
= path_extract_filename(of
->path
, &fname
);
107 has_fdname
= !streq(fname
, of
->fdname
);
109 if (!strextend(&s
, ":", of
->fdname
))
112 for (OpenFileFlag flag
= OPENFILE_READ_ONLY
; flag
< _OPENFILE_MAX
; flag
<<= 1)
113 if (FLAGS_SET(of
->flags
, flag
) && !strextend_with_separator(&options
, ",", open_file_flags_to_string(flag
)))
117 if (!(has_fdname
? strextend(&s
, ":", options
) : strextend(&s
, "::", options
)))
125 OpenFile
*open_file_free(OpenFile
*of
) {
134 void open_file_free_many(OpenFile
**head
) {
137 LIST_CLEAR(open_files
, *head
, open_file_free
);
140 static const char * const open_file_flags_table
[_OPENFILE_MAX
] = {
141 [OPENFILE_READ_ONLY
] = "read-only",
142 [OPENFILE_APPEND
] = "append",
143 [OPENFILE_TRUNCATE
] = "truncate",
144 [OPENFILE_GRACEFUL
] = "graceful",
147 DEFINE_STRING_TABLE_LOOKUP(open_file_flags
, OpenFileFlag
);