static int show_status(char **args, unsigned n) { char buf[64]; struct boot_info *info; int err; err = boot_info_new(&info); if (err < 0) return -ENOMEM; err = boot_info_query(info); printf(" Machine ID: %s\n", sd_id128_to_string(info->machine_id, buf)); printf(" Boot ID: %s\n", sd_id128_to_string(info->boot_id, buf)); if (info->fw_type) printf(" Firmware: %s (%s)\n", info->fw_type, strna(info->fw_info)); if (info->fw_entry_active >= 0) { printf("Firmware entry: %s\n", strna(info->fw_entries[info->fw_entry_active].title)); if (info->fw_entries[info->fw_entry_active].path) printf(" %s\n", info->fw_entries[info->fw_entry_active].path); if (!sd_id128_equal(info->fw_entries[info->fw_entry_active].part_uuid, SD_ID128_NULL)) printf(" /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", SD_ID128_FORMAT_VAL(info->fw_entries[info->fw_entry_active].part_uuid)); } if (info->loader) { printf(" Loader: %s\n", info->loader); printf(" %s\n", strna(info->loader_image_path)); if (!sd_id128_equal(info->loader_part_uuid, SD_ID128_NULL)) printf(" /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", SD_ID128_FORMAT_VAL(info->loader_part_uuid)); if (info->loader_entry_active >= 0) { printf(" Loader entry: %s\n", strna(info->loader_entries[info->loader_entry_active].title)); printf(" %s\n", info->loader_entries[info->loader_entry_active].path); } printf("Loader options: %s\n", strna(info->loader_options_added)); } else printf("No suitable data is provided by the boot manager. See:\n" " http://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface\n" " http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec\n" "for details.\n"); printf("\n"); boot_info_free(info); return err; }
int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) { char buffer[36 + 2]; size_t sz; int r; assert(fd >= 0); assert(f < _ID128_FORMAT_MAX); if (f != ID128_UUID) { sd_id128_to_string(id, buffer); buffer[32] = '\n'; sz = 33; } else { id128_to_uuid_string(id, buffer); buffer[36] = '\n'; sz = 37; } r = loop_write(fd, buffer, sz, false); if (r < 0) return r; if (do_sync) { if (fsync(fd) < 0) return -errno; } return r; }
int main(int argc, char *argv[]) { sd_id128_t bid; char boot_id[SD_ID128_STRING_MAX]; _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *zz = NULL; assert_se(sd_id128_get_boot(&bid) >= 0); sd_id128_to_string(bid, boot_id); x = strjoin("/tmp/systemd-private-", boot_id, "-abcd.service-", NULL); y = strjoin("/var/tmp/systemd-private-", boot_id, "-abcd.service-", NULL); assert_se(x && y); test_tmpdir("abcd.service", x, y); z = strjoin("/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-", NULL); zz = strjoin("/var/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-", NULL); assert_se(z && zz); test_tmpdir("sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device", z, zz); test_netns(); return 0; }
static void test_condition_test_host(void) { Condition *condition; sd_id128_t id; int r; char sid[SD_ID128_STRING_MAX]; _cleanup_free_ char *hostname = NULL; r = sd_id128_get_machine(&id); assert_se(r >= 0); assert_se(sd_id128_to_string(id, sid)); condition = condition_new(CONDITION_HOST, sid, false, false); assert_se(condition_test(condition)); condition_free(condition); condition = condition_new(CONDITION_HOST, "garbage value jjjjjjjjjjjjjj", false, false); assert_se(!condition_test(condition)); condition_free(condition); condition = condition_new(CONDITION_HOST, sid, false, true); assert_se(!condition_test(condition)); condition_free(condition); hostname = gethostname_malloc(); assert_se(hostname); condition = condition_new(CONDITION_HOST, hostname, false, false); assert_se(condition_test(condition)); condition_free(condition); }
int boot_info_query(struct boot_info *info) { char str[64]; char buf[64]; char *loader_active = NULL; info->fw_secure_boot = is_efi_secure_boot(); info->fw_secure_boot_setup_mode = is_efi_secure_boot_setup_mode(); efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderInfo", &info->loader); get_boot_entries(info); if (info->fw_entries_count > 0) { get_boot_order(info); qsort(info->fw_entries, info->fw_entries_count, sizeof(struct boot_info_entry), entry_cmp); find_active_entry(info); } efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareType", &info->fw_type); efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareInfo", &info->fw_info); efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderImageIdentifier", &info->loader_image_path); tilt_slashes(info->loader_image_path); efi_loader_get_device_part_uuid(&info->loader_part_uuid); boot_loader_read_entries(info); efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntrySelected", &loader_active); if (loader_active) { boot_loader_find_active_entry(info, loader_active); free(loader_active); } snprintf(str, sizeof(str), "LoaderEntryOptions-%s", sd_id128_to_string(info->machine_id, buf)); efi_get_variable_string(EFI_VENDOR_LOADER, str, &info->loader_options_added); return 0; }
static int process_machine_id(void) { const char *etc_machine_id; char id[SD_ID128_STRING_MAX]; int r; etc_machine_id = prefix_roota("/etc/machine-id"); if (faccessat(AT_FDCWD, etc_machine_id, F_OK, AT_SYMLINK_NOFOLLOW) >= 0) return 0; if (!arg_root) return 0; if (sd_id128_equal(arg_machine_id, SD_ID128_NULL)) return 0; mkdir_parents(etc_machine_id, 0755); r = write_string_file(etc_machine_id, sd_id128_to_string(arg_machine_id, id)); if (r < 0) { log_error("Failed to write machine id: %s", strerror(-r)); return r; } log_info("%s written.", etc_machine_id); return 0; }
gboolean gl_util_can_read_user_journal (void) { GFile *file; GFileInfo *info; gint ret; gchar *path; gchar ids[33]; gchar *filename; gchar *uid; uid_t user_id; sd_id128_t machine; GError *error = NULL; GCredentials *credentials; credentials = g_credentials_new (); user_id = g_credentials_get_unix_user (credentials, &error); if (error != NULL) { g_debug ("Unable to get uid: %s", error->message); g_error_free (error); } uid = g_strdup_printf ("%d", user_id); filename = g_strconcat ("/user-", uid, ".journal", NULL); ret = sd_id128_get_machine (&machine); if (ret < 0) { g_critical ("Error getting machine id: %s", g_strerror (-ret)); } sd_id128_to_string (machine, ids); path = g_build_filename ("/var/log/journal", ids, filename, NULL); file = g_file_new_for_path (path); info = g_file_query_info (file, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, G_FILE_QUERY_INFO_NONE, NULL, NULL); g_free (uid); g_free (path); g_free (filename); g_object_unref (file); g_object_unref (credentials); if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ)) { g_object_unref (info); return TRUE; } else { g_object_unref (info); return FALSE; } }
int main(int argc, char *argv[]) { sd_id128_t id, id2; char t[33]; _cleanup_free_ char *b = NULL; assert_se(sd_id128_randomize(&id) == 0); printf("random: %s\n", sd_id128_to_string(id, t)); assert_se(sd_id128_from_string(t, &id2) == 0); assert_se(sd_id128_equal(id, id2)); if (sd_booted() > 0) { assert_se(sd_id128_get_machine(&id) == 0); printf("machine: %s\n", sd_id128_to_string(id, t)); assert_se(sd_id128_get_boot(&id) == 0); printf("boot: %s\n", sd_id128_to_string(id, t)); } printf("waldi: %s\n", sd_id128_to_string(ID128_WALDI, t)); assert_se(streq(t, STR_WALDI)); assert_se(asprintf(&b, SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 32); printf("waldi2: %s\n", b); assert_se(streq(t, b)); assert_se(sd_id128_from_string(UUID_WALDI, &id) >= 0); assert_se(sd_id128_equal(id, ID128_WALDI)); assert_se(sd_id128_from_string("", &id) < 0); assert_se(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f101", &id) < 0); assert_se(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f10-", &id) < 0); assert_se(sd_id128_from_string("01020304-0506-0708-090a0b0c0d0e0f10", &id) < 0); assert_se(sd_id128_from_string("010203040506-0708-090a-0b0c0d0e0f10", &id) < 0); assert_se(id128_is_valid(STR_WALDI)); assert_se(id128_is_valid(UUID_WALDI)); assert_se(!id128_is_valid("")); assert_se(!id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f101")); assert_se(!id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f10-")); assert_se(!id128_is_valid("01020304-0506-0708-090a0b0c0d0e0f10")); assert_se(!id128_is_valid("010203040506-0708-090a-0b0c0d0e0f10")); return 0; }
static int driver_get_id(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) { sd_id128_t server_id; char buf[SD_ID128_STRING_MAX]; int r; r = sd_bus_get_server_id(bus, &server_id); if (r < 0) return r; return sd_bus_reply_method_return(m, "s", sd_id128_to_string(server_id, buf)); }
gboolean gl_util_can_read_system_journal (GlJournalStorage storage_type) { GFile *file; GFileInfo *info; gint ret; gchar *path; gchar ids[33]; sd_id128_t machine; ret = sd_id128_get_machine (&machine); if (ret < 0) { g_critical ("Error getting machine id: %s", g_strerror (-ret)); } sd_id128_to_string (machine, ids); if (storage_type == GL_JOURNAL_STORAGE_PERSISTENT) { path = g_build_filename ("/var/log/journal", ids, "system.journal", NULL); } else if (storage_type == GL_JOURNAL_STORAGE_VOLATILE) { path = g_build_filename ("/run/log/journal", ids, "system.journal", NULL); } else { path = "/dev/null"; } file = g_file_new_for_path (path); info = g_file_query_info (file, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, G_FILE_QUERY_INFO_NONE, NULL, NULL); g_free (path); g_object_unref (file); if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ)) { g_object_unref (info); return TRUE; } else { g_object_unref (info); return FALSE; } }
static int process_machine_id(void) { const char *etc_machine_id; char id[SD_ID128_STRING_MAX]; int r; etc_machine_id = prefix_roota(arg_root, "/etc/machine-id"); if (laccess(etc_machine_id, F_OK) >= 0) return 0; if (sd_id128_is_null(arg_machine_id)) return 0; mkdir_parents(etc_machine_id, 0755); r = write_string_file(etc_machine_id, sd_id128_to_string(arg_machine_id, id), WRITE_STRING_FILE_CREATE | WRITE_STRING_FILE_SYNC); if (r < 0) return log_error_errno(r, "Failed to write machine id: %m"); log_info("%s written.", etc_machine_id); return 0; }
gboolean gl_util_can_read_system_journal (void) { GFile *file; GFileInfo *info; gint ret; gchar *path; gchar ids[33]; sd_id128_t machine; ret = sd_id128_get_machine (&machine); if (ret < 0) { g_critical ("Error getting machine id: %s", g_strerror (-ret)); } sd_id128_to_string (machine, ids); path = g_build_filename ("/var/log/journal", ids, "system.journal", NULL); file = g_file_new_for_path (path); info = g_file_query_info (file, G_FILE_ATTRIBUTE_ACCESS_CAN_READ, G_FILE_QUERY_INFO_NONE, NULL, NULL); g_free (path); g_object_unref (file); if (g_file_info_get_attribute_boolean (info, G_FILE_ATTRIBUTE_ACCESS_CAN_READ)) { g_object_unref (info); return TRUE; } else { g_object_unref (info); return FALSE; } }
static int add_this_boot(sd_journal *j) { char match[9+32+1] = "_BOOT_ID="; sd_id128_t boot_id; int r; if (!arg_this_boot) return 0; r = sd_id128_get_boot(&boot_id); if (r < 0) { log_error("Failed to get boot id: %s", strerror(-r)); return r; } sd_id128_to_string(boot_id, match + 9); r = sd_journal_add_match(j, match, strlen(match)); if (r < 0) { log_error("Failed to add match: %s", strerror(-r)); return r; } return 0; }
/** * Write up to size bytes to buf. Return negative on error, and number of * bytes written otherwise. The last case is a kind of an error too. */ static ssize_t write_entry(char *buf, size_t size, Uploader *u) { int r; size_t pos = 0; assert(size <= SSIZE_MAX); while (true) { switch(u->entry_state) { case ENTRY_CURSOR: { free(u->current_cursor); u->current_cursor = NULL; r = sd_journal_get_cursor(u->journal, &u->current_cursor); if (r < 0) return log_error_errno(r, "Failed to get cursor: %m"); r = snprintf(buf + pos, size - pos, "__CURSOR=%s\n", u->current_cursor); if (pos + r > size) /* not enough space */ return pos; u->entry_state ++; if (pos + r == size) { /* exactly one character short, but we don't need it */ buf[size - 1] = '\n'; return size; } pos += r; } /* fall through */ case ENTRY_REALTIME: { usec_t realtime; r = sd_journal_get_realtime_usec(u->journal, &realtime); if (r < 0) return log_error_errno(r, "Failed to get realtime timestamp: %m"); r = snprintf(buf + pos, size - pos, "__REALTIME_TIMESTAMP="USEC_FMT"\n", realtime); if (r + pos > size) /* not enough space */ return pos; u->entry_state ++; if (r + pos == size) { /* exactly one character short, but we don't need it */ buf[size - 1] = '\n'; return size; } pos += r; } /* fall through */ case ENTRY_MONOTONIC: { usec_t monotonic; sd_id128_t boot_id; r = sd_journal_get_monotonic_usec(u->journal, &monotonic, &boot_id); if (r < 0) return log_error_errno(r, "Failed to get monotonic timestamp: %m"); r = snprintf(buf + pos, size - pos, "__MONOTONIC_TIMESTAMP="USEC_FMT"\n", monotonic); if (r + pos > size) /* not enough space */ return pos; u->entry_state ++; if (r + pos == size) { /* exactly one character short, but we don't need it */ buf[size - 1] = '\n'; return size; } pos += r; } /* fall through */ case ENTRY_BOOT_ID: { sd_id128_t boot_id; char sid[33]; r = sd_journal_get_monotonic_usec(u->journal, NULL, &boot_id); if (r < 0) return log_error_errno(r, "Failed to get monotonic timestamp: %m"); r = snprintf(buf + pos, size - pos, "_BOOT_ID=%s\n", sd_id128_to_string(boot_id, sid)); if (r + pos > size) /* not enough space */ return pos; u->entry_state ++; if (r + pos == size) { /* exactly one character short, but we don't need it */ buf[size - 1] = '\n'; return size; } pos += r; } /* fall through */ case ENTRY_NEW_FIELD: { u->field_pos = 0; r = sd_journal_enumerate_data(u->journal, &u->field_data, &u->field_length); if (r < 0) return log_error_errno(r, "Failed to move to next field in entry: %m"); else if (r == 0) { u->entry_state = ENTRY_OUTRO; continue; } if (!utf8_is_printable_newline(u->field_data, u->field_length, false)) { u->entry_state = ENTRY_BINARY_FIELD_START; continue; } u->entry_state ++; } /* fall through */ case ENTRY_TEXT_FIELD: case ENTRY_BINARY_FIELD: { bool done; size_t tocopy; done = size - pos > u->field_length - u->field_pos; if (done) tocopy = u->field_length - u->field_pos; else tocopy = size - pos; memcpy(buf + pos, (char*) u->field_data + u->field_pos, tocopy); if (done) { buf[pos + tocopy] = '\n'; pos += tocopy + 1; u->entry_state = ENTRY_NEW_FIELD; continue; } else { u->field_pos += tocopy; return size; } } case ENTRY_BINARY_FIELD_START: { const char *c; size_t len; c = memchr(u->field_data, '=', u->field_length); if (!c || c == u->field_data) { log_error("Invalid field."); return -EINVAL; } len = c - (const char*)u->field_data; /* need space for label + '\n' */ if (size - pos < len + 1) return pos; memcpy(buf + pos, u->field_data, len); buf[pos + len] = '\n'; pos += len + 1; u->field_pos = len + 1; u->entry_state ++; } /* fall through */ case ENTRY_BINARY_FIELD_SIZE: { uint64_t le64; /* need space for uint64_t */ if (size - pos < 8) return pos; le64 = htole64(u->field_length - u->field_pos); memcpy(buf + pos, &le64, 8); pos += 8; u->entry_state ++; continue; } case ENTRY_OUTRO: /* need space for '\n' */ if (size - pos < 1) return pos; buf[pos++] = '\n'; u->entry_state ++; u->entries_sent ++; return pos; default: assert_not_reached("WTF?"); } } assert_not_reached("WTF?"); }
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 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"); /* (void) kill_and_sigcont(pid, SIGTERM); */ quit_usec = now(CLOCK_MONOTONIC) + DEFAULT_TIMEOUT_USEC; } finish: _exit(r < 0 ? EXIT_FAILURE : r); }
static int lldp_send_packet( int ifindex, const struct ether_addr *address, const void *packet, size_t packet_size) { union sockaddr_union sa = { .ll.sll_family = AF_PACKET, .ll.sll_protocol = htobe16(ETHERTYPE_LLDP), .ll.sll_ifindex = ifindex, .ll.sll_halen = ETH_ALEN, }; _cleanup_close_ int fd = -1; ssize_t l; assert(ifindex > 0); assert(address); assert(packet || packet_size <= 0); memcpy(sa.ll.sll_addr, address, ETH_ALEN); fd = socket(PF_PACKET, SOCK_RAW|SOCK_CLOEXEC, IPPROTO_RAW); if (fd < 0) return -errno; l = sendto(fd, packet, packet_size, MSG_NOSIGNAL, &sa.sa, sizeof(sa.ll)); if (l < 0) return -errno; if ((size_t) l != packet_size) return -EIO; return 0; } static int link_send_lldp(Link *link) { char machine_id_string[SD_ID128_STRING_MAX]; _cleanup_free_ char *hostname = NULL, *pretty_hostname = NULL; _cleanup_free_ void *packet = NULL; size_t packet_size = 0; sd_id128_t machine_id; uint16_t caps; usec_t ttl; int r; assert(link); if (!link->network || link->network->lldp_emit == LLDP_EMIT_NO) return 0; assert(link->network->lldp_emit < _LLDP_EMIT_MAX); r = sd_id128_get_machine(&machine_id); if (r < 0) return r; (void) gethostname_strict(&hostname); (void) parse_env_file("/etc/machine-info", NEWLINE, "PRETTY_HOSTNAME", &pretty_hostname, NULL); assert_cc(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1 <= (UINT16_MAX - 1) * USEC_PER_SEC); ttl = DIV_ROUND_UP(LLDP_TX_INTERVAL_USEC * LLDP_TX_HOLD + 1, USEC_PER_SEC); caps = (link->network && link->network->ip_forward != ADDRESS_FAMILY_NO) ? SD_LLDP_SYSTEM_CAPABILITIES_ROUTER : SD_LLDP_SYSTEM_CAPABILITIES_STATION; r = lldp_make_packet(link->network->lldp_emit, &link->mac, sd_id128_to_string(machine_id, machine_id_string), link->ifname, (uint16_t) ttl, link->network ? link->network->description : NULL, hostname, pretty_hostname, SD_LLDP_SYSTEM_CAPABILITIES_STATION|SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE|SD_LLDP_SYSTEM_CAPABILITIES_ROUTER, caps, &packet, &packet_size); if (r < 0) return r; return lldp_send_packet(link->ifindex, lldp_multicast_addr + link->network->lldp_emit, packet, packet_size); }
int main(int argc, char *argv[]) { sd_id128_t id, id2; char t[33], q[37]; _cleanup_free_ char *b = NULL; _cleanup_close_ int fd = -1; assert_se(sd_id128_randomize(&id) == 0); printf("random: %s\n", sd_id128_to_string(id, t)); assert_se(sd_id128_from_string(t, &id2) == 0); assert_se(sd_id128_equal(id, id2)); if (sd_booted() > 0) { assert_se(sd_id128_get_machine(&id) == 0); printf("machine: %s\n", sd_id128_to_string(id, t)); assert_se(sd_id128_get_boot(&id) == 0); printf("boot: %s\n", sd_id128_to_string(id, t)); } printf("waldi: %s\n", sd_id128_to_string(ID128_WALDI, t)); assert_se(streq(t, STR_WALDI)); assert_se(asprintf(&b, SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 32); printf("waldi2: %s\n", b); assert_se(streq(t, b)); printf("waldi3: %s\n", id128_to_uuid_string(ID128_WALDI, q)); assert_se(streq(q, UUID_WALDI)); b = mfree(b); assert_se(asprintf(&b, ID128_UUID_FORMAT_STR, SD_ID128_FORMAT_VAL(ID128_WALDI)) == 36); printf("waldi4: %s\n", b); assert_se(streq(q, b)); assert_se(sd_id128_from_string(STR_WALDI, &id) >= 0); assert_se(sd_id128_equal(id, ID128_WALDI)); assert_se(sd_id128_from_string(UUID_WALDI, &id) >= 0); assert_se(sd_id128_equal(id, ID128_WALDI)); assert_se(sd_id128_from_string("", &id) < 0); assert_se(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f101", &id) < 0); assert_se(sd_id128_from_string("01020304-0506-0708-090a-0b0c0d0e0f10-", &id) < 0); assert_se(sd_id128_from_string("01020304-0506-0708-090a0b0c0d0e0f10", &id) < 0); assert_se(sd_id128_from_string("010203040506-0708-090a-0b0c0d0e0f10", &id) < 0); assert_se(id128_is_valid(STR_WALDI)); assert_se(id128_is_valid(UUID_WALDI)); assert_se(!id128_is_valid("")); assert_se(!id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f101")); assert_se(!id128_is_valid("01020304-0506-0708-090a-0b0c0d0e0f10-")); assert_se(!id128_is_valid("01020304-0506-0708-090a0b0c0d0e0f10")); assert_se(!id128_is_valid("010203040506-0708-090a-0b0c0d0e0f10")); fd = open_tmpfile_unlinkable(NULL, O_RDWR|O_CLOEXEC); assert_se(fd >= 0); /* First, write as UUID */ assert_se(sd_id128_randomize(&id) >= 0); assert_se(id128_write_fd(fd, ID128_UUID, id, false) >= 0); assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL); assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0); assert_se(sd_id128_equal(id, id2)); assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(id128_read_fd(fd, ID128_ANY, &id2) >= 0); assert_se(sd_id128_equal(id, id2)); /* Second, write as plain */ assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(ftruncate(fd, 0) >= 0); assert_se(sd_id128_randomize(&id) >= 0); assert_se(id128_write_fd(fd, ID128_PLAIN, id, false) >= 0); assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(id128_read_fd(fd, ID128_UUID, &id2) == -EINVAL); assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) >= 0); assert_se(sd_id128_equal(id, id2)); assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(id128_read_fd(fd, ID128_ANY, &id2) >= 0); assert_se(sd_id128_equal(id, id2)); /* Third, write plain without trailing newline */ assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(ftruncate(fd, 0) >= 0); assert_se(sd_id128_randomize(&id) >= 0); assert_se(write(fd, sd_id128_to_string(id, t), 32) == 32); assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(id128_read_fd(fd, ID128_UUID, &id2) == -EINVAL); assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) >= 0); assert_se(sd_id128_equal(id, id2)); /* Third, write UUID without trailing newline */ assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(ftruncate(fd, 0) >= 0); assert_se(sd_id128_randomize(&id) >= 0); assert_se(write(fd, id128_to_uuid_string(id, q), 36) == 36); assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL); assert_se(lseek(fd, 0, SEEK_SET) == 0); assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0); assert_se(sd_id128_equal(id, id2)); return 0; }
static int show_status(char **args, unsigned n) { char buf[64]; struct boot_info *info; int err; err = boot_info_new(&info); if (err < 0) return -ENOMEM; err = boot_info_query(info); printf("System:\n"); printf(" Machine ID: %s\n", sd_id128_to_string(info->machine_id, buf)); printf(" Boot ID: %s\n", sd_id128_to_string(info->boot_id, buf)); if (info->fw_type) printf(" Firmware: %s (%s)\n", info->fw_type, strna(info->fw_info)); if (info->fw_secure_boot >= 0) printf(" Secure Boot: %s\n", info->fw_secure_boot ? "enabled" : "disabled"); if (info->fw_secure_boot_setup_mode >= 0) printf(" Setup Mode: %s\n", info->fw_secure_boot_setup_mode ? "setup" : "user"); printf("\n"); if (info->fw_entry_active >= 0) { printf("Selected Firmware Entry:\n"); printf(" Title: %s\n", strna(info->fw_entries[info->fw_entry_active].title)); if (!sd_id128_equal(info->fw_entries[info->fw_entry_active].part_uuid, SD_ID128_NULL)) printf(" Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", SD_ID128_FORMAT_VAL(info->fw_entries[info->fw_entry_active].part_uuid)); else printf(" Partition: n/a\n"); if (info->fw_entries[info->fw_entry_active].path) printf(" File: %s%s\n", draw_special_char(DRAW_TREE_RIGHT), info->fw_entries[info->fw_entry_active].path); } printf("\n"); if (info->loader) { printf("Boot Loader:\n"); printf(" Product: %s\n", info->loader); if (!sd_id128_equal(info->loader_part_uuid, SD_ID128_NULL)) printf(" Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n", SD_ID128_FORMAT_VAL(info->loader_part_uuid)); else printf(" Partition: n/a\n"); printf(" File: %s%s\n", draw_special_char(DRAW_TREE_RIGHT), strna(info->loader_image_path)); printf("\n"); if (info->loader_entry_active >= 0) { printf("Selected Boot Loader Entry:\n"); printf(" Title: %s\n", strna(info->loader_entries[info->loader_entry_active].title)); printf(" File: %s\n", info->loader_entries[info->loader_entry_active].path); if (info->loader_options_added) printf(" Options: %s\n", info->loader_options_added); } } else printf("No suitable data is provided by the boot manager. See:\n" " http://www.freedesktop.org/wiki/Software/systemd/BootLoaderInterface\n" " http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec\n" "for details.\n"); printf("\n"); boot_info_free(info); return err; }