*ret = TAKE_PTR(n);
return 0;
}
+
+int split_user_at_host(const char *s, char **ret_user, char **ret_host) {
+ _cleanup_free_ char *u = NULL, *h = NULL;
+
+ /* Splits a user@host expression (one of those we accept on --machine= and similar). Returns NULL in
+ * each of the two return parameters if that part was left empty. */
+
+ const char *rhs = strchr(s, '@');
+ if (rhs) {
+ if (ret_user && rhs > s) {
+ u = strndup(s, rhs - s);
+ if (!u)
+ return -ENOMEM;
+ }
+
+ if (ret_host && rhs[1] != 0) {
+ h = strdup(rhs + 1);
+ if (!h)
+ return -ENOMEM;
+ }
+ } else if (!isempty(s) && ret_host) {
+ h = strdup(s);
+ if (!h)
+ return -ENOMEM;
+ }
+
+ if (ret_user)
+ *ret_user = TAKE_PTR(u);
+ if (ret_host)
+ *ret_host = TAKE_PTR(h);
+
+ return !!rhs; /* return > 0 if '@' was specified, 0 otherwise */
+}
ASSERT_STREQ(hostname_cleanup(s), "xxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
}
+static void test_split_user_at_host_one(const char *s, const char *expected_user, const char *expected_host, int ret) {
+ _cleanup_free_ char *u = NULL, *h = NULL;
+
+ ASSERT_OK_EQ(split_user_at_host(s, &u, &h), ret);
+ ASSERT_STREQ(u, expected_user);
+ ASSERT_STREQ(h, expected_host);
+
+ u = mfree(u);
+ h = mfree(h);
+
+ ASSERT_OK_EQ(split_user_at_host(s, &u, NULL), ret);
+ ASSERT_STREQ(u, expected_user);
+
+ ASSERT_OK_EQ(split_user_at_host(s, NULL, &h), ret);
+ ASSERT_STREQ(h, expected_host);
+}
+
+TEST(split_user_at_host) {
+ test_split_user_at_host_one("", NULL, NULL, 0);
+ test_split_user_at_host_one("@", NULL, NULL, 1);
+ test_split_user_at_host_one("a", NULL, "a", 0);
+ test_split_user_at_host_one("a@b", "a", "b", 1);
+ test_split_user_at_host_one("@b", NULL, "b", 1);
+ test_split_user_at_host_one("a@", "a", NULL, 1);
+ test_split_user_at_host_one("aa@@@bb", "aa", "@@bb", 1);
+}
+
DEFINE_TEST_MAIN(LOG_DEBUG);