gboolean __scan_usb_sysfs(void) { GDir *sysfs; gchar *filename; const gchar *sysfs_path = "/sys/class/usb_endpoint"; gint usb_device_number = 0; if (!(sysfs = g_dir_open(sysfs_path, 0, NULL))) { return FALSE; } if (usb_list) { moreinfo_del_with_prefix("DEV:USB"); g_free(usb_list); } usb_list = g_strdup("[USB Devices]\n"); while ((filename = (gchar *) g_dir_read_name(sysfs))) { gchar *endpoint = g_build_filename(sysfs_path, filename, "device", NULL); gchar *temp; temp = g_build_filename(endpoint, "idVendor", NULL); if (g_file_test(temp, G_FILE_TEST_EXISTS)) { __scan_usb_sysfs_add_device(endpoint, ++usb_device_number); } g_free(temp); g_free(endpoint); } g_dir_close(sysfs); return usb_device_number > 0; }
gboolean __scan_usb_lsusb(void) { static gchar *lsusb_path = NULL; int usb_device_number = 0; FILE *lsusb; FILE *temp_lsusb; char buffer[512], *temp; if (!lsusb_path) { if (!(lsusb_path = find_program("lsusb"))) { DEBUG("lsusb not found"); return FALSE; } } temp = g_strdup_printf("%s -v | tr '[]' '()'", lsusb_path); if (!(lsusb = popen(temp, "r"))) { DEBUG("cannot run %s", lsusb_path); g_free(temp); return FALSE; } temp_lsusb = tmpfile(); if (!temp_lsusb) { DEBUG("cannot create temporary file for lsusb"); return FALSE; } while (fgets(buffer, sizeof(buffer), lsusb)) { fputs(buffer, temp_lsusb); } pclose(lsusb); // rewind file so we can read from it fseek(temp_lsusb, 0, SEEK_SET); g_free(temp); if (usb_list) { moreinfo_del_with_prefix("DEV:USB"); g_free(usb_list); } usb_list = g_strdup("[USB Devices]\n"); while (fgets(buffer, sizeof(buffer), temp_lsusb)) { if (g_str_has_prefix(buffer, "Bus ")) { __scan_usb_lsusb_add_device(buffer, sizeof(buffer), temp_lsusb, ++usb_device_number); } } fclose(temp_lsusb); return usb_device_number > 0; }
void hi_module_init(void) { if (!g_file_test("/usr/share/misc/pci.ids", G_FILE_TEST_EXISTS)) { static SyncEntry se = { .fancy_name = N_("Update PCI ID listing"), .name = "GetPCIIds", .save_to = "pci.ids", .get_data = NULL }; sync_manager_add_entry(&se); } #if defined(ARCH_x86) || defined(ARCH_x86_64) { static SyncEntry se = { .fancy_name = N_("Update CPU feature database"), .name = "RecvCPUFlags", .save_to = "cpuflags.conf", .get_data = NULL }; sync_manager_add_entry(&se); } #endif /* defined(ARCH_x86) */ init_memory_labels(); init_cups(); sensors_init(); } void hi_module_deinit(void) { moreinfo_del_with_prefix("DEV"); sensors_shutdown(); g_hash_table_destroy(memlabels); g_module_close(cups); } ModuleAbout *hi_module_get_about(void) { static ModuleAbout ma[] = { { .author = "Leandro A. F. Pereira", .description = N_("Gathers information about hardware devices"), .version = VERSION, .license = "GNU GPL version 2"} }; return ma; }
void hi_module_deinit(void) { if (computer->os) { g_free(computer->os->kernel); g_free(computer->os->libc); g_free(computer->os->distrocode); g_free(computer->os->distro); g_free(computer->os->hostname); g_free(computer->os->language); g_free(computer->os->homedir); g_free(computer->os->kernel_version); g_free(computer->os->languages); g_free(computer->os->desktop); g_free(computer->os->username); g_free(computer->os->boots); g_free(computer->os); } if (computer->display) { g_free(computer->display->ogl_vendor); g_free(computer->display->ogl_renderer); g_free(computer->display->ogl_version); g_free(computer->display->display_name); g_free(computer->display->vendor); g_free(computer->display->version); g_free(computer->display->extensions); g_free(computer->display->monitors); g_free(computer->display); } if (computer->alsa) { g_slist_free(computer->alsa->cards); g_free(computer->alsa); } g_free(computer->date_time); g_free(computer); moreinfo_del_with_prefix("COMP"); }
void scan_printers_do(void) { int num_dests, i, j; CUPSDest *dests; gchar *prn_id, *prn_moreinfo; g_free(printer_list); g_free(printer_icons); if (!cups_init) { init_cups(); printer_icons = g_strdup(""); printer_list = g_strdup(_("[Printers]\n" "No suitable CUPS library found=")); return; } /* remove old devices from global device table */ moreinfo_del_with_prefix("DEV:PRN"); num_dests = cups_dests_get(&dests); if (num_dests > 0) { printer_list = g_strdup_printf(_("[Printers (CUPS)]\n")); printer_icons = g_strdup(""); for (i = 0; i < num_dests; i++) { GHashTable *options; options = g_hash_table_new(g_str_hash, g_str_equal); for (j = 0; j < dests[i].num_options; j++) { g_hash_table_insert(options, g_strdup(dests[i].options[j].name), g_strdup(dests[i].options[j].value)); } prn_id = g_strdup_printf("PRN%d", i); printer_list = h_strdup_cprintf("\n$%s$%s=%s\n", printer_list, prn_id, dests[i].name, dests[i].is_default ? "<i>Default</i>" : ""); printer_icons = h_strdup_cprintf("\nIcon$%s$%s=printer.png", printer_icons, prn_id, dests[i].name); prn_moreinfo = g_strdup(""); for (j = 0; j < G_N_ELEMENTS(cups_fields); j++) { if (!cups_fields[j].name) { prn_moreinfo = h_strdup_cprintf("[%s]\n", prn_moreinfo, cups_fields[j].key); } else { gchar *temp; temp = g_hash_table_lookup(options, cups_fields[j].key); if (cups_fields[j].callback) { temp = cups_fields[j].callback(temp); } else { if (temp) { /* FIXME Do proper escaping */ temp = g_strdup(strreplacechr(temp, "&=", ' ')); } else { temp = g_strdup(_("Unknown")); } } prn_moreinfo = h_strdup_cprintf("%s=%s\n", prn_moreinfo, cups_fields[j].name, temp); g_free(temp); } } moreinfo_add_with_prefix("DEV", prn_id, prn_moreinfo); g_free(prn_id); g_hash_table_destroy(options); } cups_dests_free(num_dests, dests); } else { printer_list = g_strdup(_("[Printers]\n" "No printers found=\n")); } }
void __scan_ide_devices(void) { FILE *proc_ide; gchar *device, iface, *model, *media, *pgeometry = NULL, *lgeometry = NULL; gint n = 0, i = 0, cache, nn = 0; gchar *capab = NULL, *speed = NULL, *driver = NULL, *ide_storage_list; /* remove old devices from global device table */ moreinfo_del_with_prefix("DEV:IDE"); ide_storage_list = g_strdup(_("\n[IDE Disks]\n")); iface = 'a'; for (i = 0; i <= 16; i++) { device = g_strdup_printf("/proc/ide/hd%c/model", iface); if (g_file_test(device, G_FILE_TEST_EXISTS)) { gchar buf[128]; cache = 0; proc_ide = fopen(device, "r"); if (!proc_ide) continue; (void) fgets(buf, 128, proc_ide); fclose(proc_ide); buf[strlen(buf) - 1] = 0; model = g_strdup(buf); g_free(device); device = g_strdup_printf("/proc/ide/hd%c/media", iface); proc_ide = fopen(device, "r"); if (!proc_ide) { free(model); continue; } (void) fgets(buf, 128, proc_ide); fclose(proc_ide); buf[strlen(buf) - 1] = 0; media = g_strdup(buf); if (g_str_equal(media, "cdrom")) { /* obtain cd-rom drive information from cdrecord */ GTimer *timer; gchar *tmp = g_strdup_printf("cdrecord dev=/dev/hd%c -prcap 2>/dev/stdout", iface); FILE *prcap; if ((prcap = popen(tmp, "r"))) { /* we need a timeout so cdrecord does not try to get information on cd drives with inserted media, which is not possible currently. half second should be enough. */ timer = g_timer_new(); g_timer_start(timer); while (fgets(buf, 128, prcap) && g_timer_elapsed(timer, NULL) < 0.5) { if (g_str_has_prefix(buf, " Does")) { if (g_str_has_suffix(buf, "media\n") && !strstr(buf, "speed")) { gchar *media_type = g_strstrip(strstr(buf, "Does ")); gchar **ttmp = g_strsplit(media_type, " ", 0); capab = h_strdup_cprintf("\nCan %s#%d=%s\n", capab, ttmp[1], ++nn, ttmp[2]); g_strfreev(ttmp); } else if (strstr(buf, "Buffer-Underrun-Free")) { capab = h_strdup_cprintf ("\nSupports BurnProof=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes"); } else if (strstr(buf, "multi-session")) { capab = h_strdup_cprintf ("\nCan read multi-session CDs=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes"); } else if (strstr(buf, "audio CDs")) { capab = h_strdup_cprintf ("\nCan play audio CDs=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes"); } else if (strstr(buf, "PREVENT/ALLOW")) { capab = h_strdup_cprintf ("\nCan lock media=%s\n", capab, strstr(buf, "Does not") ? "No" : "Yes"); } } else if ((strstr(buf, "read") || strstr(buf, "write")) && strstr(buf, "kB/s")) { speed = g_strconcat(speed ? speed : "", strreplacechr(g_strstrip(buf), ":", '='), "\n", NULL); } else if (strstr(buf, "Device seems to be")) { driver = g_strdup_printf(_("Driver=%s\n"), strchr(buf, ':') + 1); } } pclose(prcap); g_timer_destroy(timer); } g_free(tmp); } g_free(device); device = g_strdup_printf("/proc/ide/hd%c/cache", iface); if (g_file_test(device, G_FILE_TEST_EXISTS)) { proc_ide = fopen(device, "r"); if (proc_ide) { (void) fscanf(proc_ide, "%d", &cache); fclose(proc_ide); } else { cache = 0; } } g_free(device); device = g_strdup_printf("/proc/ide/hd%c/geometry", iface); if (g_file_test(device, G_FILE_TEST_EXISTS)) { gchar *tmp; proc_ide = fopen(device, "r"); if (proc_ide) { (void) fgets(buf, 64, proc_ide); for (tmp = buf; *tmp; tmp++) { if (*tmp >= '0' && *tmp <= '9') break; } pgeometry = g_strdup(g_strstrip(tmp)); (void) fgets(buf, 64, proc_ide); for (tmp = buf; *tmp; tmp++) { if (*tmp >= '0' && *tmp <= '9') break; } lgeometry = g_strdup(g_strstrip(tmp)); fclose(proc_ide); } else { pgeometry = g_strdup("Unknown"); lgeometry = g_strdup("Unknown"); } } g_free(device); n++; gchar *devid = g_strdup_printf("IDE%d", n); ide_storage_list = h_strdup_cprintf("$%s$%s=\n", ide_storage_list, devid, model); storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, model, g_str_equal(media, "cdrom") ? "cdrom" : "hdd"); gchar *strhash = g_strdup_printf(_("[Device Information]\n" "Model=%s\n"), model); const gchar *url = vendor_get_url(model); if (url) { strhash = h_strdup_cprintf(_("Vendor=%s (%s)\n"), strhash, vendor_get_name(model), url); } else { strhash = h_strdup_cprintf(_("Vendor=%s\n"), strhash, vendor_get_name(model)); } strhash = h_strdup_cprintf(_("Device Name=hd%c\n" "Media=%s\n" "Cache=%dkb\n"), strhash, iface, media, cache); if (driver) { strhash = h_strdup_cprintf("%s\n", strhash, driver); g_free(driver); driver = NULL; } if (pgeometry && lgeometry) { strhash = h_strdup_cprintf(_("[Geometry]\n" "Physical=%s\n" "Logical=%s\n"), strhash, pgeometry, lgeometry); g_free(pgeometry); pgeometry = NULL; g_free(lgeometry); lgeometry = NULL; } if (capab) { strhash = h_strdup_cprintf(_("[Capabilities]\n%s"), strhash, capab); g_free(capab); capab = NULL; } if (speed) { strhash = h_strdup_cprintf(_("[Speeds]\n%s"), strhash, speed); g_free(speed); speed = NULL; } moreinfo_add_with_prefix("DEV", devid, strhash); g_free(devid); g_free(model); } else { g_free(device); } iface++; } if (n) { storage_list = h_strconcat(storage_list, ide_storage_list, NULL); g_free(ide_storage_list); } }
gboolean __scan_udisks2_devices(void) { GSList *node, *drives; udiskd *disk; gchar *udisks2_storage_list = NULL, *features = NULL, *moreinfo = NULL; gchar *devid, *label; const gchar *url, *vendor_str, *icon; int n = 0, i; static struct { char *media_prefix; char *icon; } media2icon[] = { { "thumb", "usbfldisk"}, { "flash", "usbfldisk"}, { "floppy", "media-floppy"}, { "optical", "cdrom"}, { NULL, NULL} }; moreinfo_del_with_prefix("DEV:UDISKS"); udisks2_storage_list = g_strdup(_("\n[UDisks2]\n")); drives = get_udisks2_all_drives_info(); for (node = drives; node != NULL; node = node->next) { disk = (udiskd *)node->data; devid = g_strdup_printf("UDISKS%d", n++); if (disk->vendor && strlen(disk->vendor) > 0) { label = g_strdup_printf("%s %s", disk->vendor, disk->model); vendor_str = disk->vendor; } else{ label = g_strdup(disk->model); vendor_str = disk->model; } icon = NULL; if (disk->media_compatibility){ for (i = 0; media2icon[i].media_prefix != NULL; i++) { if (g_str_has_prefix(disk->media_compatibility, media2icon[i].media_prefix)) { icon = media2icon[i].icon; break; } } } if (icon == NULL && disk->ejectable && g_strcmp0(disk->connection_bus, "usb") == 0) { icon = "usbfldisk"; } if (icon == NULL){ icon = "hdd"; } url = vendor_get_url(vendor_str); udisks2_storage_list = h_strdup_cprintf("$%s$%s=\n", udisks2_storage_list, devid, label); storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, label, icon); features = h_strdup_cprintf("%s", features, disk->removable ? _("Removable"): _("Fixed")); if (disk->ejectable) { features = h_strdup_cprintf(", %s", features, _("Ejectable")); } if (disk->smart_enabled) { features = h_strdup_cprintf(", %s", features, _("Smart monitoring")); } moreinfo = g_strdup_printf(_("[Drive Information]\n" "Model=%s\n"), label); if (url) { moreinfo = h_strdup_cprintf(_("Vendor=%s (%s)\n"), moreinfo, vendor_get_name(vendor_str), url); } else { moreinfo = h_strdup_cprintf(_("Vendor=%s\n"), moreinfo, vendor_get_name(vendor_str)); } moreinfo = h_strdup_cprintf(_("Revision=%s\n" "Block Device=%s\n" "Serial=%s\n" "Size=%s\n" "Features=%s\n"), moreinfo, disk->revision, disk->block_dev, disk->serial, size_human_readable((gfloat) disk->size), features); if (disk->rotation_rate > 0) { moreinfo = h_strdup_cprintf(_("Rotation Rate=%d\n"), moreinfo, disk->rotation_rate); } if (disk->media_compatibility || disk->media) { moreinfo = h_strdup_cprintf(_("Media=%s\n" "Media compatibility=%s\n"), moreinfo, disk->media ? disk->media : _("(None)"), disk->media_compatibility ? disk->media_compatibility : _("(Unknown)")); } if (disk->connection_bus && strlen(disk->connection_bus) > 0) { moreinfo = h_strdup_cprintf(_("Connection bus=%s\n"), moreinfo, disk->connection_bus); } if (disk->smart_enabled) { moreinfo = h_strdup_cprintf(_("[Smart monitoring]\n" "Status=%s\n" "Bad Sectors=%ld\n" "Power on time=%d days %d hours\n" "Temperature=%d°C\n"), moreinfo, disk->smart_failing ? _("Failing"): _("OK"), disk->smart_bad_sectors, disk->smart_poweron/(60*60*24), (disk->smart_poweron/60/60) % 24, disk->smart_temperature); } moreinfo_add_with_prefix("DEV", devid, moreinfo); g_free(devid); g_free(features); g_free(label); features = NULL; moreinfo = NULL; devid = NULL; udiskd_free(disk); } g_slist_free(drives); if (n) { storage_list = h_strconcat(storage_list, udisks2_storage_list, NULL); g_free(udisks2_storage_list); return TRUE; } g_free(udisks2_storage_list); return FALSE; }
/* SCSI support by Pascal F.Martin <*****@*****.**> */ void __scan_scsi_devices(void) { FILE *proc_scsi; gchar buffer[256], *buf; gint n = 0; gint scsi_controller = 0; gint scsi_channel = 0; gint scsi_id = 0 ; gint scsi_lun = 0; gchar *vendor = NULL, *revision = NULL, *model = NULL; gchar *scsi_storage_list; /* remove old devices from global device table */ moreinfo_del_with_prefix("DEV:SCSI"); scsi_storage_list = g_strdup(_("\n[SCSI Disks]\n")); int otype = 0; if (proc_scsi = fopen("/proc/scsi/scsi", "r")) { otype = 1; } else if (proc_scsi = popen("lsscsi -c", "r")) { otype = 2; } if (otype) { while (fgets(buffer, 256, proc_scsi)) { buf = g_strstrip(buffer); if (!strncmp(buf, "Host: scsi", 10)) { sscanf(buf, "Host: scsi%d Channel: %d Id: %d Lun: %d", &scsi_controller, &scsi_channel, &scsi_id, &scsi_lun); n++; } else if (!strncmp(buf, "Vendor: ", 8)) { buf[17] = '\0'; buf[41] = '\0'; buf[53] = '\0'; vendor = g_strdup(g_strstrip(buf + 8)); model = g_strdup_printf("%s %s", vendor, g_strstrip(buf + 24)); revision = g_strdup(g_strstrip(buf + 46)); } else if (!strncmp(buf, "Type: ", 8)) { char *p; gchar *type = NULL, *icon = NULL; if (!(p = strstr(buf, "ANSI SCSI revision"))) { p = strstr(buf, "ANSI SCSI revision"); } if (p != NULL) { while (*(--p) == ' '); *(++p) = 0; static struct { char *type; char *label; char *icon; } type2icon[] = { { "Direct-Access", "Disk", "hdd"}, { "Sequential-Access", "Tape", "tape"}, { "Printer", "Printer", "lpr"}, { "WORM", "CD-ROM", "cdrom"}, { "CD-ROM", "CD-ROM", "cdrom"}, { "Scanner", "Scanner", "scanner"}, { "Flash Disk", "USB Flash Disk", "usbfldisk" }, { NULL, "Generic", "scsi"} }; int i; if (model && strstr(model, "Flash Disk")) { type = "Flash Disk"; icon = "usbfldisk"; } else { for (i = 0; type2icon[i].type != NULL; i++) if (g_str_equal(buf + 8, type2icon[i].type)) break; type = type2icon[i].label; icon = type2icon[i].icon; } } gchar *devid = g_strdup_printf("SCSI%d", n); scsi_storage_list = h_strdup_cprintf("$%s$%s=\n", scsi_storage_list, devid, model); storage_icons = h_strdup_cprintf("Icon$%s$%s=%s.png\n", storage_icons, devid, model, icon); gchar *strhash = g_strdup_printf(_("[Device Information]\n" "Model=%s\n"), model); const gchar *url = vendor_get_url(model); if (url) { strhash = h_strdup_cprintf(_("Vendor=%s (%s)\n"), strhash, vendor_get_name(model), url); } else { strhash = h_strdup_cprintf(_("Vendor=%s\n"), strhash, vendor_get_name(model)); } strhash = h_strdup_cprintf(_("Type=%s\n" "Revision=%s\n" "[SCSI Controller]\n" "Controller=scsi%d\n" "Channel=%d\n" "ID=%d\n" "LUN=%d\n"), strhash, type, revision, scsi_controller, scsi_channel, scsi_id, scsi_lun); moreinfo_add_with_prefix("DEV", devid, strhash); g_free(devid); g_free(model); g_free(revision); g_free(vendor); scsi_controller = scsi_channel = scsi_id = scsi_lun = 0; } } if (otype == 1) fclose(proc_scsi); else if (otype == 2) pclose(proc_scsi); } if (n) { storage_list = h_strconcat(storage_list, scsi_storage_list, NULL); g_free(scsi_storage_list); } }
gboolean __scan_usb_procfs(void) { FILE *dev; gchar buffer[128]; gchar *tmp, *manuf = NULL, *product = NULL, *mxpwr; gint bus, level, port = 0, classid = 0, trash; gint vendor, prodid; gfloat ver, rev, speed; int n = 0; dev = fopen("/proc/bus/usb/devices", "r"); if (!dev) return 0; if (usb_list) { moreinfo_del_with_prefix("DEV:USB"); g_free(usb_list); } usb_list = g_strdup("[USB Devices]\n"); while (fgets(buffer, 128, dev)) { tmp = buffer; switch (*tmp) { case 'T': sscanf(tmp, "T: Bus=%d Lev=%d Prnt=%d Port=%d Cnt=%d Dev#=%d Spd=%f", &bus, &level, &trash, &port, &trash, &trash, &speed); break; case 'D': sscanf(tmp, "D: Ver=%f Cls=%x", &ver, &classid); break; case 'P': sscanf(tmp, "P: Vendor=%x ProdID=%x Rev=%f", &vendor, &prodid, &rev); break; case 'S': if (strstr(tmp, "Manufacturer=")) { manuf = g_strdup(strchr(tmp, '=') + 1); remove_linefeed(manuf); } else if (strstr(tmp, "Product=")) { product = g_strdup(strchr(tmp, '=') + 1); remove_linefeed(product); } break; case 'C': mxpwr = strstr(buffer, "MxPwr=") + 6; tmp = g_strdup_printf("USB%d", ++n); if (product && *product == '\0') { g_free(product); if (classid == 9) { product = g_strdup_printf("USB %.2f Hub", ver); } else { product = g_strdup_printf ("Unknown USB %.2f Device (class %d)", ver, classid); } } if (classid == 9) { /* hub */ usb_list = h_strdup_cprintf("[%s#%d]\n", usb_list, product, n); } else { /* everything else */ usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, product); const gchar *url = vendor_get_url(manuf); if (url) { gchar *tmp = g_strdup_printf("%s (%s)", vendor_get_name(manuf), url); g_free(manuf); manuf = tmp; } gchar *strhash = g_strdup_printf("[Device Information]\n" "Product=%s\n", product); if (manuf && strlen(manuf)) strhash = h_strdup_cprintf("Manufacturer=%s\n", strhash, manuf); strhash = h_strdup_cprintf("[Port #%d]\n" "Speed=%.2fMbit/s\n" "Max Current=%s\n" "[Misc]\n" "USB Version=%.2f\n" "Revision=%.2f\n" "Class=0x%x\n" "Vendor=0x%x\n" "Product ID=0x%x\n" "Bus=%d\n" "Level=%d\n", strhash, port, speed, mxpwr, ver, rev, classid, vendor, prodid, bus, level); moreinfo_add_with_prefix("DEV", tmp, strhash); g_free(tmp); } g_free(manuf); g_free(product); manuf = g_strdup(""); product = g_strdup(""); port = classid = 0; } } fclose(dev); return n > 0; }
void scan_filesystems(void) { FILE *mtab; gchar buf[1024]; struct statfs sfs; int count = 0; g_free(fs_list); fs_list = g_strdup(""); moreinfo_del_with_prefix("COMP:FS"); mtab = fopen("/etc/mtab", "r"); if (!mtab) return; while (fgets(buf, 1024, mtab)) { gfloat size, used, avail; gchar **tmp; tmp = g_strsplit(buf, " ", 0); if (!statfs(tmp[1], &sfs)) { gfloat use_ratio; size = (float) sfs.f_bsize * (float) sfs.f_blocks; avail = (float) sfs.f_bsize * (float) sfs.f_bavail; used = size - avail; if (size == 0.0f) { continue; } if (avail == 0.0f) { use_ratio = 100.0f; } else { use_ratio = 100.0f * (used / size); } gchar *strsize = size_human_readable(size), *stravail = size_human_readable(avail), *strused = size_human_readable(used); gchar *strhash; strreplacechr(tmp[0], "#", '_'); strhash = g_strdup_printf("[%s]\n" "Filesystem=%s\n" "Mounted As=%s\n" "Mount Point=%s\n" "Size=%s\n" "Used=%s\n" "Available=%s\n", tmp[0], tmp[2], strstr(tmp[3], "rw") ? "Read-Write" : "Read-Only", tmp[1], strsize, strused, stravail); gchar *key = g_strdup_printf("FS%d", ++count); moreinfo_add_with_prefix("COMP", key, strhash); g_free(key); fs_list = h_strdup_cprintf("$FS%d$%s=%.2f %% (%s of %s)|%s\n", fs_list, count, tmp[0], use_ratio, stravail, strsize, tmp[1]); g_free(strsize); g_free(stravail); g_free(strused); } g_strfreev(tmp); } fclose(mtab); }