1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include "extract-word.h"
5 #include "ip-protocol-list.h"
7 #include "parse-helpers.h"
8 #include "parse-util.h"
12 int path_simplify_and_warn(
20 bool fatal
= flag
& PATH_CHECK_FATAL
;
22 assert(!FLAGS_SET(flag
, PATH_CHECK_ABSOLUTE
| PATH_CHECK_RELATIVE
));
24 if (!utf8_is_valid(path
))
25 return log_syntax_invalid_utf8(unit
, LOG_ERR
, filename
, line
, path
);
27 if (flag
& (PATH_CHECK_ABSOLUTE
| PATH_CHECK_RELATIVE
)) {
30 absolute
= path_is_absolute(path
);
32 if (!absolute
&& (flag
& PATH_CHECK_ABSOLUTE
))
33 return log_syntax(unit
, LOG_ERR
, filename
, line
, SYNTHETIC_ERRNO(EINVAL
),
34 "%s= path is not absolute%s: %s",
35 lvalue
, fatal
? "" : ", ignoring", path
);
37 if (absolute
&& (flag
& PATH_CHECK_RELATIVE
))
38 return log_syntax(unit
, LOG_ERR
, filename
, line
, SYNTHETIC_ERRNO(EINVAL
),
39 "%s= path is absolute%s: %s",
40 lvalue
, fatal
? "" : ", ignoring", path
);
45 if (!path_is_valid(path
))
46 return log_syntax(unit
, LOG_ERR
, filename
, line
, SYNTHETIC_ERRNO(EINVAL
),
47 "%s= path has invalid length (%zu bytes)%s.",
48 lvalue
, strlen(path
), fatal
? "" : ", ignoring");
50 if (!path_is_normalized(path
))
51 return log_syntax(unit
, LOG_ERR
, filename
, line
, SYNTHETIC_ERRNO(EINVAL
),
52 "%s= path is not normalized%s: %s",
53 lvalue
, fatal
? "" : ", ignoring", path
);
58 static int parse_af_token(
70 af
= af_from_ipv4_ipv6(token
);
78 static int parse_ip_protocol_token(
90 proto
= ip_protocol_from_tcp_udp(token
);
98 static int parse_ip_ports_token(
103 uint16_t *port_min
) {
109 if (streq(token
, "any"))
110 *nr_ports
= *port_min
= 0;
112 uint16_t mn
= 0, mx
= 0;
113 int r
= parse_ip_port_range(token
, &mn
, &mx
);
117 *nr_ports
= mx
- mn
+ 1;
124 typedef int (*parse_token_f
)(
131 int parse_socket_bind_item(
136 uint16_t *port_min
) {
138 /* Order of token parsers is important. */
139 const parse_token_f parsers
[] = {
141 &parse_ip_protocol_token
,
142 &parse_ip_ports_token
,
144 parse_token_f
const *parser_ptr
= parsers
;
145 int af
= AF_UNSPEC
, proto
= 0, r
;
146 uint16_t nr
= 0, mn
= 0;
147 const char *p
= ASSERT_PTR(str
);
149 assert(address_family
);
158 _cleanup_free_
char *token
= NULL
;
160 r
= extract_first_word(&p
, &token
, ":", EXTRACT_DONT_COALESCE_SEPARATORS
);
169 while (parser_ptr
!= parsers
+ ELEMENTSOF(parsers
)) {
170 r
= (*parser_ptr
)(token
, &af
, &proto
, &nr
, &mn
);
175 /* Continue to next token if parsing succeeded,
176 * otherwise apply next parser to the same token.
181 if (parser_ptr
== parsers
+ ELEMENTSOF(parsers
))
185 /* Failed to parse a token. */
189 /* Parsers applied successfully, but end of the string not reached. */
193 *address_family
= af
;
194 *ip_protocol
= proto
;