示例#1
0
static void test_unoctchar(void) {
        assert_se(unoctchar('0') == 00);
        assert_se(unoctchar('7') == 07);
}
示例#2
0
static void test_socket_address_parse(void) {
        SocketAddress a;

        assert_se(socket_address_parse(&a, "junk") < 0);
        assert_se(socket_address_parse(&a, "192.168.1.1") < 0);
        assert_se(socket_address_parse(&a, ".168.1.1") < 0);
        assert_se(socket_address_parse(&a, "989.168.1.1") < 0);
        assert_se(socket_address_parse(&a, "192.168.1.1:65536") < 0);
        assert_se(socket_address_parse(&a, "192.168.1.1:0") < 0);
        assert_se(socket_address_parse(&a, "0") < 0);
        assert_se(socket_address_parse(&a, "65536") < 0);

        assert_se(socket_address_parse(&a, "65535") >= 0);

        if (socket_ipv6_is_supported()) {
                assert_se(socket_address_parse(&a, "[::1]") < 0);
                assert_se(socket_address_parse(&a, "[::1]8888") < 0);
                assert_se(socket_address_parse(&a, "::1") < 0);
                assert_se(socket_address_parse(&a, "[::1]:0") < 0);
                assert_se(socket_address_parse(&a, "[::1]:65536") < 0);
                assert_se(socket_address_parse(&a, "[a:b:1]:8888") < 0);

                assert_se(socket_address_parse(&a, "8888") >= 0);
                assert_se(a.sockaddr.sa.sa_family == AF_INET6);

                assert_se(socket_address_parse(&a, "[2001:0db8:0000:85a3:0000:0000:ac1f:8001]:8888") >= 0);
                assert_se(a.sockaddr.sa.sa_family == AF_INET6);

                assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
                assert_se(a.sockaddr.sa.sa_family == AF_INET6);
        } else {
                assert_se(socket_address_parse(&a, "[::1]:8888") < 0);

                assert_se(socket_address_parse(&a, "8888") >= 0);
                assert_se(a.sockaddr.sa.sa_family == AF_INET);
        }

        assert_se(socket_address_parse(&a, "192.168.1.254:8888") >= 0);
        assert_se(a.sockaddr.sa.sa_family == AF_INET);

        assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
        assert_se(a.sockaddr.sa.sa_family == AF_UNIX);

        assert_se(socket_address_parse(&a, "@abstract") >= 0);
        assert_se(a.sockaddr.sa.sa_family == AF_UNIX);
}
示例#3
0
static void test_address_equality(void) {
        _cleanup_address_free_ Address *a1 = NULL, *a2 = NULL;

        assert_se(address_new_dynamic(&a1) >= 0);
        assert_se(address_new_dynamic(&a2) >= 0);

        assert_se(address_equal(NULL, NULL));
        assert_se(!address_equal(a1, NULL));
        assert_se(!address_equal(NULL, a2));
        assert_se(address_equal(a1, a2));

        a1->family = AF_INET;
        assert_se(!address_equal(a1, a2));

        a2->family = AF_INET;
        assert_se(address_equal(a1, a2));

        assert_se(inet_pton(AF_INET, "192.168.3.9", &a1->in_addr.in));
        assert_se(address_equal(a1, a2));
        assert_se(inet_pton(AF_INET, "192.168.3.9", &a2->in_addr.in));
        assert_se(address_equal(a1, a2));
        a1->prefixlen = 10;
        assert_se(!address_equal(a1, a2));
        a2->prefixlen = 10;
        assert_se(address_equal(a1, a2));

        assert_se(inet_pton(AF_INET, "192.168.3.10", &a2->in_addr.in));
        assert_se(address_equal(a1, a2));

        a1->family = AF_INET6;
        assert_se(!address_equal(a1, a2));

        a2->family = AF_INET6;
        assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a1->in_addr.in6));
        assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::2", &a2->in_addr.in6));
        assert_se(address_equal(a1, a2));

        a2->prefixlen = 8;
        assert_se(address_equal(a1, a2));

        assert_se(inet_pton(AF_INET6, "2001:4ca0:4f01::1", &a2->in_addr.in6));
        assert_se(!address_equal(a1, a2));
}
示例#4
0
static void test_strextend(void) {
        _cleanup_free_ char *str = strdup("0123");
        strextend(&str, "456", "78", "9", NULL);
        assert_se(streq(str, "0123456789"));
}
示例#5
0
static void test_ascii_strcasecmp_n(void) {

        assert_se(ascii_strcasecmp_n("", "", 0) == 0);
        assert_se(ascii_strcasecmp_n("", "", 1) == 0);
        assert_se(ascii_strcasecmp_n("", "a", 1) < 0);
        assert_se(ascii_strcasecmp_n("", "a", 2) < 0);
        assert_se(ascii_strcasecmp_n("a", "", 1) > 0);
        assert_se(ascii_strcasecmp_n("a", "", 2) > 0);
        assert_se(ascii_strcasecmp_n("a", "a", 1) == 0);
        assert_se(ascii_strcasecmp_n("a", "a", 2) == 0);
        assert_se(ascii_strcasecmp_n("a", "b", 1) < 0);
        assert_se(ascii_strcasecmp_n("a", "b", 2) < 0);
        assert_se(ascii_strcasecmp_n("b", "a", 1) > 0);
        assert_se(ascii_strcasecmp_n("b", "a", 2) > 0);
        assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxYxxxx", 9) == 0);
        assert_se(ascii_strcasecmp_n("xxxxxxxxx", "xxxxyxxxx", 9) < 0);
        assert_se(ascii_strcasecmp_n("xxxxXxxxx", "xxxxyxxxx", 9) < 0);
        assert_se(ascii_strcasecmp_n("xxxxxxxxx", "xxxxYxxxx", 9) < 0);
        assert_se(ascii_strcasecmp_n("xxxxXxxxx", "xxxxYxxxx", 9) < 0);

        assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxYxxxx", 9) == 0);
        assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxxxxxx", 9) > 0);
        assert_se(ascii_strcasecmp_n("xxxxyxxxx", "xxxxXxxxx", 9) > 0);
        assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxxxxxx", 9) > 0);
        assert_se(ascii_strcasecmp_n("xxxxYxxxx", "xxxxXxxxx", 9) > 0);
}
示例#6
0
int uname_architecture(void) {

        /* Return a sanitized enum identifying the architecture we are
         * running on. This is based on uname(), and the user may
         * hence control what this returns by using
         * personality(). This puts the user in control on systems
         * that can run binaries of multiple architectures.
         *
         * We do not translate the string returned by uname()
         * 1:1. Instead we try to clean it up and break down the
         * confusion on x86 and arm in particular.
         *
         * We do not try to distinguish CPUs not CPU features, but
         * actual architectures, i.e. that have genuinely different
         * code. */

        static const struct {
                const char *machine;
                int arch;
        } arch_map[] = {
#if defined(__x86_64__) || defined(__i386__)
                { "x86_64",     ARCHITECTURE_X86_64   },
                { "i686",       ARCHITECTURE_X86      },
                { "i586",       ARCHITECTURE_X86      },
                { "i486",       ARCHITECTURE_X86      },
                { "i386",       ARCHITECTURE_X86      },
#elif defined(__powerpc__) || defined(__powerpc64__)
                { "ppc64",      ARCHITECTURE_PPC64    },
                { "ppc64le",    ARCHITECTURE_PPC64_LE },
                { "ppc",        ARCHITECTURE_PPC      },
                { "ppcle",      ARCHITECTURE_PPC_LE   },
#elif defined(__ia64__)
                { "ia64",       ARCHITECTURE_IA64     },
#elif defined(__hppa__) || defined(__hppa64__)
                { "parisc64",   ARCHITECTURE_PARISC64 },
                { "parisc",     ARCHITECTURE_PARISC   },
#elif defined(__s390__) || defined(__s390x__)
                { "s390x",      ARCHITECTURE_S390X    },
                { "s390",       ARCHITECTURE_S390     },
#elif defined(__sparc__)
                { "sparc64",    ARCHITECTURE_SPARC64  },
                { "sparc",      ARCHITECTURE_SPARC    },
#elif defined(__mips__) || defined(__mips64__)
                { "mips64",     ARCHITECTURE_MIPS64   },
                { "mips",       ARCHITECTURE_MIPS     },
#elif defined(__alpha__)
                { "alpha" ,     ARCHITECTURE_ALPHA    },
#elif defined(__arm__) || defined(__aarch64__)
                { "aarch64",    ARCHITECTURE_ARM64    },
                { "aarch64_be", ARCHITECTURE_ARM64_BE },
                { "armv4l",     ARCHITECTURE_ARM      },
                { "armv4b",     ARCHITECTURE_ARM_BE   },
                { "armv4tl",    ARCHITECTURE_ARM      },
                { "armv4tb",    ARCHITECTURE_ARM_BE   },
                { "armv5tl",    ARCHITECTURE_ARM      },
                { "armv5tb",    ARCHITECTURE_ARM_BE   },
                { "armv5tel",   ARCHITECTURE_ARM      },
                { "armv5teb" ,  ARCHITECTURE_ARM_BE   },
                { "armv5tejl",  ARCHITECTURE_ARM      },
                { "armv5tejb",  ARCHITECTURE_ARM_BE   },
                { "armv6l",     ARCHITECTURE_ARM      },
                { "armv6b",     ARCHITECTURE_ARM_BE   },
                { "armv7l",     ARCHITECTURE_ARM      },
                { "armv7b",     ARCHITECTURE_ARM_BE   },
                { "armv7ml",    ARCHITECTURE_ARM      },
                { "armv7mb",    ARCHITECTURE_ARM_BE   },
                { "armv4l",     ARCHITECTURE_ARM      },
                { "armv4b",     ARCHITECTURE_ARM_BE   },
                { "armv4tl",    ARCHITECTURE_ARM      },
                { "armv4tb",    ARCHITECTURE_ARM_BE   },
                { "armv5tl",    ARCHITECTURE_ARM      },
                { "armv5tb",    ARCHITECTURE_ARM_BE   },
                { "armv5tel",   ARCHITECTURE_ARM      },
                { "armv5teb",   ARCHITECTURE_ARM_BE   },
                { "armv5tejl",  ARCHITECTURE_ARM      },
                { "armv5tejb",  ARCHITECTURE_ARM_BE   },
                { "armv6l",     ARCHITECTURE_ARM      },
                { "armv6b",     ARCHITECTURE_ARM_BE   },
                { "armv7l",     ARCHITECTURE_ARM      },
                { "armv7b",     ARCHITECTURE_ARM_BE   },
                { "armv7ml",    ARCHITECTURE_ARM      },
                { "armv7mb",    ARCHITECTURE_ARM_BE   },
                { "armv8l",     ARCHITECTURE_ARM      },
                { "armv8b",     ARCHITECTURE_ARM_BE   },
#elif defined(__sh__) || defined(__sh64__)
                { "sh5",        ARCHITECTURE_SH64     },
                { "sh2",        ARCHITECTURE_SH       },
                { "sh2a",       ARCHITECTURE_SH       },
                { "sh3",        ARCHITECTURE_SH       },
                { "sh4",        ARCHITECTURE_SH       },
                { "sh4a",       ARCHITECTURE_SH       },
#elif defined(__m68k__)
                { "m68k",       ARCHITECTURE_M68K     },
#elif defined(__tilegx__)
                { "tilegx",     ARCHITECTURE_TILEGX   },
#elif defined(__cris__)
                { "crisv32",    ARCHITECTURE_CRIS     },
#elif defined(__nios2__)
                { "nios2",      ARCHITECTURE_NIOS2    },
#elif defined(__riscv__) || defined(__riscv)
        /* __riscv__ is obsolete, remove in 2018 */
                { "riscv32",    ARCHITECTURE_RISCV32  },
                { "riscv64",    ARCHITECTURE_RISCV64  },
#  if __SIZEOF_POINTER__ == 4
                { "riscv",      ARCHITECTURE_RISCV32  },
#  elif __SIZEOF_POINTER__ == 8
                { "riscv",      ARCHITECTURE_RISCV64  },
#  endif
#else
#error "Please register your architecture here!"
#endif
        };

        static int cached = _ARCHITECTURE_INVALID;
        struct utsname u;
        unsigned i;

        if (cached != _ARCHITECTURE_INVALID)
                return cached;

        assert_se(uname(&u) >= 0);

        for (i = 0; i < ELEMENTSOF(arch_map); i++)
                if (streq(arch_map[i].machine, u.machine))
                        return cached = arch_map[i].arch;

        assert_not_reached("Couldn't identify architecture. You need to patch systemd.");
        return _ARCHITECTURE_INVALID;
}
static void test_one(
                const char *path,
                const char *interface,
                const char *member,
                bool as_list,
                const char *arg0,
                const char *match,
                bool good) {

        _cleanup_close_ int bus_ref = -1;
        _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL;
        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
        sd_bus *a, *b;
        int r;

        assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);

        bus_ref = bus_kernel_create_bus(name, false, &bus_name);
        if (bus_ref == -ENOENT)
                exit(EXIT_TEST_SKIP);

        assert_se(bus_ref >= 0);

        address = strappend("kernel:path=", bus_name);
        assert_se(address);

        r = sd_bus_new(&a);
        assert_se(r >= 0);

        r = sd_bus_new(&b);
        assert_se(r >= 0);

        r = sd_bus_set_address(a, address);
        assert_se(r >= 0);

        r = sd_bus_set_address(b, address);
        assert_se(r >= 0);

        r = sd_bus_start(a);
        assert_se(r >= 0);

        r = sd_bus_start(b);
        assert_se(r >= 0);

        log_debug("match");
        r = sd_bus_add_match(b, NULL, match, NULL, NULL);
        assert_se(r >= 0);

        log_debug("signal");

        if (as_list)
                r = sd_bus_emit_signal(a, path, interface, member, "as", 1, arg0);
        else
                r = sd_bus_emit_signal(a, path, interface, member, "s", arg0);
        assert_se(r >= 0);

        r = sd_bus_process(b, &m);
        assert_se(r >= 0 && (good == !!m));

        sd_bus_unref(a);
        sd_bus_unref(b);
}
示例#8
0
static void test_nameinfo_pretty(void) {
        _cleanup_free_ char *stdin_name = NULL, *localhost = NULL;

        union sockaddr_union s = {
                .in.sin_family = AF_INET,
                .in.sin_port = 0,
                .in.sin_addr.s_addr = htonl(INADDR_ANY),
        };
        int r;

        union sockaddr_union c = {};
        socklen_t slen = sizeof(c.in), clen = sizeof(c.in);

        _cleanup_close_ int sfd = -1, cfd = -1;
        r = getnameinfo_pretty(STDIN_FILENO, &stdin_name);
        log_info_errno(r, "No connection remote: %m");

        assert_se(r < 0);

        sfd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, 0);
        assert_se(sfd >= 0);

        assert_se(bind(sfd, &s.sa, sizeof(s.in)) == 0);

        /* find out the port number */
        assert_se(getsockname(sfd, &s.sa, &slen) == 0);

        assert_se(listen(sfd, 1) == 0);

        assert_se(asynchronous_job(connect_thread, &s) == 0);

        log_debug("Accepting new connection on fd:%d", sfd);
        cfd = accept4(sfd, &c.sa, &clen, SOCK_CLOEXEC);
        assert_se(cfd >= 0);

        r = getnameinfo_pretty(cfd, &localhost);
        log_info("Connection from %s", localhost);
        assert_se(r == 0);
}

static void test_sockaddr_equal(void) {
        union sockaddr_union a = {
                .in.sin_family = AF_INET,
                .in.sin_port = 0,
                .in.sin_addr.s_addr = htonl(INADDR_ANY),
        };
        union sockaddr_union b = {
                .in.sin_family = AF_INET,
                .in.sin_port = 0,
                .in.sin_addr.s_addr = htonl(INADDR_ANY),
        };
        union sockaddr_union c = {
                .in.sin_family = AF_INET,
                .in.sin_port = 0,
                .in.sin_addr.s_addr = htonl(1234),
        };
        union sockaddr_union d = {
                .in6.sin6_family = AF_INET6,
                .in6.sin6_port = 0,
                .in6.sin6_addr = IN6ADDR_ANY_INIT,
        };
        assert_se(sockaddr_equal(&a, &a));
        assert_se(sockaddr_equal(&a, &b));
        assert_se(sockaddr_equal(&d, &d));
        assert_se(!sockaddr_equal(&a, &c));
        assert_se(!sockaddr_equal(&b, &c));
}

int main(int argc, char *argv[]) {

        log_set_max_level(LOG_DEBUG);

        test_socket_address_parse();
        test_socket_address_parse_netlink();
        test_socket_address_equal();
        test_socket_address_get_path();
        test_socket_address_is();
        test_socket_address_is_netlink();

        test_in_addr_is_null();
        test_in_addr_prefix_intersect();
        test_in_addr_prefix_next();
        test_in_addr_to_string();

        test_nameinfo_pretty();

        test_sockaddr_equal();

        return 0;
}
示例#9
0
int stub_pid1(sd_id128_t uuid) {
        enum {
                STATE_RUNNING,
                STATE_REBOOT,
                STATE_POWEROFF,
        } state = STATE_RUNNING;

        sigset_t fullmask, oldmask, waitmask;
        usec_t quit_usec = USEC_INFINITY;
        pid_t pid;
        int r;

        /* The new environment we set up, on the stack. */
        char new_environment[] =
                "container=systemd-nspawn\0"
                "container_uuid=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

        /* Implements a stub PID 1, that reaps all processes and processes a couple of standard signals. This is useful
         * for allowing arbitrary processes run in a container, and still have all zombies reaped. */

        assert_se(sigfillset(&fullmask) >= 0);
        assert_se(sigprocmask(SIG_BLOCK, &fullmask, &oldmask) >= 0);

        pid = fork();
        if (pid < 0)
                return log_error_errno(errno, "Failed to fork child pid: %m");

        if (pid == 0) {
                /* Return in the child */
                assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) >= 0);
                setsid();
                return 0;
        }

        reset_all_signal_handlers();

        log_close();
        close_all_fds(NULL, 0);
        log_open();

        /* Flush out /proc/self/environ, so that we don't leak the environment from the host into the container. Also,
         * set $container= and $container_uuid= so that clients in the container that query it from /proc/1/environ
         * find them set. */
        sd_id128_to_string(uuid, new_environment + sizeof(new_environment) - SD_ID128_STRING_MAX);
        reset_environ(new_environment, sizeof(new_environment));

        rename_process("STUBINIT");

        assert_se(sigemptyset(&waitmask) >= 0);
        assert_se(sigset_add_many(&waitmask,
                                  SIGCHLD,          /* posix: process died */
                                  SIGINT,           /* sysv: ctrl-alt-del */
                                  SIGRTMIN+3,       /* systemd: halt */
                                  SIGRTMIN+4,       /* systemd: poweroff */
                                  SIGRTMIN+5,       /* systemd: reboot */
                                  SIGRTMIN+6,       /* systemd: kexec */
                                  SIGRTMIN+13,      /* systemd: halt */
                                  SIGRTMIN+14,      /* systemd: poweroff */
                                  SIGRTMIN+15,      /* systemd: reboot */
                                  SIGRTMIN+16,      /* systemd: kexec */
                                  -1) >= 0);

        /* Note that we ignore SIGTERM (sysv's reexec), SIGHUP (reload), and all other signals here, since we don't
         * support reexec/reloading in this stub process. */

        for (;;) {
                siginfo_t si;
                usec_t current_usec;

                si.si_pid = 0;
                r = waitid(P_ALL, 0, &si, WEXITED|WNOHANG);
                if (r < 0) {
                        r = log_error_errno(errno, "Failed to reap children: %m");
                        goto finish;
                }

                current_usec = now(CLOCK_MONOTONIC);

                if (si.si_pid == pid || current_usec >= quit_usec) {

                        /* The child we started ourselves died or we reached a timeout. */

                        if (state == STATE_REBOOT) { /* dispatch a queued reboot */
                                (void) reboot(RB_AUTOBOOT);
                                r = log_error_errno(errno, "Failed to reboot: %m");
                                goto finish;

                        } else if (state == STATE_POWEROFF)
                                (void) reboot(RB_POWER_OFF); /* if this fails, fall back to normal exit. */

                        if (si.si_pid == pid && si.si_code == CLD_EXITED)
                                r = si.si_status; /* pass on exit code */
                        else
                                r = 255; /* signal, coredump, timeout, … */

                        goto finish;
                }
                if (si.si_pid != 0)
                        /* We reaped something. Retry until there's nothing more to reap. */
                        continue;

                if (quit_usec == USEC_INFINITY)
                        r = sigwaitinfo(&waitmask, &si);
                else {
                        struct timespec ts;
                        r = sigtimedwait(&waitmask, &si, timespec_store(&ts, quit_usec - current_usec));
                }
                if (r < 0) {
                        if (errno == EINTR) /* strace -p attach can result in EINTR, let's handle this nicely. */
                                continue;
                        if (errno == EAGAIN) /* timeout reached */
                                continue;

                        r = log_error_errno(errno, "Failed to wait for signal: %m");
                        goto finish;
                }

                if (si.si_signo == SIGCHLD)
                        continue; /* Let's reap this */

                if (state != STATE_RUNNING)
                        continue;

                /* Would love to use a switch() statement here, but SIGRTMIN is actually a function call, not a
                 * constant… */

                if (si.si_signo == SIGRTMIN+3 ||
                    si.si_signo == SIGRTMIN+4 ||
                    si.si_signo == SIGRTMIN+13 ||
                    si.si_signo == SIGRTMIN+14)

                        state = STATE_POWEROFF;

                else if (si.si_signo == SIGINT ||
                         si.si_signo == SIGRTMIN+5 ||
                         si.si_signo == SIGRTMIN+6 ||
                         si.si_signo == SIGRTMIN+15 ||
                         si.si_signo == SIGRTMIN+16)

                        state = STATE_REBOOT;
                else
                        assert_not_reached("Got unexpected signal");

                r = kill_and_sigcont(pid, SIGTERM);

                /* Let's send a SIGHUP after the SIGTERM, as shells tend to ignore SIGTERM but do react to SIGHUP. We
                 * do it strictly in this order, so that the SIGTERM is dispatched first, and SIGHUP second for those
                 * processes which handle both. That's because services tend to bind configuration reload or something
                 * else to SIGHUP. */

                if (r != -ESRCH)
                        (void) kill(pid, SIGHUP);

                quit_usec = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC;
        }

finish:
        _exit(r < 0 ? EXIT_FAILURE : r);
}
示例#10
0
static void test_align_power2(void) {
        unsigned long i, p2;

        assert_se(ALIGN_POWER2(0) == 0);
        assert_se(ALIGN_POWER2(1) == 1);
        assert_se(ALIGN_POWER2(2) == 2);
        assert_se(ALIGN_POWER2(3) == 4);
        assert_se(ALIGN_POWER2(12) == 16);

        assert_se(ALIGN_POWER2(ULONG_MAX) == 0);
        assert_se(ALIGN_POWER2(ULONG_MAX - 1) == 0);
        assert_se(ALIGN_POWER2(ULONG_MAX - 1024) == 0);
        assert_se(ALIGN_POWER2(ULONG_MAX / 2) == ULONG_MAX / 2 + 1);
        assert_se(ALIGN_POWER2(ULONG_MAX + 1) == 0);

        for (i = 1; i < 131071; ++i) {
                for (p2 = 1; p2 < i; p2 <<= 1)
                        /* empty */ ;

                assert_se(ALIGN_POWER2(i) == p2);
        }

        for (i = ULONG_MAX - 1024; i < ULONG_MAX; ++i) {
                for (p2 = 1; p2 && p2 < i; p2 <<= 1)
                        /* empty */ ;

                assert_se(ALIGN_POWER2(i) == p2);
        }
}
示例#11
0
static int setup_machine_raw(uint64_t size, sd_bus_error *error) {
        _cleanup_free_ char *tmp = NULL;
        _cleanup_close_ int fd = -1;
        struct statvfs ss;
        pid_t pid = 0;
        siginfo_t si;
        int r;

        /* We want to be able to make use of btrfs-specific file
         * system features, in particular subvolumes, reflinks and
         * quota. Hence, if we detect that /var/lib/machines.raw is
         * not located on btrfs, let's create a loopback file, place a
         * btrfs file system into it, and mount it to
         * /var/lib/machines. */

        fd = open("/var/lib/machines.raw", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
        if (fd >= 0) {
                r = fd;
                fd = -1;
                return r;
        }

        if (errno != ENOENT)
                return sd_bus_error_set_errnof(error, errno, "Failed to open /var/lib/machines.raw: %m");

        r = tempfn_xxxxxx("/var/lib/machines.raw", &tmp);
        if (r < 0)
                return r;

        (void) mkdir_p_label("/var/lib", 0755);
        fd = open(tmp, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0600);
        if (fd < 0)
                return sd_bus_error_set_errnof(error, errno, "Failed to create /var/lib/machines.raw: %m");

        if (fstatvfs(fd, &ss) < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to determine free space on /var/lib/machines.raw: %m");
                goto fail;
        }

        if (ss.f_bsize * ss.f_bavail < VAR_LIB_MACHINES_FREE_MIN) {
                r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Not enough free disk space to set up /var/lib/machines.");
                goto fail;
        }

        if (ftruncate(fd, size) < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to enlarge /var/lib/machines.raw: %m");
                goto fail;
        }

        pid = fork();
        if (pid < 0) {
                r = sd_bus_error_set_errnof(error, errno, "Failed to fork mkfs.btrfs: %m");
                goto fail;
        }

        if (pid == 0) {

                /* Child */

                (void) reset_all_signal_handlers();
                (void) reset_signal_mask();
                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);

                fd = safe_close(fd);

                execlp("mkfs.btrfs", "-Lvar-lib-machines", tmp, NULL);
                if (errno == ENOENT)
                        return 99;

                _exit(EXIT_FAILURE);
        }

        r = wait_for_terminate(pid, &si);
        if (r < 0) {
                sd_bus_error_set_errnof(error, r, "Failed to wait for mkfs.btrfs: %m");
                goto fail;
        }

        pid = 0;

        if (si.si_code != CLD_EXITED) {
                r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs died abnormally.");
                goto fail;
        }
        if (si.si_status == 99) {
                r = sd_bus_error_set_errnof(error, ENOENT, "Cannot set up /var/lib/machines, mkfs.btrfs is missing");
                goto fail;
        }
        if (si.si_status != 0) {
                r = sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "mkfs.btrfs failed with error code %i", si.si_status);
                goto fail;
        }

        r = rename_noreplace(AT_FDCWD, tmp, AT_FDCWD, "/var/lib/machines.raw");
        if (r < 0) {
                sd_bus_error_set_errnof(error, r, "Failed to move /var/lib/machines.raw into place: %m");
                goto fail;
        }

        r = fd;
        fd = -1;

        return r;

fail:
        unlink_noerrno(tmp);

        if (pid > 1)
                kill_and_sigcont(pid, SIGKILL);

        return r;
}
示例#12
0
static void test_cunescape(void) {
        _cleanup_free_ char *unescaped;
        unescaped = cunescape("abc\\\\\\\"\\b\\f\\n\\r\\t\\v\\003\\177\\234\\313");
        assert_se(streq(unescaped, "abc\\\"\b\f\n\r\t\v\003\177\234\313"));
}
示例#13
0
static void test_undecchar(void) {
        assert_se(undecchar('0') == 0);
        assert_se(undecchar('9') == 9);
}
示例#14
0
static void test_decchar(void) {
        assert_se(decchar(0) == '0');
        assert_se(decchar(9) == '9');
}
示例#15
0
static int manager_send_request(Manager *m) {
        _cleanup_free_ char *pretty = NULL;
        struct ntp_msg ntpmsg = {
                /*
                 * "The client initializes the NTP message header, sends the request
                 * to the server, and strips the time of day from the Transmit
                 * Timestamp field of the reply.  For this purpose, all the NTP
                 * header fields are set to 0, except the Mode, VN, and optional
                 * Transmit Timestamp fields."
                 */
                .field = NTP_FIELD(0, 4, NTP_MODE_CLIENT),
        };
        ssize_t len;
        int r;

        assert(m);
        assert(m->current_server_name);
        assert(m->current_server_address);

        m->event_timeout = sd_event_source_unref(m->event_timeout);

        /*
         * Set transmit timestamp, remember it; the server will send that back
         * as the origin timestamp and we have an indication that this is the
         * matching answer to our request.
         *
         * The actual value does not matter, We do not care about the correct
         * NTP UINT_MAX fraction; we just pass the plain nanosecond value.
         */
        assert_se(clock_gettime(clock_boottime_or_monotonic(), &m->trans_time_mon) >= 0);
        assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0);
        ntpmsg.trans_time.sec = htobe32(m->trans_time.tv_sec + OFFSET_1900_1970);
        ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec);

        server_address_pretty(m->current_server_address, &pretty);

        len = sendto(m->server_socket, &ntpmsg, sizeof(ntpmsg), MSG_DONTWAIT, &m->current_server_address->sockaddr.sa, m->current_server_address->socklen);
        if (len == sizeof(ntpmsg)) {
                m->pending = true;
                log_debug("Sent NTP request to %s (%s).", strna(pretty), m->current_server_name->string);
        } else {
                log_debug("Sending NTP request to %s (%s) failed: %m", strna(pretty), m->current_server_name->string);
                return manager_connect(m);
        }

        /* re-arm timer with increasing timeout, in case the packets never arrive back */
        if (m->retry_interval > 0) {
                if (m->retry_interval < NTP_POLL_INTERVAL_MAX_SEC * USEC_PER_SEC)
                        m->retry_interval *= 2;
        } else
                m->retry_interval = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;

        r = manager_arm_timer(m, m->retry_interval);
        if (r < 0) {
                log_error("Failed to rearm timer: %s", strerror(-r));
                return r;
        }

        r = sd_event_add_time(
                        m->event,
                        &m->event_timeout,
                        clock_boottime_or_monotonic(),
                        now(clock_boottime_or_monotonic()) + TIMEOUT_USEC, 0,
                        manager_timeout, m);
        if (r < 0) {
                log_error("Failed to arm timeout timer: %s", strerror(-r));
                return r;
        }

        return 0;
}

static int manager_timer(sd_event_source *source, usec_t usec, void *userdata) {
        Manager *m = userdata;

        assert(m);

        return manager_send_request(m);
}
示例#16
0
static void test_strv_join_prefix(void) {
        _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL;

        p = strv_join_prefix((char **)input_table_multiple, ", ", "foo");
        assert_se(p);
        assert_se(streq(p, "fooone, footwo, foothree"));

        q = strv_join_prefix((char **)input_table_multiple, ";", "foo");
        assert_se(q);
        assert_se(streq(q, "fooone;footwo;foothree"));

        r = strv_join_prefix((char **)input_table_multiple, NULL, "foo");
        assert_se(r);
        assert_se(streq(r, "fooone footwo foothree"));

        s = strv_join_prefix((char **)input_table_one, ", ", "foo");
        assert_se(s);
        assert_se(streq(s, "fooone"));

        t = strv_join_prefix((char **)input_table_none, ", ", "foo");
        assert_se(t);
        assert_se(streq(t, ""));

        v = strv_join_prefix((char **)input_table_two_empties, ", ", "foo");
        assert_se(v);
        assert_se(streq(v, "foo, foo"));

        w = strv_join_prefix((char **)input_table_one_empty, ", ", "foo");
        assert_se(w);
        assert_se(streq(w, "foo"));
}
示例#17
0
static int manager_receive_response(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
        Manager *m = userdata;
        struct ntp_msg ntpmsg;

        struct iovec iov = {
                .iov_base = &ntpmsg,
                .iov_len = sizeof(ntpmsg),
        };
        union {
                struct cmsghdr cmsghdr;
                uint8_t buf[CMSG_SPACE(sizeof(struct timeval))];
        } control;
        union sockaddr_union server_addr;
        struct msghdr msghdr = {
                .msg_iov = &iov,
                .msg_iovlen = 1,
                .msg_control = &control,
                .msg_controllen = sizeof(control),
                .msg_name = &server_addr,
                .msg_namelen = sizeof(server_addr),
        };
        struct cmsghdr *cmsg;
        struct timespec now_ts;
        struct timeval *recv_time;
        ssize_t len;
        double origin, receive, trans, dest;
        double delay, offset;
        bool spike;
        int leap_sec;
        int r;

        assert(source);
        assert(m);

        if (revents & (EPOLLHUP|EPOLLERR)) {
                log_warning("Server connection returned error.");
                return manager_connect(m);
        }

        len = recvmsg(fd, &msghdr, MSG_DONTWAIT);
        if (len < 0) {
                if (errno == EAGAIN)
                        return 0;

                log_warning("Error receiving message. Disconnecting.");
                return manager_connect(m);
        }

        if (iov.iov_len < sizeof(struct ntp_msg)) {
                log_warning("Invalid response from server. Disconnecting.");
                return manager_connect(m);
        }

        if (!m->current_server_name ||
            !m->current_server_address ||
            !sockaddr_equal(&server_addr, &m->current_server_address->sockaddr)) {
                log_debug("Response from unknown server.");
                return 0;
        }

        recv_time = NULL;
        for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) {
                if (cmsg->cmsg_level != SOL_SOCKET)
                        continue;

                switch (cmsg->cmsg_type) {
                case SCM_TIMESTAMP:
                        recv_time = (struct timeval *) CMSG_DATA(cmsg);
                        break;
                }
        }
        if (!recv_time) {
                log_error("Invalid packet timestamp.");
                return -EINVAL;
        }

        if (!m->pending) {
                log_debug("Unexpected reply. Ignoring.");
                return 0;
        }

        /* check our "time cookie" (we just stored nanoseconds in the fraction field) */
        if (be32toh(ntpmsg.origin_time.sec) != m->trans_time.tv_sec + OFFSET_1900_1970 ||
            be32toh(ntpmsg.origin_time.frac) != m->trans_time.tv_nsec) {
                log_debug("Invalid reply; not our transmit time. Ignoring.");
                return 0;
        }

        m->event_timeout = sd_event_source_unref(m->event_timeout);

        if (be32toh(ntpmsg.recv_time.sec) < TIME_EPOCH + OFFSET_1900_1970 ||
            be32toh(ntpmsg.trans_time.sec) < TIME_EPOCH + OFFSET_1900_1970) {
                log_debug("Invalid reply, returned times before epoch. Ignoring.");
                return manager_connect(m);
        }

        if (NTP_FIELD_LEAP(ntpmsg.field) == NTP_LEAP_NOTINSYNC) {
                log_debug("Server is not synchronized. Disconnecting.");
                return manager_connect(m);
        }

        if (!IN_SET(NTP_FIELD_VERSION(ntpmsg.field), 3, 4)) {
                log_debug("Response NTPv%d. Disconnecting.", NTP_FIELD_VERSION(ntpmsg.field));
                return manager_connect(m);
        }

        if (NTP_FIELD_MODE(ntpmsg.field) != NTP_MODE_SERVER) {
                log_debug("Unsupported mode %d. Disconnecting.", NTP_FIELD_MODE(ntpmsg.field));
                return manager_connect(m);
        }

        /* valid packet */
        m->pending = false;
        m->retry_interval = 0;

        /* announce leap seconds */
        if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_PLUSSEC)
                leap_sec = 1;
        else if (NTP_FIELD_LEAP(ntpmsg.field) & NTP_LEAP_MINUSSEC)
                leap_sec = -1;
        else
                leap_sec = 0;

        /*
         * "Timestamp Name          ID   When Generated
         *  ------------------------------------------------------------
         *  Originate Timestamp     T1   time request sent by client
         *  Receive Timestamp       T2   time request received by server
         *  Transmit Timestamp      T3   time reply sent by server
         *  Destination Timestamp   T4   time reply received by client
         *
         *  The round-trip delay, d, and system clock offset, t, are defined as:
         *  d = (T4 - T1) - (T3 - T2)     t = ((T2 - T1) + (T3 - T4)) / 2"
         */
        assert_se(clock_gettime(clock_boottime_or_monotonic(), &now_ts) >= 0);
        origin = tv_to_d(recv_time) - (ts_to_d(&now_ts) - ts_to_d(&m->trans_time_mon)) + OFFSET_1900_1970;
        receive = ntp_ts_to_d(&ntpmsg.recv_time);
        trans = ntp_ts_to_d(&ntpmsg.trans_time);
        dest = tv_to_d(recv_time) + OFFSET_1900_1970;

        offset = ((receive - origin) + (trans - dest)) / 2;
        delay = (dest - origin) - (trans - receive);

        spike = manager_sample_spike_detection(m, offset, delay);

        manager_adjust_poll(m, offset, spike);

        log_debug("NTP response:\n"
                  "  leap         : %u\n"
                  "  version      : %u\n"
                  "  mode         : %u\n"
                  "  stratum      : %u\n"
                  "  precision    : %.6f sec (%d)\n"
                  "  reference    : %.4s\n"
                  "  origin       : %.3f\n"
                  "  receive      : %.3f\n"
                  "  transmit     : %.3f\n"
                  "  dest         : %.3f\n"
                  "  offset       : %+.3f sec\n"
                  "  delay        : %+.3f sec\n"
                  "  packet count : %"PRIu64"\n"
                  "  jitter       : %.3f%s\n"
                  "  poll interval: " USEC_FMT "\n",
                  NTP_FIELD_LEAP(ntpmsg.field),
                  NTP_FIELD_VERSION(ntpmsg.field),
                  NTP_FIELD_MODE(ntpmsg.field),
                  ntpmsg.stratum,
                  exp2(ntpmsg.precision), ntpmsg.precision,
                  ntpmsg.stratum == 1 ? ntpmsg.refid : "n/a",
                  origin - OFFSET_1900_1970,
                  receive - OFFSET_1900_1970,
                  trans - OFFSET_1900_1970,
                  dest - OFFSET_1900_1970,
                  offset, delay,
                  m->packet_count,
                  m->samples_jitter, spike ? " spike" : "",
                  m->poll_interval_usec / USEC_PER_SEC);

        if (!spike) {
                m->sync = true;
                r = manager_adjust_clock(m, offset, leap_sec);
                if (r < 0)
                        log_error("Failed to call clock_adjtime(): %m");
        }

        log_info("interval/delta/delay/jitter/drift " USEC_FMT "s/%+.3fs/%.3fs/%.3fs/%+ippm%s",
                 m->poll_interval_usec / USEC_PER_SEC, offset, delay, m->samples_jitter, m->drift_ppm,
                 spike ? " (ignored)" : "");

        r = manager_arm_timer(m, m->poll_interval_usec);
        if (r < 0) {
                log_error("Failed to rearm timer: %s", strerror(-r));
                return r;
        }

        return 0;
}

static int manager_listen_setup(Manager *m) {
        union sockaddr_union addr = {};
        static const int tos = IPTOS_LOWDELAY;
        static const int on = 1;
        int r;

        assert(m);

        assert(m->server_socket < 0);
        assert(!m->event_receive);
        assert(m->current_server_address);

        addr.sa.sa_family = m->current_server_address->sockaddr.sa.sa_family;

        m->server_socket = socket(addr.sa.sa_family, SOCK_DGRAM | SOCK_CLOEXEC, 0);
        if (m->server_socket < 0)
                return -errno;

        r = bind(m->server_socket, &addr.sa, m->current_server_address->socklen);
        if (r < 0)
                return -errno;

        r = setsockopt(m->server_socket, SOL_SOCKET, SO_TIMESTAMP, &on, sizeof(on));
        if (r < 0)
                return -errno;

        setsockopt(m->server_socket, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));

        return sd_event_add_io(m->event, &m->event_receive, m->server_socket, EPOLLIN, manager_receive_response, m);
}

static int manager_begin(Manager *m) {
        _cleanup_free_ char *pretty = NULL;
        int r;

        assert(m);
        assert_return(m->current_server_name, -EHOSTUNREACH);
        assert_return(m->current_server_address, -EHOSTUNREACH);

        m->poll_interval_usec = NTP_POLL_INTERVAL_MIN_SEC * USEC_PER_SEC;

        server_address_pretty(m->current_server_address, &pretty);
        log_info("Using NTP server %s (%s).", strna(pretty), m->current_server_name->string);
        sd_notifyf(false, "STATUS=Using Time Server %s (%s).", strna(pretty), m->current_server_name->string);

        r = manager_listen_setup(m);
        if (r < 0) {
                log_warning("Failed to setup connection socket: %s", strerror(-r));
                return r;
        }

        r = manager_clock_watch_setup(m);
        if (r < 0)
                return r;

        return manager_send_request(m);
}

void manager_set_server_name(Manager *m, ServerName *n) {
        assert(m);

        if (m->current_server_name == n)
                return;

        m->current_server_name = n;
        m->current_server_address = NULL;

        manager_disconnect(m);

        if (n)
                log_debug("Selected server %s.", n->string);
}
示例#18
0
static void test_strv_split(void) {
        _cleanup_strv_free_ char **l = NULL;
        const char str[] = "one,two,three";

        l = strv_split(str, ",");
        assert_se(l);
        assert_se(strv_equal(l, (char**) input_table_multiple));

        strv_free(l);

        l = strv_split("    one    two\t three", WHITESPACE);
        assert_se(l);
        assert_se(strv_equal(l, (char**) input_table_multiple));

        strv_free(l);

        /* Setting NULL for separator is equivalent to WHITESPACE */
        l = strv_split("    one    two\t three", NULL);
        assert_se(l);
        assert_se(strv_equal(l, (char**) input_table_multiple));

        strv_free(l);

        l = strv_split_full("    one    two\t three", NULL, 0);
        assert_se(l);
        assert_se(strv_equal(l, (char**) input_table_multiple));

        strv_free(l);

        l = strv_split_full("    'one'  \"  two\t three \" ' four  five'", NULL, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_equal(l, (char**) input_table_quoted));

        strv_free(l);

        /* missing last quote ignores the last element. */
        l = strv_split_full("    'one'  \"  two\t three \" ' four  five'  ' ignored element ", NULL, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_equal(l, (char**) input_table_quoted));

        strv_free(l);

        /* missing last quote, but the last element is _not_ ignored with SPLIT_RELAX. */
        l = strv_split_full("    'one'  \"  two\t three \" ' four  five", NULL, SPLIT_QUOTES | SPLIT_RELAX);
        assert_se(l);
        assert_se(strv_equal(l, (char**) input_table_quoted));

        strv_free(l);

        /* missing separator between */
        l = strv_split_full("    'one'  \"  two\t three \"' four  five'", NULL, SPLIT_QUOTES | SPLIT_RELAX);
        assert_se(l);
        assert_se(strv_equal(l, (char**) input_table_quoted));

        strv_free(l);

        l = strv_split_full("    'one'  \"  two\t three \"' four  five", NULL, SPLIT_QUOTES | SPLIT_RELAX);
        assert_se(l);
        assert_se(strv_equal(l, (char**) input_table_quoted));
}
示例#19
0
int main(int argc, char *argv[]) {
        _cleanup_journal_close_ sd_journal*j;
        _cleanup_free_ char *t;

        log_set_max_level(LOG_DEBUG);

        assert_se(sd_journal_open(&j, 0) >= 0);

        assert_se(sd_journal_add_match(j, "foobar", 0) < 0);
        assert_se(sd_journal_add_match(j, "foobar=waldo", 0) < 0);
        assert_se(sd_journal_add_match(j, "", 0) < 0);
        assert_se(sd_journal_add_match(j, "=", 0) < 0);
        assert_se(sd_journal_add_match(j, "=xxxxx", 0) < 0);
        assert_se(sd_journal_add_match(j, "HALLO=WALDO", 0) >= 0);
        assert_se(sd_journal_add_match(j, "QUUX=mmmm", 0) >= 0);
        assert_se(sd_journal_add_match(j, "QUUX=xxxxx", 0) >= 0);
        assert_se(sd_journal_add_match(j, "HALLO=", 0) >= 0);
        assert_se(sd_journal_add_match(j, "QUUX=xxxxx", 0) >= 0);
        assert_se(sd_journal_add_match(j, "QUUX=yyyyy", 0) >= 0);
        assert_se(sd_journal_add_match(j, "PIFF=paff", 0) >= 0);

        assert_se(sd_journal_add_disjunction(j) >= 0);

        assert_se(sd_journal_add_match(j, "ONE=one", 0) >= 0);
        assert_se(sd_journal_add_match(j, "ONE=two", 0) >= 0);
        assert_se(sd_journal_add_match(j, "TWO=two", 0) >= 0);

        assert_se(sd_journal_add_conjunction(j) >= 0);

        assert_se(sd_journal_add_match(j, "L4_1=yes", 0) >= 0);
        assert_se(sd_journal_add_match(j, "L4_1=ok", 0) >= 0);
        assert_se(sd_journal_add_match(j, "L4_2=yes", 0) >= 0);
        assert_se(sd_journal_add_match(j, "L4_2=ok", 0) >= 0);

        assert_se(sd_journal_add_disjunction(j) >= 0);

        assert_se(sd_journal_add_match(j, "L3=yes", 0) >= 0);
        assert_se(sd_journal_add_match(j, "L3=ok", 0) >= 0);

        assert_se(t = journal_make_match_string(j));

        printf("resulting match expression is: %s\n", t);

        assert_se(streq(t, "(((L3=ok OR L3=yes) OR ((L4_2=ok OR L4_2=yes) AND (L4_1=ok OR L4_1=yes))) AND ((TWO=two AND (ONE=two OR ONE=one)) OR (PIFF=paff AND (QUUX=yyyyy OR QUUX=xxxxx OR QUUX=mmmm) AND (HALLO= OR HALLO=WALDO))))"));

        return 0;
}
示例#20
0
static void test_strv_split_empty(void) {
        _cleanup_strv_free_ char **l = NULL;

        l = strv_split("", WHITESPACE);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split("", NULL);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", NULL, 0);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", NULL, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", WHITESPACE, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("", WHITESPACE, SPLIT_QUOTES | SPLIT_RELAX);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split("    ", WHITESPACE);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split("    ", NULL);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", NULL, 0);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", WHITESPACE, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", NULL, SPLIT_QUOTES);
        assert_se(l);
        assert_se(strv_isempty(l));

        strv_free(l);
        l = strv_split_full("    ", NULL, SPLIT_QUOTES | SPLIT_RELAX);
        assert_se(l);
        assert_se(strv_isempty(l));
}
示例#21
0
static void test_streq_ptr(void) {
        assert_se(streq_ptr(NULL, NULL));
        assert_se(!streq_ptr("abc", "cdef"));
}
示例#22
0
static void test_str_in_set(void) {
        assert_se(STR_IN_SET("x", "x", "y", "z"));
        assert_se(!STR_IN_SET("X", "x", "y", "z"));
        assert_se(!STR_IN_SET("", "x", "y", "z"));
        assert_se(STR_IN_SET("x", "w", "x"));
}
示例#23
0
static void test_ascii_strlower(void) {
        char a[] = "AabBcC Jk Ii Od LKJJJ kkd LK";
        assert_se(streq(ascii_strlower(a), "aabbcc jk ii od lkjjj kkd lk"));
}
示例#24
0
static void test_strv_find(void) {
        assert_se(strv_find((char **)input_table_multiple, "three"));
        assert_se(!strv_find((char **)input_table_multiple, "four"));
}
示例#25
0
static void test_ascii_strcasecmp_nn(void) {
        assert_se(ascii_strcasecmp_nn("", 0, "", 0) == 0);
        assert_se(ascii_strcasecmp_nn("", 0, "", 1) < 0);
        assert_se(ascii_strcasecmp_nn("", 1, "", 0) > 0);
        assert_se(ascii_strcasecmp_nn("", 1, "", 1) == 0);

        assert_se(ascii_strcasecmp_nn("aaaa", 4, "aaAa", 4) == 0);
        assert_se(ascii_strcasecmp_nn("aaa", 3, "aaAa", 4) < 0);
        assert_se(ascii_strcasecmp_nn("aaa", 4, "aaAa", 4) < 0);
        assert_se(ascii_strcasecmp_nn("aaaa", 4, "aaA", 3) > 0);
        assert_se(ascii_strcasecmp_nn("aaaa", 4, "AAA", 4) > 0);

        assert_se(ascii_strcasecmp_nn("aaaa", 4, "bbbb", 4) < 0);
        assert_se(ascii_strcasecmp_nn("aaAA", 4, "BBbb", 4) < 0);
        assert_se(ascii_strcasecmp_nn("BBbb", 4, "aaaa", 4) > 0);
}
示例#26
0
sd_dhcp_lease *sd_dhcp_lease_ref(sd_dhcp_lease *lease) {
        if (lease)
                assert_se(REFCNT_INC(lease->n_ref) >= 2);

        return lease;
}
示例#27
0
static void test_socket_address_equal(void) {
        SocketAddress a;
        SocketAddress b;

        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
        assert_se(socket_address_parse(&b, "192.168.1.1:888") >= 0);
        assert_se(!socket_address_equal(&a, &b));

        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
        assert_se(socket_address_parse(&b, "192.16.1.1:8888") >= 0);
        assert_se(!socket_address_equal(&a, &b));

        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
        assert_se(socket_address_parse(&b, "8888") >= 0);
        assert_se(!socket_address_equal(&a, &b));

        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
        assert_se(socket_address_parse(&b, "/foo/bar/") >= 0);
        assert_se(!socket_address_equal(&a, &b));

        assert_se(socket_address_parse(&a, "192.168.1.1:8888") >= 0);
        assert_se(socket_address_parse(&b, "192.168.1.1:8888") >= 0);
        assert_se(socket_address_equal(&a, &b));

        assert_se(socket_address_parse(&a, "/foo/bar") >= 0);
        assert_se(socket_address_parse(&b, "/foo/bar") >= 0);
        assert_se(socket_address_equal(&a, &b));

        assert_se(socket_address_parse(&a, "[::1]:8888") >= 0);
        assert_se(socket_address_parse(&b, "[::1]:8888") >= 0);
        assert_se(socket_address_equal(&a, &b));

        assert_se(socket_address_parse(&a, "@abstract") >= 0);
        assert_se(socket_address_parse(&b, "@abstract") >= 0);
        assert_se(socket_address_equal(&a, &b));

        assert_se(socket_address_parse_netlink(&a, "firewall") >= 0);
        assert_se(socket_address_parse_netlink(&b, "firewall") >= 0);
        assert_se(socket_address_equal(&a, &b));
}
示例#28
0
int main(int argc, char *argv[]) {
        _cleanup_close_ int bus_ref = -1;
        _cleanup_free_ char *name = NULL, *bus_name = NULL, *address = NULL;
        _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
        const char *ua = NULL, *ub = NULL, *the_string = NULL;
        sd_bus *a, *b;
        int r, pipe_fds[2];
        const char *nn;

        log_set_max_level(LOG_DEBUG);

        assert_se(asprintf(&name, "deine-mutter-%u", (unsigned) getpid()) >= 0);

        bus_ref = bus_kernel_create_bus(name, false, &bus_name);
        if (bus_ref == -ENOENT)
                return EXIT_TEST_SKIP;

        assert_se(bus_ref >= 0);

        address = strappend("kernel:path=", bus_name);
        assert_se(address);

        r = sd_bus_new(&a);
        assert_se(r >= 0);

        r = sd_bus_new(&b);
        assert_se(r >= 0);

        r = sd_bus_set_name(a, "a");
        assert_se(r >= 0);

        r = sd_bus_set_address(a, address);
        assert_se(r >= 0);

        r = sd_bus_set_address(b, address);
        assert_se(r >= 0);

        assert_se(sd_bus_negotiate_timestamp(a, 1) >= 0);
        assert_se(sd_bus_negotiate_creds(a, _SD_BUS_CREDS_ALL) >= 0);

        assert_se(sd_bus_negotiate_timestamp(b, 1) >= 0);
        assert_se(sd_bus_negotiate_creds(b, _SD_BUS_CREDS_ALL) >= 0);

        r = sd_bus_start(a);
        assert_se(r >= 0);

        r = sd_bus_start(b);
        assert_se(r >= 0);

        r = sd_bus_get_unique_name(a, &ua);
        assert_se(r >= 0);
        printf("unique a: %s\n", ua);

        r = sd_bus_get_name(a, &nn);
        assert_se(r >= 0);
        printf("name of a: %s\n", nn);

        r = sd_bus_get_unique_name(b, &ub);
        assert_se(r >= 0);
        printf("unique b: %s\n", ub);

        r = sd_bus_get_name(b, &nn);
        assert_se(r >= 0);
        printf("name of b: %s\n", nn);

        r = sd_bus_call_method(a, "this.doesnt.exist", "/foo", "meh.mah", "muh", &error, NULL, "s", "yayayay");
        assert_se(sd_bus_error_has_name(&error, SD_BUS_ERROR_SERVICE_UNKNOWN));
        assert_se(r == -EHOSTUNREACH);

        r = sd_bus_add_match(b, "interface='waldo.com',member='Piep'", NULL, NULL);
        assert_se(r >= 0);

        r = sd_bus_emit_signal(a, "/foo/bar/waldo", "waldo.com", "Piep", "sss", "I am a string", "/this/is/a/path", "and.this.a.domain.name");
        assert_se(r >= 0);

        r = sd_bus_try_close(b);
        assert_se(r == -EBUSY);

        r = sd_bus_process_priority(b, -10, &m);
        assert_se(r == -ENOMSG);

        r = sd_bus_process(b, &m);
        assert_se(r > 0);
        assert_se(m);

        bus_message_dump(m, stdout, true);
        assert_se(sd_bus_message_rewind(m, true) >= 0);

        r = sd_bus_message_read(m, "s", &the_string);
        assert_se(r >= 0);
        assert_se(streq(the_string, "I am a string"));

        sd_bus_message_unref(m);
        m = NULL;

        r = sd_bus_request_name(a, "net.x0pointer.foobar", 0);
        assert_se(r >= 0);

        r = sd_bus_message_new_method_call(b, &m, "net.x0pointer.foobar", "/a/path", "an.inter.face", "AMethod");
        assert_se(r >= 0);

        assert_se(pipe2(pipe_fds, O_CLOEXEC) >= 0);

        assert_se(write(pipe_fds[1], "x", 1) == 1);

        pipe_fds[1] = safe_close(pipe_fds[1]);

        r = sd_bus_message_append(m, "h", pipe_fds[0]);
        assert_se(r >= 0);

        pipe_fds[0] = safe_close(pipe_fds[0]);

        r = sd_bus_send(b, m, NULL);
        assert_se(r >= 0);

        for (;;) {
                sd_bus_message_unref(m);
                m = NULL;
                r = sd_bus_process(a, &m);
                assert_se(r > 0);
                assert_se(m);

                bus_message_dump(m, stdout, true);
                assert_se(sd_bus_message_rewind(m, true) >= 0);

                if (sd_bus_message_is_method_call(m, "an.inter.face", "AMethod")) {
                        int fd;
                        char x;

                        r = sd_bus_message_read(m, "h", &fd);
                        assert_se(r >= 0);

                        assert_se(read(fd, &x, 1) == 1);
                        assert_se(x == 'x');
                        break;
                }
        }

        r = sd_bus_release_name(a, "net.x0pointer.foobar");
        assert_se(r >= 0);

        r = sd_bus_release_name(a, "net.x0pointer.foobar");
        assert_se(r == -ESRCH);

        r = sd_bus_try_close(a);
        assert_se(r >= 0);

        sd_bus_unref(a);
        sd_bus_unref(b);

        return 0;
}
示例#29
0
static void test_deserialize_in_addr(void) {
        _cleanup_free_ struct in_addr *addresses = NULL;
        _cleanup_free_ struct in6_addr *addresses6 = NULL;
        struct in_addr  a, b, c;
        struct in6_addr d, e, f;
        int size;
        const char *addresses_string = "192.168.0.1 0:0:0:0:0:FFFF:204.152.189.116 192.168.0.2 ::1 192.168.0.3 1:0:0:0:0:0:0:8";

        assert_se(inet_pton(AF_INET, "0:0:0:0:0:FFFF:204.152.189.116", &a) == 0);
        assert_se(inet_pton(AF_INET6, "192.168.0.1", &d) == 0);

        assert_se(inet_pton(AF_INET, "192.168.0.1", &a) == 1);
        assert_se(inet_pton(AF_INET, "192.168.0.2", &b) == 1);
        assert_se(inet_pton(AF_INET, "192.168.0.3", &c) == 1);
        assert_se(inet_pton(AF_INET6, "0:0:0:0:0:FFFF:204.152.189.116", &d) == 1);
        assert_se(inet_pton(AF_INET6, "::1", &e) == 1);
        assert_se(inet_pton(AF_INET6, "1:0:0:0:0:0:0:8", &f) == 1);

        assert_se((size = deserialize_in_addrs(&addresses, addresses_string)) >= 0);
        assert_se(size == 3);
        assert_se(!memcmp(&a, &addresses[0], sizeof(struct in_addr)));
        assert_se(!memcmp(&b, &addresses[1], sizeof(struct in_addr)));
        assert_se(!memcmp(&c, &addresses[2], sizeof(struct in_addr)));

        assert_se((size = deserialize_in6_addrs(&addresses6, addresses_string)) >= 0);
        assert_se(size == 3);
        assert_se(!memcmp(&d, &addresses6[0], sizeof(struct in6_addr)));
        assert_se(!memcmp(&e, &addresses6[1], sizeof(struct in6_addr)));
        assert_se(!memcmp(&f, &addresses6[2], sizeof(struct in6_addr)));
}
示例#30
0
static void test_octchar(void) {
        assert_se(octchar(00) == '0');
        assert_se(octchar(07) == '7');
}