c += strspn(c, DIGITS);
if (*c == '-') {
/* A connector DRM device, let's ignore all but LVDS and eDP! */
-
- if (!startswith(c, "-LVDS-") &&
- !startswith(c, "-Embedded DisplayPort-"))
+ if (!STARTSWITH_SET(c, "-LVDS-", "-Embedded DisplayPort-"))
return -EOPNOTSUPP;
}
* needs free()! */
if (IN_SET(p[0], 0, '_', '.') ||
- streq(p, "notify_on_release") ||
- streq(p, "release_agent") ||
- streq(p, "tasks") ||
+ STR_IN_SET(p, "notify_on_release", "release_agent", "tasks") ||
startswith(p, "cgroup."))
need_prefix = true;
else {
/* Like valid_device_node_path(), but also allows full-subsystem expressions, like DeviceAllow= and DeviceDeny=
* accept it */
- if (startswith(path, "block-") ||
- startswith(path, "char-"))
+ if (STARTSWITH_SET(path, "block-", "char-"))
return true;
return valid_device_node_path(path);
#define PATH_STARTSWITH_SET(p, ...) \
({ \
- char **s; \
- bool _found = false; \
- STRV_FOREACH(s, STRV_MAKE(__VA_ARGS__)) \
- if (path_startswith(p, *s)) { \
- _found = true; \
- break; \
- } \
+ const char *_p = (p); \
+ char *_found = NULL, **_i; \
+ STRV_FOREACH(_i, STRV_MAKE(__VA_ARGS__)) { \
+ _found = path_startswith(_p, *_i); \
+ if (_found) \
+ break; \
+ } \
_found; \
})
_x && strv_contains(STRV_MAKE(__VA_ARGS__), _x); \
})
+#define STARTSWITH_SET(p, ...) \
+ ({ \
+ const char *_p = (p); \
+ char *_found = NULL, **_i; \
+ STRV_FOREACH(_i, STRV_MAKE(__VA_ARGS__)) { \
+ _found = startswith(_p, *_i); \
+ if (_found) \
+ break; \
+ } \
+ _found; \
+ })
+
#define FOREACH_STRING(x, ...) \
for (char **_l = ({ \
char **_ll = STRV_MAKE(__VA_ARGS__); \
return -ENOMEM;
}
} else {
- if (startswith(s, "/dev/"))
- p = s + 5;
- else if (startswith(s, "../"))
- p = s + 3;
- else
+ p = PATH_STARTSWITH_SET(s, "/dev/", "../");
+ if (!p)
p = s;
b = strdup(p);
if (r < 0)
return r; /* returns EINVAL if not a symlink */
- e = path_startswith(t, "/usr/share/zoneinfo/");
- if (!e)
- e = path_startswith(t, "../usr/share/zoneinfo/");
+ e = PATH_STARTSWITH_SET(t, "/usr/share/zoneinfo/", "../usr/share/zoneinfo/");
if (!e)
return -EINVAL;
return 0;
}
- if (!startswith(resolved, "block-") && !startswith(resolved, "char-")) {
+ if (!STARTSWITH_SET(resolved, "block-", "char-")) {
r = path_simplify_and_warn(resolved, 0, unit, filename, line, lvalue);
if (r < 0)
#include "process-util.h"
#include "signal-util.h"
#include "string-util.h"
+#include "strv.h"
#include "umount.h"
#include "util.h"
#include "virt.h"
continue;
}
- uuid = startswith(device, "UUID=");
+ uuid = STARTSWITH_SET(device, "UUID=", "luks-");
if (!uuid)
uuid = path_startswith(device, "/dev/disk/by-uuid/");
- if (!uuid)
- uuid = startswith(name, "luks-");
if (uuid)
d = hashmap_get(arg_disks, uuid);
if (arg_url) {
const char *url;
- char *hostname, *p;
+ char *hostname;
if (!strstr(arg_url, "/entries")) {
if (endswith(arg_url, "/"))
url = strjoina(arg_url, "entries");
else
url = strjoina(arg_url, "/entries");
- }
- else
+ } else
url = strdupa(arg_url);
log_info("Spawning curl %s...", url);
if (fd < 0)
return fd;
- hostname =
- startswith(arg_url, "https://") ?:
- startswith(arg_url, "http://") ?:
- arg_url;
+ hostname = STARTSWITH_SET(arg_url, "https://", "http://");
+ if (!hostname)
+ hostname = arg_url;
- hostname = strdupa(hostname);
- if ((p = strchr(hostname, '/')))
- *p = '\0';
- if ((p = strchr(hostname, ':')))
- *p = '\0';
+ hostname = strndupa(hostname, strcspn(hostname, "/:"));
r = journal_remote_add_source(s, fd, hostname, false);
if (r < 0)
#include "sigbus.h"
#include "signal-util.h"
#include "string-util.h"
+#include "strv.h"
#include "util.h"
#define PRIV_KEY_FILE CERTIFICATE_ROOT "/private/journal-upload.pem"
assert(u);
assert(url);
- memzero(u, sizeof(Uploader));
- u->input = -1;
+ *u = (Uploader) {
+ .input = -1
+ };
- if (!(host = startswith(url, "http://")) && !(host = startswith(url, "https://"))) {
+ host = STARTSWITH_SET(url, "http://", "https://");
+ if (!host) {
host = url;
proto = "https://";
}
#include "selinux-util.h"
#include "socket-util.h"
#include "string-util.h"
+#include "strv.h"
#include "unaligned.h"
static bool allow_object_pid(const struct ucred *ucred) {
return;
}
- e = path_startswith(k, "/dev/shm/");
- if (!e)
- e = path_startswith(k, "/tmp/");
- if (!e)
- e = path_startswith(k, "/var/tmp/");
+ e = PATH_STARTSWITH_SET(k, "/dev/shm/", "/tmp/", "/var/tmp/");
if (!e) {
log_error("Received file outside of allowed directories. Refusing.");
return;
tilded = strjoina(full, "~");
atted = strjoina(prefix, "@");
- return streq(filename, full) ||
- streq(filename, tilded) ||
+ return STR_IN_SET(filename, full, tilded) ||
startswith(filename, atted);
}
return r;
FOREACH_DEVICE(e, d) {
+ const char *status, *enabled, *dash, *nn, *subsys;
sd_device *p;
- const char *status, *enabled, *dash, *nn, *i, *subsys;
- bool external = false;
if (sd_device_get_parent(d, &p) < 0)
continue;
continue;
dash++;
- FOREACH_STRING(i, "VGA-", "DVI-I-", "DVI-D-", "DVI-A-"
- "Composite-", "SVIDEO-", "Component-",
- "DIN-", "DP-", "HDMI-A-", "HDMI-B-", "TV-") {
-
- if (startswith(dash, i)) {
- external = true;
- break;
- }
- }
- if (!external)
+ if (!STARTSWITH_SET(dash,
+ "VGA-", "DVI-I-", "DVI-D-", "DVI-A-"
+ "Composite-", "SVIDEO-", "Component-",
+ "DIN-", "DP-", "HDMI-A-", "HDMI-B-", "TV-"))
continue;
/* Ignore ports that are not enabled */
}
static const char *timezone_from_path(const char *path) {
- const char *z;
-
- z = path_startswith(path, "../usr/share/zoneinfo/");
- if (z)
- return z;
-
- z = path_startswith(path, "/usr/share/zoneinfo/");
- if (z)
- return z;
-
- return NULL;
+ return PATH_STARTSWITH_SET(
+ path,
+ "../usr/share/zoneinfo/",
+ "/usr/share/zoneinfo/");
}
static int setup_timezone(const char *dest) {
return log_oom();
with_timer = with_timer ||
- !!startswith(optarg, "OnActiveSec=") ||
- !!startswith(optarg, "OnBootSec=") ||
- !!startswith(optarg, "OnStartupSec=") ||
- !!startswith(optarg, "OnUnitActiveSec=") ||
- !!startswith(optarg, "OnUnitInactiveSec=") ||
- !!startswith(optarg, "OnCalendar=");
+ STARTSWITH_SET(optarg,
+ "OnActiveSec=",
+ "OnBootSec=",
+ "OnStartupSec=",
+ "OnUnitActiveSec=",
+ "OnUnitInactiveSec=",
+ "OnCalendar=");
break;
case ARG_PATH_PROPERTY:
STRV_FOREACH(entry, split) {
char *p;
- p = startswith(*entry, "default:");
+ p = STARTSWITH_SET(*entry, "default:", "d:");
if (!p)
- p = startswith(*entry, "d:");
+ p = *entry;
- if (p)
- r = strv_push(&d, p);
- else
- r = strv_push(&a, *entry);
+ r = strv_push(&d, p);
if (r < 0)
return r;
}
#include <stdbool.h>
#include "string-util.h"
+#include "strv.h"
#include "utf8.h"
#include "web-util.h"
if (!endswith(etag, "\""))
return false;
- if (!startswith(etag, "\"") && !startswith(etag, "W/\""))
+ if (!STARTSWITH_SET(etag, "\"", "W/\""))
return false;
return true;
if (isempty(url))
return false;
- p = startswith(url, "http://");
- if (!p)
- p = startswith(url, "https://");
+ p = STARTSWITH_SET(url, "http://", "https://");
if (!p)
return false;
if (http_url_is_valid(url))
return true;
- p = startswith(url, "file:/");
- if (!p)
- p = startswith(url, "info:");
- if (!p)
- p = startswith(url, "man:");
-
+ p = STARTSWITH_SET(url, "file:/", "info:", "man:");
if (isempty(p))
return false;
assert_se(!empty_or_root("//yy//"));
}
+static void test_path_startswith_set(void) {
+
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/foo/bar", "/zzz"), ""));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/foo/", "/zzz"), "bar"));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/foo", "/zzz"), "bar"));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "/", "/zzz"), "foo/bar"));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar", "/foo/quux", "", "/zzz"), NULL));
+
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar2", "/foo/quux", "/foo/bar", "/zzz"), NULL));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar2", "/foo/quux", "/foo/", "/zzz"), "bar2"));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar2", "/foo/quux", "/foo", "/zzz"), "bar2"));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar2", "/foo/quux", "/", "/zzz"), "foo/bar2"));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo/bar2", "/foo/quux", "", "/zzz"), NULL));
+
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo2/bar", "/foo/quux", "/foo/bar", "/zzz"), NULL));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo2/bar", "/foo/quux", "/foo/", "/zzz"), NULL));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo2/bar", "/foo/quux", "/foo", "/zzz"), NULL));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo2/bar", "/foo/quux", "/", "/zzz"), "foo2/bar"));
+ assert_se(streq_ptr(PATH_STARTSWITH_SET("/foo2/bar", "/foo/quux", "", "/zzz"), NULL));
+}
+
int main(int argc, char **argv) {
test_setup_logging(LOG_DEBUG);
test_hidden_or_backup_file();
test_skip_dev_prefix();
test_empty_or_root();
+ test_path_startswith_set();
test_systemd_installation_has_version(argv[1]); /* NULL is OK */
assert_se(!STRPTR_IN_SET(NULL, NULL));
}
+static void test_startswith_set(void) {
+ assert_se(!STARTSWITH_SET("foo", "bar", "baz", "waldo"));
+ assert_se(!STARTSWITH_SET("foo", "bar"));
+
+ assert_se(STARTSWITH_SET("abc", "a", "ab", "abc"));
+ assert_se(STARTSWITH_SET("abc", "ax", "ab", "abc"));
+ assert_se(STARTSWITH_SET("abc", "ax", "abx", "abc"));
+ assert_se(!STARTSWITH_SET("abc", "ax", "abx", "abcx"));
+
+ assert_se(streq_ptr(STARTSWITH_SET("foobar", "hhh", "kkk", "foo", "zzz"), "bar"));
+ assert_se(streq_ptr(STARTSWITH_SET("foobar", "hhh", "kkk", "", "zzz"), "foobar"));
+ assert_se(streq_ptr(STARTSWITH_SET("", "hhh", "kkk", "zzz", ""), ""));
+}
+
static const char* const input_table_multiple[] = {
"one",
"two",
test_specifier_printf();
test_str_in_set();
test_strptr_in_set();
+ test_startswith_set();
test_strv_foreach();
test_strv_foreach_backwards();
test_strv_foreach_pair();
#include "signal-util.h"
#include "socket-util.h"
#include "string-util.h"
+#include "strv.h"
#include "strxcpyx.h"
#include "syslog-util.h"
#include "udev-builtin.h"
if (r < 0)
return log_device_debug_errno(dev, r, "Failed to get sysname: %m");
- if (startswith(val, "dm-") ||
- startswith(val, "md") ||
- startswith(val, "drbd"))
+ if (STARTSWITH_SET(val, "dm-", "md", "drbd"))
return 0;
r = sd_device_get_devtype(dev, &val);