#include <stdbool.h>
#include <unistd.h>
#include <getopt.h>
+#include <locale.h>
#include <string.h>
#include <sys/timex.h>
+#include <sys/utsname.h>
#include "dbus-common.h"
#include "util.h"
#include "strv.h"
#include "sd-id128.h"
#include "virt.h"
+#include "fileio.h"
static enum transport {
TRANSPORT_NORMAL,
TRANSPORT_POLKIT
} arg_transport = TRANSPORT_NORMAL;
static bool arg_ask_password = true;
-static const char *arg_host = NULL;
+static char *arg_host = NULL;
+static char *arg_user = NULL;
static bool arg_set_transient = false;
static bool arg_set_pretty = false;
static bool arg_set_static = false;
const char *static_hostname;
const char *pretty_hostname;
const char *icon_name;
+ const char *chassis;
} StatusInfo;
static void print_status_info(StatusInfo *i) {
sd_id128_t mid, bid;
int r;
- const char *id;
+ const char *id = NULL;
+ _cleanup_free_ char *pretty_name = NULL, *cpe_name = NULL;
+ struct utsname u;
assert(i);
printf(" Static hostname: %s\n",
strna(i->static_hostname));
- if (!streq_ptr(i->hostname, i->static_hostname))
+ if (!isempty(i->pretty_hostname) &&
+ !streq_ptr(i->pretty_hostname, i->static_hostname))
+ printf(" Pretty hostname: %s\n",
+ strna(i->pretty_hostname));
+
+ if (!isempty(i->hostname) &&
+ !streq_ptr(i->hostname, i->static_hostname))
printf("Transient hostname: %s\n",
strna(i->hostname));
- printf(" Pretty hostname: %s\n"
- " Icon name: %s\n",
- strna(i->pretty_hostname),
- strna(i->icon_name));
+ printf(" Icon name: %s\n"
+ " Chassis: %s\n",
+ strna(i->icon_name),
+ strna(i->chassis));
r = sd_id128_get_machine(&mid);
if (r >= 0)
if (r >= 0)
printf(" Boot ID: " SD_ID128_FORMAT_STR "\n", SD_ID128_FORMAT_VAL(bid));
- if (detect_virtualization(&id) >= 0)
+ if (detect_virtualization(&id) > 0)
printf(" Virtualization: %s\n", id);
+
+ r = parse_env_file("/etc/os-release", NEWLINE,
+ "PRETTY_NAME", &pretty_name,
+ "CPE_NAME", &cpe_name,
+ NULL);
+
+ if (!isempty(pretty_name))
+ printf(" Operating System: %s\n", pretty_name);
+
+ if (!isempty(cpe_name))
+ printf(" CPE OS Name: %s\n", cpe_name);
+
+ assert_se(uname(&u) >= 0);
+ printf(" Kernel: %s %s\n"
+ " Architecture: %s\n", u.sysname, u.release, u.machine);
+
}
static int status_property(const char *name, DBusMessageIter *iter, StatusInfo *i) {
i->pretty_hostname = s;
if (streq(name, "IconName"))
i->icon_name = s;
+ if (streq(name, "Chassis"))
+ i->chassis = s;
}
break;
}
const char *interface = "";
int r;
DBusMessageIter iter, sub, sub2, sub3;
- StatusInfo info;
+ StatusInfo info = {};
assert(args);
return -EIO;
}
- zero(info);
dbus_message_iter_recurse(&iter, &sub);
while (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_INVALID) {
return 0;
}
-static char* hostname_simplify(char *s) {
- char *p, *d;
-
- for (p = s, d = s; *p; p++) {
- if ((*p >= 'a' && *p <= 'z') ||
- (*p >= '0' && *p <= '9') ||
- *p == '-' || *p == '_')
- *(d++) = *p;
- else if (*p >= 'A' && *p <= 'Z')
- *(d++) = *p - 'A' + 'a';
- else if (*p == ' ')
- *(d++) = '-';
- }
-
- *d = 0;
-
- strshorten(s, HOST_NAME_MAX);
- return s;
-}
-
static int set_hostname(DBusConnection *bus, char **args, unsigned n) {
_cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
- dbus_bool_t interactive = true;
+ dbus_bool_t interactive = arg_ask_password;
_cleanup_free_ char *h = NULL;
const char *hostname = args[1];
int r;
polkit_agent_open_if_enabled();
if (arg_set_pretty) {
+ const char *p;
+
+ /* If the passed hostname is already valid, then
+ * assume the user doesn't know anything about pretty
+ * hostnames, so let's unset the pretty hostname, and
+ * just set the passed hostname as static/dynamic
+ * hostname. */
+
+ h = strdup(hostname);
+ if (!h)
+ return log_oom();
+
+ hostname_cleanup(h, true);
+
+ if (arg_set_static && streq(h, hostname))
+ p = "";
+ else {
+ p = hostname;
+ hostname = h;
+ }
+
r = bus_method_call_with_reply(
bus,
"org.freedesktop.hostname1",
"SetPrettyHostname",
&reply,
NULL,
- DBUS_TYPE_STRING, &hostname,
+ DBUS_TYPE_STRING, &p,
DBUS_TYPE_BOOLEAN, &interactive,
DBUS_TYPE_INVALID);
if (r < 0)
return r;
- h = strdup(hostname);
- if (!h)
- return log_oom();
-
- hostname = hostname_simplify(h);
+ dbus_message_unref(reply);
+ reply = NULL;
}
if (arg_set_static) {
if (r < 0)
return r;
+
+ dbus_message_unref(reply);
+ reply = NULL;
}
if (arg_set_transient) {
static int set_icon_name(DBusConnection *bus, char **args, unsigned n) {
_cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
- dbus_bool_t interactive = true;
+ dbus_bool_t interactive = arg_ask_password;
assert(args);
assert(n == 2);
DBUS_TYPE_INVALID);
}
+static int set_chassis(DBusConnection *bus, char **args, unsigned n) {
+ _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+ dbus_bool_t interactive = arg_ask_password;
+
+ assert(args);
+ assert(n == 2);
+
+ polkit_agent_open_if_enabled();
+
+ return bus_method_call_with_reply(
+ bus,
+ "org.freedesktop.hostname1",
+ "/org/freedesktop/hostname1",
+ "org.freedesktop.hostname1",
+ "SetChassis",
+ &reply,
+ NULL,
+ DBUS_TYPE_STRING, &args[1],
+ DBUS_TYPE_BOOLEAN, &interactive,
+ DBUS_TYPE_INVALID);
+}
+
static int help(void) {
printf("%s [OPTIONS...] COMMAND ...\n\n"
" --transient Only set transient hostname\n"
" --static Only set static hostname\n"
" --pretty Only set pretty hostname\n"
+ " -P --privileged Acquire privileges before execution\n"
" --no-ask-password Do not prompt for password\n"
" -H --host=[USER@]HOST Operate on remote host\n\n"
"Commands:\n"
" status Show current hostname settings\n"
" set-hostname NAME Set system hostname\n"
- " set-icon-name NAME Set icon name for host\n",
+ " set-icon-name NAME Set icon name for host\n"
+ " set-chassis NAME Set chassis type for host\n",
program_invocation_short_name);
return 0;
case ARG_VERSION:
puts(PACKAGE_STRING);
- puts(DISTRIBUTION);
puts(SYSTEMD_FEATURES);
return 0;
case 'H':
arg_transport = TRANSPORT_SSH;
- arg_host = optarg;
+ parse_user_at_host(optarg, &arg_user, &arg_host);
break;
case ARG_SET_TRANSIENT:
arg_set_static = true;
break;
+ case ARG_NO_ASK_PASSWORD:
+ arg_ask_password = false;
+ break;
+
case '?':
return -EINVAL;
const int argc;
int (* const dispatch)(DBusConnection *bus, char **args, unsigned n);
} verbs[] = {
- { "status", LESS, 1, show_status },
- { "set-hostname", LESS, 2, set_hostname },
- { "set-icon-name", EQUAL, 2, set_icon_name },
+ { "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 },
};
int left;
dbus_error_init(&error);
+ setlocale(LC_ALL, "");
log_parse_environment();
log_open();