X-Git-Url: https://git.xinqibao.xyz/slstatus.git/blobdiff_plain/fb440d8f622142c11e98e4799b7adceb33cd23b0..4d6761e0c70942d5cab055bf12ebc6ac920d39b5:/slstatus.c?ds=inline

diff --git a/slstatus.c b/slstatus.c
index ba7f95a..f39a2dc 100644
--- a/slstatus.c
+++ b/slstatus.c
@@ -6,6 +6,7 @@
 #include <ifaddrs.h>
 #include <limits.h>
 #include <linux/wireless.h>
+#include <locale.h>
 #include <netdb.h>
 #include <pwd.h>
 #include <signal.h>
@@ -56,6 +57,10 @@ static char *ram_perc(void);
 static char *ram_used(void);
 static char *ram_total(void);
 static char *run_command(const char *cmd);
+static char *swap_free(void);
+static char *swap_perc(void);
+static char *swap_used(void);
+static char *swap_total(void);
 static char *temp(const char *file);
 static char *uid(void);
 static char *uptime(void);
@@ -269,16 +274,11 @@ static char *
 hostname(void)
 {
 	char buf[HOST_NAME_MAX];
-	FILE *fp;
 
-	fp = fopen("/proc/sys/kernel/hostname", "r");
-	if (fp == NULL) {
-		warn("Failed to open file /proc/sys/kernel/hostname");
+	if (gethostname(buf, sizeof(buf)) == -1) {
+		warn("hostname");
 		return smprintf(UNKNOWN_STR);
 	}
-	fgets(buf, sizeof(buf), fp);
-	buf[strlen(buf)-1] = '\0';
-	fclose(fp);
 
 	return smprintf("%s", buf);
 }
@@ -405,20 +405,146 @@ static char *
 run_command(const char *cmd)
 {
 	FILE *fp;
-	char buf[64] = "n/a";
+	char buf[1024] = "n/a";
 
 	fp = popen(cmd, "r");
 	if (fp == NULL) {
 		warn("Failed to get command output for %s", cmd);
 		return smprintf(UNKNOWN_STR);
 	}
-	fgets(buf, sizeof(buf), fp);
-	buf[sizeof(buf)-1] = '\0';
+	fgets(buf, sizeof(buf)-1, fp);
 	pclose(fp);
 
+	buf[strlen(buf)] = '\0';
+	strtok(buf, "\n");
+
 	return smprintf("%s", buf);
 }
 
+static char *
+swap_free(void)
+{
+	long free;
+	FILE *fp;
+	char buf[2048];
+	size_t bytes_read;
+	char *match;
+
+	fp = fopen("/proc/meminfo", "r");
+	if (fp == NULL) {
+		warn("Failed to open file /proc/meminfo");
+		return smprintf(UNKNOWN_STR);
+	}
+	bytes_read = fread(buf, sizeof(char), sizeof(buf), fp);
+	buf[bytes_read] = '\0';
+	fclose(fp);
+	if (bytes_read == 0 || bytes_read == sizeof(buf)) {
+		warn("Failed to read /proc/meminfo\n");
+		return smprintf(UNKNOWN_STR);
+	}
+
+	match = strstr(buf, "SwapFree");
+	sscanf(match, "SwapFree: %ld kB\n", &free);
+
+	return smprintf("%f", (float)free / 1024 / 1024);
+}
+
+static char *
+swap_perc(void)
+{
+	long total, free, cached;
+	FILE *fp;
+	char buf[2048];
+	size_t bytes_read;
+	char *match;
+
+	fp = fopen("/proc/meminfo", "r");
+	if (fp == NULL) {
+		warn("Failed to open file /proc/meminfo");
+		return smprintf(UNKNOWN_STR);
+	}
+	bytes_read = fread(buf, sizeof(char), sizeof(buf), fp);
+	buf[bytes_read] = '\0';
+	fclose(fp);
+	if (bytes_read == 0 || bytes_read == sizeof(buf)) {
+		warn("Failed to read /proc/meminfo\n");
+		return smprintf(UNKNOWN_STR);
+	}
+
+	match = strstr(buf, "SwapCached");
+	sscanf(match, "SwapCached: %ld kB\n", &cached);
+
+	match = strstr(buf, "SwapTotal");
+	sscanf(match, "SwapTotal: %ld kB\n", &total);
+
+	match = strstr(buf, "SwapFree");
+	sscanf(match, "SwapFree: %ld kB\n", &free);
+
+	return smprintf("%d%%", 100 * (total - free - cached) / total);
+}
+
+static char *
+swap_total(void)
+{
+	long total;
+	FILE *fp;
+	char buf[2048];
+	size_t bytes_read;
+	char *match;
+
+	fp = fopen("/proc/meminfo", "r");
+	if (fp == NULL) {
+		warn("Failed to open file /proc/meminfo");
+		return smprintf(UNKNOWN_STR);
+	}
+	bytes_read = fread(buf, sizeof(char), sizeof(buf), fp);
+	buf[bytes_read] = '\0';
+	fclose(fp);
+	if (bytes_read == 0 || bytes_read == sizeof(buf)) {
+		warn("Failed to read /proc/meminfo\n");
+		return smprintf(UNKNOWN_STR);
+	}
+
+	match = strstr(buf, "SwapTotal");
+	sscanf(match, "SwapTotal: %ld kB\n", &total);
+
+	return smprintf("%f", (float)total / 1024 / 1024);
+}
+
+static char *
+swap_used(void)
+{
+	long total, free, cached;
+	FILE *fp;
+	char buf[2048];
+	size_t bytes_read;
+	char *match;
+
+	fp = fopen("/proc/meminfo", "r");
+	if (fp == NULL) {
+		warn("Failed to open file /proc/meminfo");
+		return smprintf(UNKNOWN_STR);
+	}
+	bytes_read = fread(buf, sizeof(char), sizeof(buf), fp);
+	buf[bytes_read] = '\0';
+	fclose(fp);
+	if (bytes_read == 0 || bytes_read == sizeof(buf)) {
+		warn("Failed to read /proc/meminfo\n");
+		return smprintf(UNKNOWN_STR);
+	}
+
+	match = strstr(buf, "SwapCached");
+	sscanf(match, "SwapCached: %ld kB\n", &cached);
+
+	match = strstr(buf, "SwapTotal");
+	sscanf(match, "SwapTotal: %ld kB\n", &total);
+
+	match = strstr(buf, "SwapFree");
+	sscanf(match, "SwapFree: %ld kB\n", &free);
+
+	return smprintf("%f", (float)(total - free - cached) / 1024 / 1024);
+}
+
 static char *
 temp(const char *file)
 {
@@ -474,6 +600,7 @@ uid(void)
 static char *
 vol_perc(const char *card)
 {
+	int mute;
 	long int vol, max, min;
 	snd_mixer_t *handle;
 	snd_mixer_elem_t *elem;
@@ -497,14 +624,17 @@ vol_perc(const char *card)
 	snd_mixer_handle_events(handle);
 	snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
 	snd_mixer_selem_get_playback_volume(elem, 0, &vol);
+	snd_mixer_selem_get_playback_switch(elem, 0, &mute);
 
 	snd_mixer_selem_id_free(s_elem);
 	snd_mixer_close(handle);
 
-	if (max == 0)
-		return smprintf("%d%%", 0);
+	if (!mute)
+		return smprintf("mute");
+	else if (max == 0)
+		return smprintf("0%%");
 	else
-		return smprintf("%d%%", ((uint_fast16_t)(vol * 100) / max));
+		return smprintf("%lu%%", ((uint_fast16_t)(vol * 100) / max));
 }
 
 static char *
@@ -624,8 +754,8 @@ main(int argc, char *argv[])
 	if (dflag && oflag) {
 		usage();
 	}
-	if (dflag) {
-		(void)daemon(1, 1);
+	if (dflag && daemon(1, 1) < 0) {
+		err(1, "daemon");
 	}
 
 	memset(&act, 0, sizeof(act));
@@ -637,6 +767,8 @@ main(int argc, char *argv[])
 		dpy = XOpenDisplay(NULL);
 	}
 
+	setlocale(LC_ALL, "");
+
 	while (!done) {
 		status_string[0] = '\0';