static int lldp_parse_chassis_tlv(tlv_packet *m, uint8_t *type) { uint8_t *p, subtype; uint16_t length; assert_se(lldp_tlv_packet_enter_container(m, LLDP_TYPE_CHASSIS_ID) >= 0); assert_se(tlv_packet_read_u8(m, &subtype) >= 0); switch (subtype) { case LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS: *type = LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS; assert_se(tlv_packet_read_bytes(m, &p, &length) >= 0); assert_se(memcmp(p, &mac_addr.ether_addr_octet, ETHER_ADDR_LEN) == 0); break; default: assert_not_reached("Unhandled option"); } assert_se(lldp_tlv_packet_exit_container(m) >= 0); return 0; }
static inline void splay_tree_splaying_i(s_splay_tree_t **tree, uint32 path_mask) { assert_exit(NON_NULL_PTR_P(tree)); assert_exit(splay_tree_structure_legal_ip(*tree)); switch (path_mask) { case PATH_LEFT_TO_LEFT: splay_tree_splaying_left_to_left(tree); break; case PATH_LEFT_TO_RIGHT: splay_tree_splaying_left_to_right(tree); break; case PATH_RIGHT_TO_LEFT: splay_tree_splaying_right_to_left(tree); break; case PATH_RIGHT_TO_RIGHT: splay_tree_splaying_right_to_right(tree); break; default: assert_not_reached("Unexpected value of enum tree_path_type.\n"); break; } }
static int pppoe_timeout(sd_event_source *s, uint64_t usec, void *userdata) { sd_pppoe *ppp = userdata; int r; assert(ppp); switch (ppp->state) { case PPPOE_STATE_INITIALIZING: r = pppoe_send_initiation(ppp); if (r < 0) log_warning_errno(r, "PPPoE: sending PADI failed: %m"); break; case PPPOE_STATE_REQUESTING: if (ppp->padr_resend_count <= 0) { log_debug("PPPoE: PADR timed out, restarting PADI"); r = pppoe_send_initiation(ppp); if (r < 0) log_warning_errno(r, "PPPoE: sending PADI failed: %m"); ppp->padr_resend_count = PPPOE_MAX_PADR_RESEND; ppp->state = PPPOE_STATE_INITIALIZING; } else { r = pppoe_send_request(ppp); if (r < 0) log_warning_errno(r, "PPPoE: sending PADR failed: %m"); } break; default: assert_not_reached("timeout in invalid state"); } return 0; }
static void test_remove_destroys (void) { p11_dict *map; Key key = { 8, 0 }; int value = 0; bool ret; map = p11_dict_new (key_hash, key_equal, key_destroy, value_destroy); assert_ptr_not_null (map); if (!p11_dict_set (map, &key, &value)) assert_not_reached (); ret = p11_dict_remove (map, &key); assert_num_eq (true, ret); assert_num_eq (true, key.freed); assert_num_eq (2, value); /* should not be destroyed again */ key.freed = false; value = 0; ret = p11_dict_remove (map, &key); assert_num_eq (false, ret); assert_num_eq (false, key.freed); assert_num_eq (0, value); /* should not be destroyed again */ key.freed = false; value = 0; p11_dict_free (map); assert_num_eq (false, key.freed); assert_num_eq (0, value); }
void bus_gvariant_write_word_le(void *p, size_t sz, size_t value) { union { uint16_t u16; uint32_t u32; uint64_t u64; } x; assert(p); assert(sz == 8 || (value < (1ULL << (sz*8)))); if (sz == 1) { *(uint8_t*) p = value; return; } else if (sz == 2) x.u16 = htole16((uint16_t) value); else if (sz == 4) x.u32 = htole32((uint32_t) value); else if (sz == 8) x.u64 = htole64((uint64_t) value); else assert_not_reached("unknown word width"); memcpy(p, &x, sz); }
static int set_options(int argc, char **argv, char *maj_min_dev) { int option; /* * optind is a global extern used by getopt. Since we can call * set_options twice (once for command line, and once for config * file) we have to reset this back to 1. */ optind = 1; while ((option = getopt_long(argc, argv, "d:f:gp:uvVxhbs:", options, NULL)) >= 0) switch (option) { case 'b': all_good = false; break; case 'd': dev_specified = true; strscpy(maj_min_dev, MAX_PATH_LEN, optarg); break; case 'f': strscpy(config_file, MAX_PATH_LEN, optarg); break; case 'g': all_good = true; break; case 'h': help(); exit(EXIT_SUCCESS); case 'p': if (streq(optarg, "0x80")) default_page_code = PAGE_80; else if (streq(optarg, "0x83")) default_page_code = PAGE_83; else if (streq(optarg, "pre-spc3-83")) default_page_code = PAGE_83_PRE_SPC3; else return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown page code '%s'", optarg); break; case 's': sg_version = atoi(optarg); if (sg_version < 3 || sg_version > 4) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown SG version '%s'", optarg); break; case 'u': reformat_serial = true; break; case 'v': log_set_target(LOG_TARGET_CONSOLE); log_set_max_level(LOG_DEBUG); log_open(); break; case 'V': printf("%s\n", GIT_VERSION); exit(EXIT_SUCCESS); case 'x': export = true; break; case '?': return -1; default: assert_not_reached("Unknown option"); } if (optind < argc && !dev_specified) { dev_specified = true; strscpy(maj_min_dev, MAX_PATH_LEN, argv[optind]); } return 0; }
int main(int argc, char *argv[]) { bool need_umount, need_swapoff, need_loop_detach, need_dm_detach; bool in_container, use_watchdog = false; _cleanup_free_ char *cgroup = NULL; char *arguments[3]; unsigned retries; int cmd, r; static const char* const dirs[] = {SYSTEM_SHUTDOWN_PATH, NULL}; log_parse_environment(); r = parse_argv(argc, argv); if (r < 0) goto error; /* journald will die if not gone yet. The log target defaults * to console, but may have been changed by command line options. */ log_close_console(); /* force reopen of /dev/console */ log_open(); umask(0022); if (getpid() != 1) { log_error("Not executed by init (PID 1)."); r = -EPERM; goto error; } if (streq(arg_verb, "reboot")) cmd = RB_AUTOBOOT; else if (streq(arg_verb, "poweroff")) cmd = RB_POWER_OFF; else if (streq(arg_verb, "halt")) cmd = RB_HALT_SYSTEM; else if (streq(arg_verb, "kexec")) cmd = LINUX_REBOOT_CMD_KEXEC; else if (streq(arg_verb, "exit")) cmd = 0; /* ignored, just checking that arg_verb is valid */ else { r = -EINVAL; log_error("Unknown action '%s'.", arg_verb); goto error; } cg_get_root_path(&cgroup); use_watchdog = !!getenv("WATCHDOG_USEC"); /* lock us into memory */ mlockall(MCL_CURRENT|MCL_FUTURE); log_info("Sending SIGTERM to remaining processes..."); broadcast_signal(SIGTERM, true, true); log_info("Sending SIGKILL to remaining processes..."); broadcast_signal(SIGKILL, true, false); in_container = detect_container() > 0; need_umount = !in_container; need_swapoff = !in_container; need_loop_detach = !in_container; need_dm_detach = !in_container; /* Unmount all mountpoints, swaps, and loopback devices */ for (retries = 0; retries < FINALIZE_ATTEMPTS; retries++) { bool changed = false; if (use_watchdog) watchdog_ping(); /* Let's trim the cgroup tree on each iteration so that we leave an empty cgroup tree around, so that container managers get a nice notify event when we are down */ if (cgroup) cg_trim(SYSTEMD_CGROUP_CONTROLLER, cgroup, false); if (need_umount) { log_info("Unmounting file systems."); r = umount_all(&changed); if (r == 0) { need_umount = false; log_info("All filesystems unmounted."); } else if (r > 0) log_info("Not all file systems unmounted, %d left.", r); else log_error_errno(r, "Failed to unmount file systems: %m"); } if (need_swapoff) { log_info("Deactivating swaps."); r = swapoff_all(&changed); if (r == 0) { need_swapoff = false; log_info("All swaps deactivated."); } else if (r > 0) log_info("Not all swaps deactivated, %d left.", r); else log_error_errno(r, "Failed to deactivate swaps: %m"); } if (need_loop_detach) { log_info("Detaching loop devices."); r = loopback_detach_all(&changed); if (r == 0) { need_loop_detach = false; log_info("All loop devices detached."); } else if (r > 0) log_info("Not all loop devices detached, %d left.", r); else log_error_errno(r, "Failed to detach loop devices: %m"); } if (need_dm_detach) { log_info("Detaching DM devices."); r = dm_detach_all(&changed); if (r == 0) { need_dm_detach = false; log_info("All DM devices detached."); } else if (r > 0) log_info("Not all DM devices detached, %d left.", r); else log_error_errno(r, "Failed to detach DM devices: %m"); } if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach) { if (retries > 0) log_info("All filesystems, swaps, loop devices, DM devices detached."); /* Yay, done */ goto initrd_jump; } /* If in this iteration we didn't manage to * unmount/deactivate anything, we simply give up */ if (!changed) { log_info("Cannot finalize remaining%s%s%s%s continuing.", need_umount ? " file systems," : "", need_swapoff ? " swap devices," : "", need_loop_detach ? " loop devices," : "", need_dm_detach ? " DM devices," : ""); goto initrd_jump; } log_debug("After %u retries, couldn't finalize remaining %s%s%s%s trying again.", retries + 1, need_umount ? " file systems," : "", need_swapoff ? " swap devices," : "", need_loop_detach ? " loop devices," : "", need_dm_detach ? " DM devices," : ""); } log_error("Too many iterations, giving up."); initrd_jump: arguments[0] = NULL; arguments[1] = arg_verb; arguments[2] = NULL; execute_directories(dirs, DEFAULT_TIMEOUT_USEC, arguments); if (!in_container && !in_initrd() && access("/run/initramfs/shutdown", X_OK) == 0) { r = switch_root_initramfs(); if (r >= 0) { argv[0] = (char*) "/shutdown"; setsid(); make_console_stdio(); log_info("Successfully changed into root pivot.\n" "Returning to initrd..."); execv("/shutdown", argv); log_error_errno(errno, "Failed to execute shutdown binary: %m"); } else log_error_errno(r, "Failed to switch root to \"/run/initramfs\": %m"); } if (need_umount || need_swapoff || need_loop_detach || need_dm_detach) log_error("Failed to finalize %s%s%s%s ignoring", need_umount ? " file systems," : "", need_swapoff ? " swap devices," : "", need_loop_detach ? " loop devices," : "", need_dm_detach ? " DM devices," : ""); /* The kernel will automaticall flush ATA disks and suchlike * on reboot(), but the file systems need to be synce'd * explicitly in advance. So let's do this here, but not * needlessly slow down containers. */ if (!in_container) sync(); if (streq(arg_verb, "exit")) { if (in_container) exit(arg_exit_code); else { /* We cannot exit() on the host, fallback on another * method. */ cmd = RB_POWER_OFF; } } switch (cmd) { case LINUX_REBOOT_CMD_KEXEC: if (!in_container) { /* We cheat and exec kexec to avoid doing all its work */ pid_t pid; log_info("Rebooting with kexec."); pid = fork(); if (pid < 0) log_error_errno(errno, "Failed to fork: %m"); else if (pid == 0) { const char * const args[] = { KEXEC, "-e", NULL }; /* Child */ execv(args[0], (char * const *) args); _exit(EXIT_FAILURE); } else wait_for_terminate_and_warn("kexec", pid, true); } cmd = RB_AUTOBOOT; /* Fall through */ case RB_AUTOBOOT: if (!in_container) { _cleanup_free_ char *param = NULL; if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) { log_info("Rebooting with argument '%s'.", param); syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param); } } log_info("Rebooting."); break; case RB_POWER_OFF: log_info("Powering off."); break; case RB_HALT_SYSTEM: log_info("Halting system."); break; default: assert_not_reached("Unknown magic"); } reboot(cmd); if (errno == EPERM && in_container) { /* If we are in a container, and we lacked * CAP_SYS_BOOT just exit, this will kill our * container for good. */ log_info("Exiting container."); exit(0); } r = log_error_errno(errno, "Failed to invoke reboot(): %m"); error: log_emergency_errno(r, "Critical error while doing system shutdown: %m"); freeze(); }
static int parse_argv(int argc, char *argv[], Set *matches) { enum { ARG_VERSION = 0x100, ARG_NO_PAGER, ARG_NO_LEGEND, }; int r, c; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version" , no_argument, NULL, ARG_VERSION }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "no-legend", no_argument, NULL, ARG_NO_LEGEND }, { "output", required_argument, NULL, 'o' }, { "field", required_argument, NULL, 'F' }, { "directory", required_argument, NULL, 'D' }, {} }; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "ho:F:1D:", options, NULL)) >= 0) switch(c) { case 'h': arg_action = ACTION_NONE; help(); return 0; case ARG_VERSION: arg_action = ACTION_NONE; puts(PACKAGE_STRING); puts(SYSTEMD_FEATURES); return 0; case ARG_NO_PAGER: arg_no_pager = true; break; case ARG_NO_LEGEND: arg_no_legend = true; break; case 'o': if (arg_output) { log_error("cannot set output more than once"); return -EINVAL; } arg_output = fopen(optarg, "we"); if (!arg_output) return log_error_errno(errno, "writing to '%s': %m", optarg); break; case 'F': if (arg_field) { log_error("cannot use --field/-F more than once"); return -EINVAL; } arg_field = optarg; break; case '1': arg_one = true; break; case 'D': arg_directory = optarg; break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } if (optind < argc) { const char *cmd = argv[optind++]; if (streq(cmd, "list")) arg_action = ACTION_LIST; else if (streq(cmd, "dump")) arg_action = ACTION_DUMP; else if (streq(cmd, "gdb")) arg_action = ACTION_GDB; else if (streq(cmd, "info")) arg_action = ACTION_INFO; else { log_error("Unknown action '%s'", cmd); return -EINVAL; } } if (arg_field && arg_action != ACTION_LIST) { log_error("Option --field/-F only makes sense with list"); return -EINVAL; } while (optind < argc) { r = add_match(matches, argv[optind]); if (r != 0) return r; optind++; } return 0; }
static int device_read_db(sd_device *device) { _cleanup_free_ char *db = NULL; char *path; const char *id, *value; char key; size_t db_len; unsigned i; int r; enum { PRE_KEY, KEY, PRE_VALUE, VALUE, INVALID_LINE, } state = PRE_KEY; assert(device); if (device->db_loaded || device->sealed) return 0; r = device_get_id_filename(device, &id); if (r < 0) return r; path = strjoina("/run/udev/data/", id); r = read_full_file(path, &db, &db_len); if (r < 0) { if (r == -ENOENT) return 0; else return log_debug_errno(r, "sd-device: failed to read db '%s': %m", path); } /* devices with a database entry are initialized */ device_set_is_initialized(device); for (i = 0; i < db_len; i++) { switch (state) { case PRE_KEY: if (!strchr(NEWLINE, db[i])) { key = db[i]; state = KEY; } break; case KEY: if (db[i] != ':') { log_debug("sd-device: ignoring invalid db entry with key '%c'", key); state = INVALID_LINE; } else { db[i] = '\0'; state = PRE_VALUE; } break; case PRE_VALUE: value = &db[i]; state = VALUE; break; case INVALID_LINE: if (strchr(NEWLINE, db[i])) state = PRE_KEY; break; case VALUE: if (strchr(NEWLINE, db[i])) { db[i] = '\0'; r = handle_db_line(device, key, value); if (r < 0) log_debug_errno(r, "sd-device: failed to handle db entry '%c:%s': %m", key, value); state = PRE_KEY; } break; default: assert_not_reached("invalid state when parsing db"); } } device->db_loaded = true; return 0; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_WHAT, ARG_WHO, ARG_WHY, ARG_MODE, ARG_LIST, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "what", required_argument, NULL, ARG_WHAT }, { "who", required_argument, NULL, ARG_WHO }, { "why", required_argument, NULL, ARG_WHY }, { "mode", required_argument, NULL, ARG_MODE }, { "list", no_argument, NULL, ARG_LIST }, {} }; int c; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "+h", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: puts(PACKAGE_STRING); puts(SYSTEMD_FEATURES); return 0; case ARG_WHAT: arg_what = optarg; break; case ARG_WHO: arg_who = optarg; break; case ARG_WHY: arg_why = optarg; break; case ARG_MODE: arg_mode = optarg; break; case ARG_LIST: arg_action = ACTION_LIST; break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } if (arg_action == ACTION_INHIBIT && argc == 1) arg_action = ACTION_LIST; else if (arg_action == ACTION_INHIBIT && optind >= argc) { log_error("Missing command line to execute."); return -EINVAL; } return 1; }
static int test_dhcp_hangcheck(sd_event_source *s, uint64_t usec, void *userdata) { assert_not_reached("Test case should have completed in 2 seconds"); return 0; }
int config_parse_destination(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata) { Network *network = userdata; _cleanup_route_free_ Route *n = NULL; const char *address, *e; union in_addr_union buffer; unsigned char prefixlen; int r, f; assert(filename); assert(section); assert(lvalue); assert(rvalue); assert(data); r = route_new_static(network, section_line, &n); if (r < 0) return r; /* Destination|Source=address/prefixlen */ /* address */ e = strchr(rvalue, '/'); if (e) address = strndupa(rvalue, e - rvalue); else address = rvalue; r = in_addr_from_string_auto(address, &f, &buffer); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Destination is invalid, ignoring assignment: %s", address); return 0; } if (f != AF_INET && f != AF_INET6) { log_syntax(unit, LOG_ERR, filename, line, 0, "Unknown address family, ignoring assignment: %s", address); return 0; } /* prefixlen */ if (e) { r = safe_atou8(e + 1, &prefixlen); if (r < 0) { log_syntax(unit, LOG_ERR, filename, line, r, "Route destination prefix length is invalid, ignoring assignment: %s", e + 1); return 0; } } else { switch (f) { case AF_INET: prefixlen = 32; break; case AF_INET6: prefixlen = 128; break; } } n->family = f; if (streq(lvalue, "Destination")) { n->dst_addr = buffer; n->dst_prefixlen = prefixlen; } else if (streq(lvalue, "Source")) { n->src_addr = buffer; n->src_prefixlen = prefixlen; } else assert_not_reached(lvalue); n = NULL; return 0; }
int dns_server_new( Manager *m, DnsServer **ret, DnsServerType type, Link *l, int family, const union in_addr_union *in_addr, int ifindex) { DnsServer *s; assert(m); assert((type == DNS_SERVER_LINK) == !!l); assert(in_addr); if (!IN_SET(family, AF_INET, AF_INET6)) return -EAFNOSUPPORT; if (l) { if (l->n_dns_servers >= LINK_DNS_SERVERS_MAX) return -E2BIG; } else { if (m->n_dns_servers >= MANAGER_DNS_SERVERS_MAX) return -E2BIG; } s = new0(DnsServer, 1); if (!s) return -ENOMEM; s->n_ref = 1; s->manager = m; s->verified_feature_level = _DNS_SERVER_FEATURE_LEVEL_INVALID; s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_BEST; s->features_grace_period_usec = DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC; s->received_udp_packet_max = DNS_PACKET_UNICAST_SIZE_MAX; s->type = type; s->family = family; s->address = *in_addr; s->ifindex = ifindex; s->resend_timeout = DNS_TIMEOUT_MIN_USEC; switch (type) { case DNS_SERVER_LINK: s->link = l; LIST_APPEND(servers, l->dns_servers, s); l->n_dns_servers++; break; case DNS_SERVER_SYSTEM: LIST_APPEND(servers, m->dns_servers, s); m->n_dns_servers++; break; case DNS_SERVER_FALLBACK: LIST_APPEND(servers, m->fallback_dns_servers, s); m->n_dns_servers++; break; default: assert_not_reached("Unknown server type"); } s->linked = true; /* A new DNS server that isn't fallback is added and the one * we used so far was a fallback one? Then let's try to pick * the new one */ if (type != DNS_SERVER_FALLBACK && m->current_dns_server && m->current_dns_server->type == DNS_SERVER_FALLBACK) manager_set_dns_server(m, NULL); if (ret) *ret = s; return 0; }
int dhcp4_configure(Link *link) { int r; assert(link); assert(link->network); assert(link->network->dhcp & ADDRESS_FAMILY_IPV4); r = sd_dhcp_client_new(&link->dhcp_client); if (r < 0) return r; r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0); if (r < 0) return r; r = sd_dhcp_client_set_mac(link->dhcp_client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) return r; r = sd_dhcp_client_set_index(link->dhcp_client, link->ifindex); if (r < 0) return r; r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link); if (r < 0) return r; r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast); if (r < 0) return r; if (link->mtu) { r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu); if (r < 0) return r; } if (link->network->dhcp_mtu) { r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_INTERFACE_MTU); if (r < 0) return r; } if (link->network->dhcp_routes) { r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_STATIC_ROUTE); if (r < 0) return r; r = sd_dhcp_client_set_request_option(link->dhcp_client, DHCP_OPTION_CLASSLESS_STATIC_ROUTE); if (r < 0) return r; } if (link->network->dhcp_sendhost) { _cleanup_free_ char *hostname = NULL; const char *hn = NULL; if (!link->network->hostname) { hostname = gethostname_malloc(); if (!hostname) return -ENOMEM; hn = hostname; } else hn = link->network->hostname; if (!is_localhost(hn)) { r = sd_dhcp_client_set_hostname(link->dhcp_client, hn); if (r < 0) return r; } } if (link->network->dhcp_vendor_class_identifier) { r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client, link->network->dhcp_vendor_class_identifier); if (r < 0) return r; } switch (link->network->dhcp_client_identifier) { case DHCP_CLIENT_ID_DUID: /* Library defaults to this. */ break; case DHCP_CLIENT_ID_MAC: r = sd_dhcp_client_set_client_id(link->dhcp_client, ARPHRD_ETHER, (const uint8_t *) &link->mac, sizeof (link->mac)); if (r < 0) return r; break; default: assert_not_reached("Unknown client identifier type."); } return 0; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_NO_PAGER, ARG_ADJUST_SYSTEM_CLOCK, ARG_NO_ASK_PASSWORD, ARG_MONITOR, ARG_VALUE, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "host", required_argument, NULL, 'H' }, { "machine", required_argument, NULL, 'M' }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, { "adjust-system-clock", no_argument, NULL, ARG_ADJUST_SYSTEM_CLOCK }, { "monitor", no_argument, NULL, ARG_MONITOR }, { "property", required_argument, NULL, 'p' }, { "all", no_argument, NULL, 'a' }, { "value", no_argument, NULL, ARG_VALUE }, {} }; int c, r; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "hH:M:p:a", options, NULL)) >= 0) switch (c) { case 'h': return help(); case ARG_VERSION: return version(); case 'H': arg_transport = BUS_TRANSPORT_REMOTE; arg_host = optarg; break; case 'M': arg_transport = BUS_TRANSPORT_MACHINE; arg_host = optarg; break; case ARG_NO_ASK_PASSWORD: arg_ask_password = false; break; case ARG_ADJUST_SYSTEM_CLOCK: arg_adjust_system_clock = true; break; case ARG_NO_PAGER: arg_pager_flags |= PAGER_DISABLE; break; case ARG_MONITOR: arg_monitor = true; break; case 'p': { r = strv_extend(&arg_property, optarg); if (r < 0) return log_oom(); /* If the user asked for a particular * property, show it to him, even if it is * empty. */ arg_all = true; break; } case 'a': arg_all = true; break; case ARG_VALUE: arg_value = true; break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } return 1; }
int dhcp4_configure(Link *link) { int r; assert(link); assert(link->network); assert(link->network->dhcp & ADDRESS_FAMILY_IPV4); if (!link->dhcp_client) { r = sd_dhcp_client_new(&link->dhcp_client); if (r < 0) return r; } r = sd_dhcp_client_attach_event(link->dhcp_client, NULL, 0); if (r < 0) return r; r = sd_dhcp_client_set_mac(link->dhcp_client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) return r; r = sd_dhcp_client_set_ifindex(link->dhcp_client, link->ifindex); if (r < 0) return r; r = sd_dhcp_client_set_callback(link->dhcp_client, dhcp4_handler, link); if (r < 0) return r; r = sd_dhcp_client_set_request_broadcast(link->dhcp_client, link->network->dhcp_broadcast); if (r < 0) return r; if (link->mtu) { r = sd_dhcp_client_set_mtu(link->dhcp_client, link->mtu); if (r < 0) return r; } if (link->network->dhcp_use_mtu) { r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_INTERFACE_MTU); if (r < 0) return r; } if (link->network->dhcp_use_routes) { r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_STATIC_ROUTE); if (r < 0) return r; r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE); if (r < 0) return r; } /* Always acquire the timezone and NTP */ r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NTP_SERVER); if (r < 0) return r; r = sd_dhcp_client_set_request_option(link->dhcp_client, SD_DHCP_OPTION_NEW_TZDB_TIMEZONE); if (r < 0) return r; r = dhcp4_set_hostname(link); if (r < 0) return r; if (link->network->dhcp_vendor_class_identifier) { r = sd_dhcp_client_set_vendor_class_identifier(link->dhcp_client, link->network->dhcp_vendor_class_identifier); if (r < 0) return r; } if (link->network->dhcp_client_port) { r = sd_dhcp_client_set_client_port(link->dhcp_client, link->network->dhcp_client_port); if (r < 0) return r; } switch (link->network->dhcp_client_identifier) { case DHCP_CLIENT_ID_DUID: { /* If configured, apply user specified DUID and/or IAID */ const DUID *duid = link_duid(link); r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, link->network->iaid, duid->type, duid->raw_data_len > 0 ? duid->raw_data : NULL, duid->raw_data_len); if (r < 0) return r; break; } case DHCP_CLIENT_ID_MAC: r = sd_dhcp_client_set_client_id(link->dhcp_client, ARPHRD_ETHER, (const uint8_t *) &link->mac, sizeof(link->mac)); if (r < 0) return r; break; default: assert_not_reached("Unknown client identifier type."); } return 0; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_NO_PAGER = 0x100, ARG_VERSION, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "all", no_argument, NULL, 'a' }, { "full", no_argument, NULL, 'l' }, { "machine", required_argument, NULL, 'M' }, {} }; int c; assert(argc >= 1); assert(argv); while ((c = getopt_long(argc, argv, "hkalM:", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: return version(); case ARG_NO_PAGER: arg_no_pager = true; break; case 'a': arg_all = true; break; case 'l': arg_full = true; break; case 'k': arg_kernel_threads = true; break; case 'M': arg_machine = optarg; break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } return 1; }
static int localectl_main(DBusConnection *bus, int argc, char *argv[], DBusError *error) { static const struct { const char* verb; const enum { MORE, LESS, EQUAL } argc_cmp; const int argc; int (* const dispatch)(DBusConnection *bus, char **args, unsigned n); } verbs[] = { { "status", LESS, 1, show_status }, { "set-locale", MORE, 2, set_locale }, { "list-locales", EQUAL, 1, list_locales }, { "set-keymap", MORE, 2, set_vconsole_keymap }, { "list-keymaps", EQUAL, 1, list_vconsole_keymaps }, { "set-x11-keymap", MORE, 2, set_x11_keymap }, }; int left; unsigned i; assert(argc >= 0); assert(argv); assert(error); left = argc - optind; if (left <= 0) /* Special rule: no arguments means "status" */ i = 0; else { if (streq(argv[optind], "help")) { help(); return 0; } for (i = 0; i < ELEMENTSOF(verbs); i++) if (streq(argv[optind], verbs[i].verb)) break; if (i >= ELEMENTSOF(verbs)) { log_error("Unknown operation %s", argv[optind]); return -EINVAL; } } switch (verbs[i].argc_cmp) { case EQUAL: if (left != verbs[i].argc) { log_error("Invalid number of arguments."); return -EINVAL; } break; case MORE: if (left < verbs[i].argc) { log_error("Too few arguments."); return -EINVAL; } break; case LESS: if (left > verbs[i].argc) { log_error("Too many arguments."); return -EINVAL; } break; default: assert_not_reached("Unknown comparison operator."); } if (!bus) { log_error("Failed to get D-Bus connection: %s", error->message); return -EIO; } return verbs[i].dispatch(bus, argv + optind, left); }
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 distuingish 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__) || defined(__sparc64__) { "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 }, #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 int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_NO_PAGER, ARG_ADJUST_SYSTEM_CLOCK, ARG_NO_ASK_PASSWORD }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "host", required_argument, NULL, 'H' }, { "machine", required_argument, NULL, 'M' }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, { "adjust-system-clock", no_argument, NULL, ARG_ADJUST_SYSTEM_CLOCK }, {} }; int c; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: return version(); case 'H': arg_transport = BUS_TRANSPORT_REMOTE; arg_host = optarg; break; case 'M': arg_transport = BUS_TRANSPORT_MACHINE; arg_host = optarg; break; case ARG_NO_ASK_PASSWORD: arg_ask_password = false; break; case ARG_ADJUST_SYSTEM_CLOCK: arg_adjust_system_clock = true; break; case ARG_NO_PAGER: arg_no_pager = true; break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } return 1; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_FILES_MAX, ARG_FILE_SIZE_MAX, ARG_TIMEOUT }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "files-max", required_argument, NULL, ARG_FILES_MAX }, { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX }, { "timeout", required_argument, NULL, ARG_TIMEOUT }, {} }; int c; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { switch (c) { case 'h': return help(); case ARG_VERSION: puts(PACKAGE_STRING); puts(SYSTEMD_FEATURES); return 0; case ARG_FILES_MAX: if (safe_atou(optarg, &arg_files_max) < 0 || arg_files_max <= 0) { log_error("Failed to parse maximum number of files %s.", optarg); return -EINVAL; } break; case ARG_FILE_SIZE_MAX: { unsigned long long ull; if (safe_atollu(optarg, &ull) < 0 || ull <= 0) { log_error("Failed to parse maximum file size %s.", optarg); return -EINVAL; } arg_file_size_max = (off_t) ull; break; } case ARG_TIMEOUT: if (parse_sec(optarg, &arg_timeout) < 0 || arg_timeout <= 0) { log_error("Failed to parse timeout %s.", optarg); return -EINVAL; } break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } } if (optind != argc-1 && optind != argc-2) { help(); return -EINVAL; } return 1; }
static void test_linked_units(const char *root) { const char *p, *q; UnitFileState state; UnitFileChange *changes = NULL; unsigned n_changes = 0, i; /* * We'll test three cases here: * * a) a unit file in /opt, that we use "systemctl link" and * "systemctl enable" on to make it available to the system * * b) a unit file in /opt, that is statically linked into * /usr/lib/systemd/system, that "enable" should work on * correctly. * * c) a unit file in /opt, that is linked into * /etc/systemd/system, and where "enable" should result in * -ELOOP, since using information from /etc to generate * information in /etc should not be allowed. */ p = strjoina(root, "/opt/linked.service"); assert_se(write_string_file(p, "[Install]\n" "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); p = strjoina(root, "/opt/linked2.service"); assert_se(write_string_file(p, "[Install]\n" "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); p = strjoina(root, "/opt/linked3.service"); assert_se(write_string_file(p, "[Install]\n" "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked2.service", NULL) == -ENOENT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked3.service", NULL) == -ENOENT); p = strjoina(root, "/usr/lib/systemd/system/linked2.service"); assert_se(symlink("/opt/linked2.service", p) >= 0); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked3.service"); assert_se(symlink("/opt/linked3.service", p) >= 0); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) == -ENOENT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked2.service", &state) >= 0 && state == UNIT_FILE_DISABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked3.service", &state) >= 0 && state == UNIT_FILE_LINKED); /* First, let's link the unit into the search path */ assert_se(unit_file_link(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/opt/linked.service")); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_LINKED); /* Let's unlink it from the search path again */ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_UNLINK); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT); /* Now, let's not just link it, but also enable it */ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 2); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service"); q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); for (i = 0 ; i < n_changes; i++) { assert_se(changes[i].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[i].source, "/opt/linked.service")); if (p && streq(changes[i].path, p)) p = NULL; else if (q && streq(changes[i].path, q)) q = NULL; else assert_not_reached("wut?"); } assert(!p && !q); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_ENABLED); /* And let's unlink it again */ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 2); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service"); q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); for (i = 0; i < n_changes; i++) { assert_se(changes[i].type == UNIT_FILE_UNLINK); if (p && streq(changes[i].path, p)) p = NULL; else if (q && streq(changes[i].path, q)) q = NULL; else assert_not_reached("wut?"); } assert(!p && !q); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked2.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 2); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked2.service"); q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked2.service"); for (i = 0 ; i < n_changes; i++) { assert_se(changes[i].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[i].source, "/opt/linked2.service")); if (p && streq(changes[i].path, p)) p = NULL; else if (q && streq(changes[i].path, q)) q = NULL; else assert_not_reached("wut?"); } assert(!p && !q); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked3.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(startswith(changes[0].path, root)); assert_se(endswith(changes[0].path, "linked3.service")); assert_se(streq(changes[0].source, "/opt/linked3.service")); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_ROOT, ARG_LOCALE, ARG_LOCALE_MESSAGES, ARG_TIMEZONE, ARG_HOSTNAME, ARG_MACHINE_ID, ARG_ROOT_PASSWORD, ARG_ROOT_PASSWORD_FILE, ARG_PROMPT, ARG_PROMPT_LOCALE, ARG_PROMPT_TIMEZONE, ARG_PROMPT_HOSTNAME, ARG_PROMPT_ROOT_PASSWORD, ARG_COPY, ARG_COPY_LOCALE, ARG_COPY_TIMEZONE, ARG_COPY_ROOT_PASSWORD, ARG_SETUP_MACHINE_ID, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "root", required_argument, NULL, ARG_ROOT }, { "locale", required_argument, NULL, ARG_LOCALE }, { "locale-messages", required_argument, NULL, ARG_LOCALE_MESSAGES }, { "timezone", required_argument, NULL, ARG_TIMEZONE }, { "hostname", required_argument, NULL, ARG_HOSTNAME }, { "machine-id", required_argument, NULL, ARG_MACHINE_ID }, { "root-password", required_argument, NULL, ARG_ROOT_PASSWORD }, { "root-password-file", required_argument, NULL, ARG_ROOT_PASSWORD_FILE }, { "prompt", no_argument, NULL, ARG_PROMPT }, { "prompt-locale", no_argument, NULL, ARG_PROMPT_LOCALE }, { "prompt-timezone", no_argument, NULL, ARG_PROMPT_TIMEZONE }, { "prompt-hostname", no_argument, NULL, ARG_PROMPT_HOSTNAME }, { "prompt-root-password", no_argument, NULL, ARG_PROMPT_ROOT_PASSWORD }, { "copy", no_argument, NULL, ARG_COPY }, { "copy-locale", no_argument, NULL, ARG_COPY_LOCALE }, { "copy-timezone", no_argument, NULL, ARG_COPY_TIMEZONE }, { "copy-root-password", no_argument, NULL, ARG_COPY_ROOT_PASSWORD }, { "setup-machine-id", no_argument, NULL, ARG_SETUP_MACHINE_ID }, {} }; int r, c; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: return version(); case ARG_ROOT: free(arg_root); arg_root = path_make_absolute_cwd(optarg); if (!arg_root) return log_oom(); path_kill_slashes(arg_root); if (path_equal(arg_root, "/")) arg_root = mfree(arg_root); break; case ARG_LOCALE: if (!locale_is_valid(optarg)) { log_error("Locale %s is not valid.", optarg); return -EINVAL; } r = free_and_strdup(&arg_locale, optarg); if (r < 0) return log_oom(); break; case ARG_LOCALE_MESSAGES: if (!locale_is_valid(optarg)) { log_error("Locale %s is not valid.", optarg); return -EINVAL; } r = free_and_strdup(&arg_locale_messages, optarg); if (r < 0) return log_oom(); break; case ARG_TIMEZONE: if (!timezone_is_valid(optarg)) { log_error("Timezone %s is not valid.", optarg); return -EINVAL; } r = free_and_strdup(&arg_timezone, optarg); if (r < 0) return log_oom(); break; case ARG_ROOT_PASSWORD: r = free_and_strdup(&arg_root_password, optarg); if (r < 0) return log_oom(); break; case ARG_ROOT_PASSWORD_FILE: arg_root_password = mfree(arg_root_password); r = read_one_line_file(optarg, &arg_root_password); if (r < 0) return log_error_errno(r, "Failed to read %s: %m", optarg); break; case ARG_HOSTNAME: if (!hostname_is_valid(optarg, true)) { log_error("Host name %s is not valid.", optarg); return -EINVAL; } hostname_cleanup(optarg); r = free_and_strdup(&arg_hostname, optarg); if (r < 0) return log_oom(); break; case ARG_MACHINE_ID: if (sd_id128_from_string(optarg, &arg_machine_id) < 0) { log_error("Failed to parse machine id %s.", optarg); return -EINVAL; } break; case ARG_PROMPT: arg_prompt_locale = arg_prompt_timezone = arg_prompt_hostname = arg_prompt_root_password = true; break; case ARG_PROMPT_LOCALE: arg_prompt_locale = true; break; case ARG_PROMPT_TIMEZONE: arg_prompt_timezone = true; break; case ARG_PROMPT_HOSTNAME: arg_prompt_hostname = true; break; case ARG_PROMPT_ROOT_PASSWORD: arg_prompt_root_password = true; break; case ARG_COPY: arg_copy_locale = arg_copy_timezone = arg_copy_root_password = true; break; case ARG_COPY_LOCALE: arg_copy_locale = true; break; case ARG_COPY_TIMEZONE: arg_copy_timezone = true; break; case ARG_COPY_ROOT_PASSWORD: arg_copy_root_password = true; break; case ARG_SETUP_MACHINE_ID: r = sd_id128_randomize(&arg_machine_id); if (r < 0) return log_error_errno(r, "Failed to generate randomized machine ID: %m"); break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } return 1; }
int parse_sleep_config(const char *verb, char ***_modes, char ***_states) { _cleanup_strv_free_ char **suspend_mode = NULL, **suspend_state = NULL, **hibernate_mode = NULL, **hibernate_state = NULL, **hybrid_mode = NULL, **hybrid_state = NULL; char **modes, **states; const ConfigTableItem items[] = { { "Sleep", "SuspendMode", config_parse_strv, 0, &suspend_mode }, { "Sleep", "SuspendState", config_parse_strv, 0, &suspend_state }, { "Sleep", "HibernateMode", config_parse_strv, 0, &hibernate_mode }, { "Sleep", "HibernateState", config_parse_strv, 0, &hibernate_state }, { "Sleep", "HybridSleepMode", config_parse_strv, 0, &hybrid_mode }, { "Sleep", "HybridSleepState", config_parse_strv, 0, &hybrid_state }, {} }; int r; _cleanup_fclose_ FILE *f; f = fopen(PKGSYSCONFDIR "/sleep.conf", "re"); if (!f) log_full(errno == ENOENT ? LOG_DEBUG: LOG_WARNING, "Failed to open configuration file " PKGSYSCONFDIR "/sleep.conf: %m"); else { r = config_parse(NULL, PKGSYSCONFDIR "/sleep.conf", f, "Sleep\0", config_item_table_lookup, (void*) items, false, false, NULL); if (r < 0) log_warning("Failed to parse configuration file: %s", strerror(-r)); } if (streq(verb, "suspend")) { /* empty by default */ USE(modes, suspend_mode); if (suspend_state) USE(states, suspend_state); else states = strv_new("mem", "standby", "freeze", NULL); } else if (streq(verb, "hibernate")) { if (hibernate_mode) USE(modes, hibernate_mode); else modes = strv_new("platform", "shutdown", NULL); if (hibernate_state) USE(states, hibernate_state); else states = strv_new("disk", NULL); } else if (streq(verb, "hybrid-sleep")) { if (hybrid_mode) USE(modes, hybrid_mode); else modes = strv_new("suspend", "platform", "shutdown", NULL); if (hybrid_state) USE(states, hybrid_state); else states = strv_new("disk", NULL); } else assert_not_reached("what verb"); if ((!modes && !streq(verb, "suspend")) || !states) { strv_free(modes); strv_free(states); return log_oom(); } *_modes = modes; *_states = states; return 0; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_DEPTH, ARG_CPU_TYPE, ARG_ORDER, ARG_RECURSIVE, }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "delay", required_argument, NULL, 'd' }, { "iterations", required_argument, NULL, 'n' }, { "batch", no_argument, NULL, 'b' }, { "raw", no_argument, NULL, 'r' }, { "depth", required_argument, NULL, ARG_DEPTH }, { "cpu", optional_argument, NULL, ARG_CPU_TYPE }, { "order", required_argument, NULL, ARG_ORDER }, { "recursive", required_argument, NULL, ARG_RECURSIVE }, { "machine", required_argument, NULL, 'M' }, {} }; bool recursive_unset = false; int c, r; assert(argc >= 1); assert(argv); while ((c = getopt_long(argc, argv, "hptcmin:brd:kPM:", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: return version(); case ARG_CPU_TYPE: if (optarg) { if (streq(optarg, "time")) arg_cpu_type = CPU_TIME; else if (streq(optarg, "percentage")) arg_cpu_type = CPU_PERCENT; else { log_error("Unknown argument to --cpu=: %s", optarg); return -EINVAL; } } else arg_cpu_type = CPU_TIME; break; case ARG_DEPTH: r = safe_atou(optarg, &arg_depth); if (r < 0) { log_error("Failed to parse depth parameter."); return -EINVAL; } break; case 'd': r = parse_sec(optarg, &arg_delay); if (r < 0 || arg_delay <= 0) { log_error("Failed to parse delay parameter."); return -EINVAL; } break; case 'n': r = safe_atou(optarg, &arg_iterations); if (r < 0) { log_error("Failed to parse iterations parameter."); return -EINVAL; } break; case 'b': arg_batch = true; break; case 'r': arg_raw = true; break; case 'p': arg_order = ORDER_PATH; break; case 't': arg_order = ORDER_TASKS; break; case 'c': arg_order = ORDER_CPU; break; case 'm': arg_order = ORDER_MEMORY; break; case 'i': arg_order = ORDER_IO; break; case ARG_ORDER: if (streq(optarg, "path")) arg_order = ORDER_PATH; else if (streq(optarg, "tasks")) arg_order = ORDER_TASKS; else if (streq(optarg, "cpu")) arg_order = ORDER_CPU; else if (streq(optarg, "memory")) arg_order = ORDER_MEMORY; else if (streq(optarg, "io")) arg_order = ORDER_IO; else { log_error("Invalid argument to --order=: %s", optarg); return -EINVAL; } break; case 'k': arg_count = COUNT_ALL_PROCESSES; break; case 'P': arg_count = COUNT_USERSPACE_PROCESSES; break; case ARG_RECURSIVE: r = parse_boolean(optarg); if (r < 0) { log_error("Failed to parse --recursive= argument: %s", optarg); return r; } arg_recursive = r; recursive_unset = r == 0; break; case 'M': arg_machine = optarg; break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } if (optind == argc-1) { if (arg_machine) { log_error("Specifying a control group path together with the -M option is not allowed"); return -EINVAL; } arg_root = argv[optind]; } else if (optind < argc) { log_error("Too many arguments."); return -EINVAL; } if (recursive_unset && arg_count == COUNT_PIDS) { log_error("Non-recursive counting is only supported when counting processes, not tasks. Use -P or -k."); return -EINVAL; } return 1; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_NO_ASK_PASSWORD, ARG_TRANSIENT, ARG_STATIC, ARG_PRETTY }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "transient", no_argument, NULL, ARG_TRANSIENT }, { "static", no_argument, NULL, ARG_STATIC }, { "pretty", no_argument, NULL, ARG_PRETTY }, { "host", required_argument, NULL, 'H' }, { "machine", required_argument, NULL, 'M' }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, {} }; int c; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "hH:M:", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: puts(PACKAGE_STRING); puts(SYSTEMD_FEATURES); return 0; case 'H': arg_transport = BUS_TRANSPORT_REMOTE; arg_host = optarg; break; case 'M': arg_transport = BUS_TRANSPORT_MACHINE; arg_host = optarg; break; case ARG_TRANSIENT: arg_transient = true; break; case ARG_PRETTY: arg_pretty = true; break; case ARG_STATIC: arg_static = true; break; case ARG_NO_ASK_PASSWORD: arg_ask_password = false; break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } return 1; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_LOG_LEVEL = 0x100, ARG_LOG_TARGET, ARG_LOG_COLOR, ARG_LOG_LOCATION, ARG_EXIT_CODE, }; static const struct option options[] = { { "log-level", required_argument, NULL, ARG_LOG_LEVEL }, { "log-target", required_argument, NULL, ARG_LOG_TARGET }, { "log-color", optional_argument, NULL, ARG_LOG_COLOR }, { "log-location", optional_argument, NULL, ARG_LOG_LOCATION }, { "exit-code", required_argument, NULL, ARG_EXIT_CODE }, {} }; int c, r; assert(argc >= 1); assert(argv); /* "-" prevents getopt from permuting argv[] and moving the verb away * from argv[1]. Our interface to initrd promises it'll be there. */ while ((c = getopt_long(argc, argv, "-", options, NULL)) >= 0) switch (c) { case ARG_LOG_LEVEL: r = log_set_max_level_from_string(optarg); if (r < 0) log_error("Failed to parse log level %s, ignoring.", optarg); break; case ARG_LOG_TARGET: r = log_set_target_from_string(optarg); if (r < 0) log_error("Failed to parse log target %s, ignoring", optarg); break; case ARG_LOG_COLOR: if (optarg) { r = log_show_color_from_string(optarg); if (r < 0) log_error("Failed to parse log color setting %s, ignoring", optarg); } else log_show_color(true); break; case ARG_LOG_LOCATION: if (optarg) { r = log_show_location_from_string(optarg); if (r < 0) log_error("Failed to parse log location setting %s, ignoring", optarg); } else log_show_location(true); break; case ARG_EXIT_CODE: r = safe_atou8(optarg, &arg_exit_code); if (r < 0) log_error("Failed to parse exit code %s, ignoring", optarg); break; case '\001': if (!arg_verb) arg_verb = optarg; else log_error("Excess arguments, ignoring"); break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option code."); } if (!arg_verb) { log_error("Verb argument missing."); return -EINVAL; } return 0; }
static int hostnamectl_main(sd_bus *bus, int argc, char *argv[]) { static const struct { const char* verb; const enum { MORE, LESS, EQUAL } argc_cmp; const int argc; int (* const dispatch)(sd_bus *bus, char **args, unsigned n); } verbs[] = { { "status", LESS, 1, show_status }, { "set-hostname", EQUAL, 2, set_hostname }, { "set-icon-name", EQUAL, 2, set_icon_name }, { "set-chassis", EQUAL, 2, set_chassis }, { "set-deployment", EQUAL, 2, set_deployment }, { "set-location", EQUAL, 2, set_location }, }; int left; unsigned i; assert(argc >= 0); assert(argv); left = argc - optind; if (left <= 0) /* Special rule: no arguments means "status" */ i = 0; else { if (streq(argv[optind], "help")) { help(); return 0; } for (i = 0; i < ELEMENTSOF(verbs); i++) if (streq(argv[optind], verbs[i].verb)) break; if (i >= ELEMENTSOF(verbs)) { log_error("Unknown operation %s", argv[optind]); return -EINVAL; } } switch (verbs[i].argc_cmp) { case EQUAL: if (left != verbs[i].argc) { log_error("Invalid number of arguments."); return -EINVAL; } break; case MORE: if (left < verbs[i].argc) { log_error("Too few arguments."); return -EINVAL; } break; case LESS: if (left > verbs[i].argc) { log_error("Too many arguments."); return -EINVAL; } break; default: assert_not_reached("Unknown comparison operator."); } return verbs[i].dispatch(bus, argv + optind, left); }
static int output_timestamp_realtime(FILE *f, sd_journal *j, OutputMode mode, OutputFlags flags, const char *realtime) { char buf[MAX(FORMAT_TIMESTAMP_MAX, 64)]; struct tm *(*gettime_r)(const time_t *, struct tm *); struct tm tm; uint64_t x; time_t t; int r; assert(f); assert(j); if (realtime) r = safe_atou64(realtime, &x); if (!realtime || r < 0 || !VALID_REALTIME(x)) r = sd_journal_get_realtime_usec(j, &x); if (r < 0) return log_error_errno(r, "Failed to get realtime timestamp: %m"); if (IN_SET(mode, OUTPUT_SHORT_FULL, OUTPUT_WITH_UNIT)) { const char *k; if (flags & OUTPUT_UTC) k = format_timestamp_utc(buf, sizeof(buf), x); else k = format_timestamp(buf, sizeof(buf), x); if (!k) { log_error("Failed to format timestamp: %"PRIu64, x); return -EINVAL; } } else { char usec[7]; gettime_r = (flags & OUTPUT_UTC) ? gmtime_r : localtime_r; t = (time_t) (x / USEC_PER_SEC); switch (mode) { case OUTPUT_SHORT_UNIX: xsprintf(buf, "%10"PRI_TIME".%06"PRIu64, t, x % USEC_PER_SEC); break; case OUTPUT_SHORT_ISO: if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", gettime_r(&t, &tm)) <= 0) { log_error("Failed to format ISO time"); return -EINVAL; } break; case OUTPUT_SHORT_ISO_PRECISE: /* No usec in strftime, so we leave space and copy over */ if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S.xxxxxx%z", gettime_r(&t, &tm)) <= 0) { log_error("Failed to format ISO-precise time"); return -EINVAL; } xsprintf(usec, "%06"PRI_USEC, x % USEC_PER_SEC); memcpy(buf + 20, usec, 6); break; case OUTPUT_SHORT: case OUTPUT_SHORT_PRECISE: if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", gettime_r(&t, &tm)) <= 0) { log_error("Failed to format syslog time"); return -EINVAL; } if (mode == OUTPUT_SHORT_PRECISE) { size_t k; assert(sizeof(buf) > strlen(buf)); k = sizeof(buf) - strlen(buf); r = snprintf(buf + strlen(buf), k, ".%06"PRIu64, x % USEC_PER_SEC); if (r <= 0 || (size_t) r >= k) { /* too long? */ log_error("Failed to format precise time"); return -EINVAL; } } break; default: assert_not_reached("Unknown time format"); } } fputs(buf, f); return (int) strlen(buf); }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_DEPTH, ARG_CPU_TYPE }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "delay", required_argument, NULL, 'd' }, { "iterations", required_argument, NULL, 'n' }, { "batch", no_argument, NULL, 'b' }, { "depth", required_argument, NULL, ARG_DEPTH }, { "cpu", optional_argument, NULL, ARG_CPU_TYPE}, {} }; int c; int r; assert(argc >= 1); assert(argv); while ((c = getopt_long(argc, argv, "hptcmin:bd:", options, NULL)) >= 0) switch (c) { case 'h': help(); return 0; case ARG_VERSION: puts(PACKAGE_STRING); puts(SYSTEMD_FEATURES); return 0; case ARG_CPU_TYPE: if (optarg) { if (strcmp(optarg, "time") == 0) arg_cpu_type = CPU_TIME; else if (strcmp(optarg, "percentage") == 0) arg_cpu_type = CPU_PERCENT; else return -EINVAL; } break; case ARG_DEPTH: r = safe_atou(optarg, &arg_depth); if (r < 0) { log_error("Failed to parse depth parameter."); return -EINVAL; } break; case 'd': r = parse_sec(optarg, &arg_delay); if (r < 0 || arg_delay <= 0) { log_error("Failed to parse delay parameter."); return -EINVAL; } break; case 'n': r = safe_atou(optarg, &arg_iterations); if (r < 0) { log_error("Failed to parse iterations parameter."); return -EINVAL; } break; case 'b': arg_batch = true; break; case 'p': arg_order = ORDER_PATH; break; case 't': arg_order = ORDER_TASKS; break; case 'c': arg_order = ORDER_CPU; break; case 'm': arg_order = ORDER_MEMORY; break; case 'i': arg_order = ORDER_IO; break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } if (optind < argc) { log_error("Too many arguments."); return -EINVAL; } return 1; }