X-Git-Url: https://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=blobdiff_plain;f=src%2Finterfaces%2Fhostnamed%2Fhostnamed.c;h=432c53b46c879c3854393e84c1aee1bb49638524;hp=7779870b5a46c27070477c1dd819e782ea6c0655;hb=bd24ff313da7148b53671091be49504f250fa782;hpb=a1bcc33cfc213eb21997f169ef433f186f483da0 diff --git a/src/interfaces/hostnamed/hostnamed.c b/src/interfaces/hostnamed/hostnamed.c index 7779870..432c53b 100644 --- a/src/interfaces/hostnamed/hostnamed.c +++ b/src/interfaces/hostnamed/hostnamed.c @@ -17,10 +17,15 @@ #include #include #include +#include #include #include -#include +#include +#include +#include + +#include #include #include @@ -76,6 +81,8 @@ guint bus_descriptor; gboolean dbus_interface_exported; /* reliable because of gdbus operational guarantees */ gchar *CHASSIS, *ICON; +gchar *OS_CPENAME; +gchar *KERN_NAME, *KERN_RELEASE, *KERN_VERS; /* TODO no specific vm or laptop icon in gnome * NOTE paravirtualization on xen is only available for linuxes right now @@ -83,7 +90,8 @@ gchar *CHASSIS, *ICON; * but we will worry about those later */ const struct SYSCTL_LOOKUP_TABLE chassis_indicator_table[] = { - { "QEMU Virtual CPU", "container", "drive-optical", FALSE, FALSE }, /* could be QEMU running in userspace or as part of KVM */ + { "QEMU Virtual CPU", "container", NULL, FALSE, FALSE }, /* could be QEMU running in userspace or as part of KVM */ + { "KVM", "vm", "drive-multidisk", FALSE, FALSE }, { "SmartDC HVM", "vm", "drive-multidisk", TRUE, TRUE }, /* oracle solaris kvm */ { "VirtualBox", "container", "drive-optical", TRUE, TRUE }, { "VMware, Inc.", "container", "drive-optical", TRUE, TRUE }, @@ -91,12 +99,12 @@ const struct SYSCTL_LOOKUP_TABLE chassis_indicator_table[] = { "Parallels", "container", "drive-optical", TRUE, TRUE } /* need verification */ }; -/*const gchar* vmstring_list[] = { - "QEMU Virtual CPU", - "SmartDC HVM", - "KVM", - "VirtualBox" -};*/ +/* archs to check against when determining if machine is server */ +const gchar *server_archs[] = { + "hppa", + "sparc", + "sparc64" +}; /* --- begin method/property/dbus signal code --- */ @@ -210,44 +218,58 @@ our_get_pretty_hostname() { const gchar * our_get_chassis() { - return "asdf"; + if(CHASSIS) + return CHASSIS; + return "desktop"; } const gchar * our_get_icon_name() { - return "TODO"; + if(ICON) + return ICON; + + return ""; } const gchar * our_get_kernel_name() { - return "TODO"; + if(KERN_NAME) + return KERN_NAME; + + return ""; } const gchar * our_get_kernel_version() { - return "TODO"; + if(KERN_VERS) + return KERN_VERS; + + return ""; } const gchar * our_get_kernel_release() { - return "TODO"; + if(KERN_RELEASE) + return KERN_RELEASE; + + return ""; } const gchar * our_get_os_cpename() { - return "TODO"; + return "ONEDAY"; } const gchar * our_get_os_pretty_name() { - return "TODO"; + return "OpenBSD"; } /* --- end method/property/dbus signal code, begin bus/name handlers --- */ @@ -354,14 +376,20 @@ void set_signal_handlers() { } int main() { - + + hostnamed_freeable = g_ptr_array_new(); + + /* TODO: check for valid, writable config at init. if no, complain to `make install` */ + + CHASSIS = ICON = OS_CPENAME = 0; + KERN_NAME = KERN_RELEASE = KERN_VERS = 0; + set_signal_handlers(); - if(!build_chassis_table() || !determine_chassis_and_icon()) + if(!determine_chassis_and_icon() || !set_uname_properties()) return 1; hostnamed_loop = g_main_loop_new(NULL, TRUE); - hostnamed_freeable = g_ptr_array_new(); bus_descriptor = g_bus_own_name(G_BUS_TYPE_SYSTEM, "org.freedesktop.hostname1", @@ -385,16 +413,51 @@ int main() { return 0; } -static gboolean build_chassis_table() { - return TRUE; +gboolean set_uname_properties() { + + struct utsname un; + + if(-1 == uname(&un)) + return FALSE; + + KERN_NAME = (gchar*)g_malloc0(sizeof(un.sysname)); + g_ptr_array_add(hostnamed_freeable, KERN_NAME); + g_strlcpy(KERN_NAME, un.sysname, sizeof(un.sysname)); + + KERN_RELEASE = (gchar*)g_malloc0(sizeof(un.release)); + g_ptr_array_add(hostnamed_freeable, KERN_RELEASE); + g_strlcpy(KERN_RELEASE, un.release, sizeof(un.release)); + + KERN_VERS = (gchar*)g_malloc0(sizeof(un.version)); + g_ptr_array_add(hostnamed_freeable, KERN_VERS); + g_strlcpy(KERN_VERS, un.version, sizeof(un.version)); + + return TRUE; } gboolean determine_chassis_and_icon() { - char *hwproduct, *hwmodel, *hwvendor; - size_t hwproduct_size, hwmodel_size, hwvendor_size; - int hwproduct_name[2], hwmodel_name[2], hwvendor_name[2]; + const size_t bufsize = 4096; + + char *hwproduct, *hwmodel, *hwvendor, *hwmachine; + size_t hwproduct_size, hwmodel_size, hwvendor_size, hwmachine_size; + int hwproduct_name[2], hwmodel_name[2], hwvendor_name[2], hwmachine_name[2]; unsigned int i; + gboolean UNSURE_CHASSIS_FLAG, UNSURE_ICON_FLAG; + + hwproduct_size = hwmodel_size = hwvendor_size = hwmachine_size = bufsize; + UNSURE_CHASSIS_FLAG = UNSURE_ICON_FLAG = FALSE; + i = 0; + + hwproduct = (char*)g_malloc0(4096); + hwmodel = (char*)g_malloc0(4096); + hwvendor = (char*)g_malloc0(4096); + hwmachine = (char*)g_malloc0(4096); + + g_ptr_array_add(hostnamed_freeable, hwproduct); + g_ptr_array_add(hostnamed_freeable, hwmodel); + g_ptr_array_add(hostnamed_freeable, hwvendor); + g_ptr_array_add(hostnamed_freeable, hwmachine); hwproduct_name[0] = CTL_HW; hwproduct_name[1] = HW_PRODUCT; @@ -405,6 +468,9 @@ gboolean determine_chassis_and_icon() { hwvendor_name[0] = CTL_HW; hwvendor_name[1] = HW_VENDOR; + hwmachine_name[0] = CTL_HW; + hwmachine_name[1] = HW_MACHINE; + /* pass NULL buffer to check size first, then pass hw to be filled according to freshly-set hw_size */ if(-1 == sysctl(hwproduct_name, 2, NULL, &hwproduct_size, NULL, 0) || -1 == sysctl(hwproduct_name, 2, hwproduct, &hwproduct_size, NULL, 0)) return FALSE; @@ -415,62 +481,117 @@ gboolean determine_chassis_and_icon() { if(-1 == sysctl(hwvendor_name, 2, NULL, &hwvendor_size, NULL, 0) || -1 == sysctl(hwvendor_name, 2, hwvendor, &hwvendor_size, NULL, 0)) return FALSE; + if(-1 == sysctl(hwmachine_name, 2, NULL, &hwmachine_size, NULL, 0) || -1 == sysctl(hwmachine_name, 2, hwmachine, &hwmachine_size, NULL, 0)) + return FALSE; + /* TODO: test for laptop, if not, dmidecode for desktop vs. server * probably move this code to vm test func and set a global after running it early, once */ - for(; i < G_N_ELEMENTS(chassis_indicator_table); i++) - - /* if(strcasestr(sysctl_string, vmstring_list[i])) - return (CHASSIS = ) ? TRUE : FALSE; */ + for(; i < G_N_ELEMENTS(chassis_indicator_table); i++) { + if(strcasestr(hwproduct, chassis_indicator_table[i].match_string) + || strcasestr(hwmodel, chassis_indicator_table[i].match_string) + || strcasestr(hwvendor, chassis_indicator_table[i].match_string)) { + + if(!UNSURE_CHASSIS_FLAG && chassis_indicator_table[i].chassis) { + + UNSURE_CHASSIS_FLAG = chassis_indicator_table[i].chassis_precedence; + CHASSIS = chassis_indicator_table[i].chassis; + } + + if(!UNSURE_ICON_FLAG && chassis_indicator_table[i].icon) { + + UNSURE_ICON_FLAG = chassis_indicator_table[i].icon_precedence; + ICON = chassis_indicator_table[i].icon; + } + } + } - return FALSE; + if(up_native_is_laptop()) { - return TRUE; /* temp */ -} + if(!CHASSIS) + CHASSIS = "laptop"; + if(!ICON) + ICON = "input-touchpad"; /* TODO pull an icon package that actually has the icons we're looking for */ + + } else if(is_server(hwmachine)) { -/* TODO figure out DMI variables on obsd */ -/*static gchar *guess_icon_name() { + if(!CHASSIS) + CHASSIS = "server"; + if(!ICON) + ICON = "uninterruptible-power-supply"; - gchar *filebuf = NULL; - gchar *ret = NULL; + } else if(!CHASSIS || !ICON) { - #if defined(__i386__) || defined(__x86_64__) + if(!CHASSIS) + CHASSIS = "desktop"; + if(!ICON) + ICON = "computer"; + } + + return (CHASSIS && ICON); +} + +gboolean is_server(gchar *arch) { - Taken with a few minor changes from systemd's hostnamed.c, - copyright 2011 Lennart Poettering. - - See the SMBIOS Specification 2.7.1 section 7.4.1 for - details about the values listed here: - - http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.7.1.pdf - - - if (g_file_get_contents ("/sys/class/dmi/id/chassis_type", &filebuf, NULL, NULL)) { - switch (g_ascii_strtoull (filebuf, NULL, 10)) { - case 0x3: - case 0x4: - case 0x5: - case 0x6: - case 0x7: - ret = g_strdup ("computer-desktop"); - goto out; - case 0x9: - case 0xA: - case 0xE: - ret = g_strdup ("computer-laptop"); - goto out; - case 0x11: - case 0x17: - case 0x1C: - case 0x1D: - ret = g_strdup ("computer-server"); - goto out; + unsigned int i; + + for(; i < G_N_ELEMENTS(server_archs); i++) + if(strcasestr(arch, server_archs[i])) + return TRUE; + + return FALSE; +} + +gboolean up_native_is_laptop() { + + struct apm_power_info bstate; + struct sensordev acpiac; + + if (up_native_get_sensordev("acpiac0", &acpiac)) + return TRUE; + + if (-1 == ioctl(up_apm_get_fd(), APM_IOC_GETPOWER, &bstate)) + g_error("ioctl on apm fd failed : %s", g_strerror(errno)); + + return bstate.ac_state != APM_AC_UNKNOWN; +} + +int up_apm_get_fd() { + + static int apm_fd = 0; + + if(apm_fd == 0) { + + g_debug("apm_fd is not initialized yet, opening"); + + /* open /dev/apm */ + if((apm_fd = open("/dev/apm", O_RDONLY)) == -1) { + if(errno != ENXIO && errno != ENOENT) + g_error("cannot open device file"); } } - #endif - ret = g_strdup ("computer"); - out: - g_free (filebuf); - return ret; -}*/ + return apm_fd; +} + +gboolean up_native_get_sensordev(const char * id, struct sensordev * snsrdev) { + + int devn; + size_t sdlen = sizeof(struct sensordev); + int mib[] = {CTL_HW, HW_SENSORS, 0, 0 ,0}; + + for (devn = 0 ; ; devn++) { + mib[2] = devn; + if(sysctl(mib, 3, snsrdev, &sdlen, NULL, 0) == -1) { + if(errno == ENXIO) + continue; + if(errno == ENOENT) + break; + } + + if (!strcmp(snsrdev->xname, id)) + return TRUE; + } + + return FALSE; +}