Compare commits

...

10 commits

Author SHA1 Message Date
Sanchayan Maity fff1fc9f6d config: Update status config as per our requirement 2020-11-07 20:04:12 +05:30
Sanchayan Maity 92f1a56c46 Add gitignore 2020-11-07 19:06:30 +05:30
Ingo Feinerer b14e039639 Follow International System of Units spacing rules 2019-02-17 16:53:56 +01:00
Aaron Marcher 93daf4f35e Add OS-support notice to README 2019-02-16 17:05:04 +01:00
Michael Buch a1ac203d16 Add ram and swap components on FreeBSD 2019-02-16 16:58:34 +01:00
Ingo Feinerer 10bdf01b71 cpu_perc: Check for division by zero 2019-02-16 16:56:55 +01:00
Ingo Feinerer d518472e62 Fix CPU frequency on OpenBSD 2019-02-13 18:04:14 +01:00
Michael Buch a9193a757a close file descriptors and fix return values 2019-02-13 15:23:04 +01:00
Ingo Feinerer c1dc896c80 Add native OpenBSD support for mute/volume
Based on functionality in dstat by Joerg Jung.
2019-02-13 13:35:44 +01:00
Michael Buch e724907cc3 wifi component on FreeBSD 2019-02-13 13:10:20 +01:00
11 changed files with 385 additions and 54 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*.o
slstatus
config.h

View file

@ -18,6 +18,8 @@ Copyright 2018 Tobias Tschinkowitz <tobias@he4d.net>
Copyright 2018 David Demelier <markand@malikania.fr> Copyright 2018 David Demelier <markand@malikania.fr>
Copyright 2018-2019 Michael Buch <michaelbuch12@gmail.com> Copyright 2018-2019 Michael Buch <michaelbuch12@gmail.com>
Copyright 2018 Ian Remmler <ian@remmler.org> Copyright 2018 Ian Remmler <ian@remmler.org>
Copyright 2016-2019 Joerg Jung <jung@openbsd.org>
Copyright 2019 Ingo Feinerer <feinerer@logic.at>
Permission to use, copy, modify, and/or distribute this software for any Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above purpose with or without fee is hereby granted, provided that the above

3
README
View file

@ -32,13 +32,14 @@ Features
Requirements Requirements
------------ ------------
Currently slstatus works on FreeBSD, Linux and OpenBSD.
In order to build slstatus you need the Xlib header files. In order to build slstatus you need the Xlib header files.
Installation Installation
------------ ------------
Edit config.mk to match your local setup (slstatus is installed into the Edit config.mk to match your local setup (slstatus is installed into the
/usr/local namespace by default). Uncomment OSSLIBS on OpenBSD. /usr/local namespace by default).
Afterwards enter the following command to build and install slstatus (if Afterwards enter the following command to build and install slstatus (if
necessary as root): necessary as root):

View file

@ -24,7 +24,7 @@
cpu_perc(void) cpu_perc(void)
{ {
static long double a[7]; static long double a[7];
long double b[7]; long double b[7], sum;
memcpy(b, a, sizeof(b)); memcpy(b, a, sizeof(b));
/* cpu user nice system idle iowait irq softirq */ /* cpu user nice system idle iowait irq softirq */
@ -37,13 +37,16 @@
return NULL; return NULL;
} }
sum = (b[0] + b[1] + b[2] + b[3] + b[4] + b[5] + b[6]) -
(a[0] + a[1] + a[2] + a[3] + a[4] + a[5] + a[6]);
if (sum == 0) {
return NULL;
}
return bprintf("%d", (int)(100 * return bprintf("%d", (int)(100 *
((b[0] + b[1] + b[2] + b[5] + b[6]) - ((b[0] + b[1] + b[2] + b[5] + b[6]) -
(a[0] + a[1] + a[2] + a[5] + a[6])) / (a[0] + a[1] + a[2] + a[5] + a[6])) / sum));
((b[0] + b[1] + b[2] + b[3] + b[4] + b[5] +
b[6]) -
(a[0] + a[1] + a[2] + a[3] + a[4] + a[5] +
a[6]))));
} }
#elif defined(__OpenBSD__) #elif defined(__OpenBSD__)
#include <sys/param.h> #include <sys/param.h>
@ -53,8 +56,7 @@
const char * const char *
cpu_freq(void) cpu_freq(void)
{ {
int mib[2]; int freq, mib[2];
uintmax_t freq;
size_t size; size_t size;
mib[0] = CTL_HW; mib[0] = CTL_HW;
@ -76,7 +78,7 @@
{ {
int mib[2]; int mib[2];
static uintmax_t a[CPUSTATES]; static uintmax_t a[CPUSTATES];
uintmax_t b[CPUSTATES]; uintmax_t b[CPUSTATES], sum;
size_t size; size_t size;
mib[0] = CTL_KERN; mib[0] = CTL_KERN;
@ -93,15 +95,18 @@
return NULL; return NULL;
} }
sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) -
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]);
if (sum == 0) {
return NULL;
}
return bprintf("%d", 100 * return bprintf("%d", 100 *
((a[CP_USER] + a[CP_NICE] + a[CP_SYS] + ((a[CP_USER] + a[CP_NICE] + a[CP_SYS] +
a[CP_INTR]) - a[CP_INTR]) -
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] + (b[CP_USER] + b[CP_NICE] + b[CP_SYS] +
b[CP_INTR])) / b[CP_INTR])) / sum);
((a[CP_USER] + a[CP_NICE] + a[CP_SYS] +
a[CP_INTR] + a[CP_IDLE]) -
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] +
b[CP_INTR] + b[CP_IDLE])));
} }
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__)
#include <sys/param.h> #include <sys/param.h>
@ -130,7 +135,7 @@
{ {
size_t size; size_t size;
static long a[CPUSTATES]; static long a[CPUSTATES];
long b[CPUSTATES]; long b[CPUSTATES], sum;
size = sizeof(a); size = sizeof(a);
memcpy(b, a, sizeof(b)); memcpy(b, a, sizeof(b));
@ -143,14 +148,17 @@
return NULL; return NULL;
} }
sum = (a[CP_USER] + a[CP_NICE] + a[CP_SYS] + a[CP_INTR] + a[CP_IDLE]) -
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] + b[CP_INTR] + b[CP_IDLE]);
if (sum == 0) {
return NULL;
}
return bprintf("%d", 100 * return bprintf("%d", 100 *
((a[CP_USER] + a[CP_NICE] + a[CP_SYS] + ((a[CP_USER] + a[CP_NICE] + a[CP_SYS] +
a[CP_INTR]) - a[CP_INTR]) -
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] + (b[CP_USER] + b[CP_NICE] + b[CP_SYS] +
b[CP_INTR])) / b[CP_INTR])) / sum);
((a[CP_USER] + a[CP_NICE] + a[CP_SYS] +
a[CP_INTR] + a[CP_IDLE]) -
(b[CP_USER] + b[CP_NICE] + b[CP_SYS] +
b[CP_INTR] + b[CP_IDLE])));
} }
#endif #endif

View file

@ -156,4 +156,67 @@
return NULL; return NULL;
} }
#elif defined(__FreeBSD__)
#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#include <unistd.h>
#include <vm/vm_param.h>
const char *
ram_free(void) {
struct vmtotal vm_stats;
int mib[] = {CTL_VM, VM_TOTAL};
size_t len;
len = sizeof(struct vmtotal);
if (sysctl(mib, 2, &vm_stats, &len, NULL, 0) == -1
|| !len)
return NULL;
return fmt_human(vm_stats.t_free * getpagesize(), 1024);
}
const char *
ram_total(void) {
long npages;
size_t len;
len = sizeof(npages);
if (sysctlbyname("vm.stats.vm.v_page_count", &npages, &len, NULL, 0) == -1
|| !len)
return NULL;
return fmt_human(npages * getpagesize(), 1024);
}
const char *
ram_perc(void) {
long npages;
long active;
size_t len;
len = sizeof(npages);
if (sysctlbyname("vm.stats.vm.v_page_count", &npages, &len, NULL, 0) == -1
|| !len)
return NULL;
if (sysctlbyname("vm.stats.vm.v_active_count", &active, &len, NULL, 0) == -1
|| !len)
return NULL;
return bprintf("%d", active * 100 / npages);
}
const char *
ram_used(void) {
long active;
size_t len;
len = sizeof(active);
if (sysctlbyname("vm.stats.vm.v_active_count", &active, &len, NULL, 0) == -1
|| !len)
return NULL;
return fmt_human(active * getpagesize(), 1024);
}
#endif #endif

View file

@ -197,4 +197,88 @@
return fmt_human(used * 1024, 1024); return fmt_human(used * 1024, 1024);
} }
#elif defined(__FreeBSD__)
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <kvm.h>
static int getswapinfo(struct kvm_swap *swap_info, size_t size)
{
kvm_t *kd;
kd = kvm_openfiles(NULL, "/dev/null", NULL, 0, NULL);
if(kd == NULL) {
warn("kvm_openfiles '/dev/null':");
return 0;
}
if(kvm_getswapinfo(kd, swap_info, size, 0 /* Unused flags */) == -1) {
warn("kvm_getswapinfo:");
kvm_close(kd);
return 0;
}
kvm_close(kd);
return 1;
}
const char *
swap_free(void)
{
struct kvm_swap swap_info[1];
long used, total;
if(!getswapinfo(swap_info, 1))
return NULL;
total = swap_info[0].ksw_total;
used = swap_info[0].ksw_used;
return fmt_human((total - used) * getpagesize(), 1024);
}
const char *
swap_perc(void)
{
struct kvm_swap swap_info[1];
long used, total;
if(!getswapinfo(swap_info, 1))
return NULL;
total = swap_info[0].ksw_total;
used = swap_info[0].ksw_used;
return bprintf("%d", used * 100 / total);
}
const char *
swap_total(void)
{
struct kvm_swap swap_info[1];
long total;
if(!getswapinfo(swap_info, 1))
return NULL;
total = swap_info[0].ksw_total;
return fmt_human(total * getpagesize(), 1024);
}
const char *
swap_used(void)
{
struct kvm_swap swap_info[1];
long used;
if(!getswapinfo(swap_info, 1))
return NULL;
used = swap_info[0].ksw_used;
return fmt_human(used * getpagesize(), 1024);
}
#endif #endif

View file

@ -2,44 +2,108 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#if defined(__OpenBSD__)
#include <soundcard.h>
#else
#include <sys/soundcard.h>
#endif
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <unistd.h> #include <unistd.h>
#include "../util.h" #include "../util.h"
const char * #if defined(__OpenBSD__)
vol_perc(const char *card) #include <sys/audioio.h>
{
size_t i;
int v, afd, devmask;
char *vnames[] = SOUND_DEVICE_NAMES;
if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) { const char *
warn("open '%s':", card); vol_perc(const char *card)
return NULL; {
} static int cls = -1;
mixer_devinfo_t mdi;
mixer_ctrl_t mc;
int afd = -1, m = -1, v = -1;
if (ioctl(afd, (int)SOUND_MIXER_READ_DEVMASK, &devmask) < 0) { if ((afd = open(card, O_RDONLY)) < 0) {
warn("ioctl 'SOUND_MIXER_READ_DEVMASK':"); warn("open '%s':", card);
close(afd); return NULL;
return NULL; }
}
for (i = 0; i < LEN(vnames); i++) { for (mdi.index = 0; cls == -1; mdi.index++) {
if (devmask & (1 << i) && !strcmp("vol", vnames[i])) { if (ioctl(afd, AUDIO_MIXER_DEVINFO, &mdi) < 0) {
if (ioctl(afd, MIXER_READ(i), &v) < 0) { warn("ioctl 'AUDIO_MIXER_DEVINFO':");
warn("ioctl 'MIXER_READ(%ld)':", i);
close(afd); close(afd);
return NULL; return NULL;
} }
if (mdi.type == AUDIO_MIXER_CLASS &&
!strncmp(mdi.label.name,
AudioCoutputs,
MAX_AUDIO_DEV_LEN))
cls = mdi.index;
}
for (mdi.index = 0; v == -1 || m == -1; mdi.index++) {
if (ioctl(afd, AUDIO_MIXER_DEVINFO, &mdi) < 0) {
warn("ioctl 'AUDIO_MIXER_DEVINFO':");
close(afd);
return NULL;
}
if (mdi.mixer_class == cls &&
((mdi.type == AUDIO_MIXER_VALUE &&
!strncmp(mdi.label.name,
AudioNmaster,
MAX_AUDIO_DEV_LEN)) ||
(mdi.type == AUDIO_MIXER_ENUM &&
!strncmp(mdi.label.name,
AudioNmute,
MAX_AUDIO_DEV_LEN)))) {
mc.dev = mdi.index, mc.type = mdi.type;
if (ioctl(afd, AUDIO_MIXER_READ, &mc) < 0) {
warn("ioctl 'AUDIO_MIXER_READ':");
close(afd);
return NULL;
}
if (mc.type == AUDIO_MIXER_VALUE)
v = mc.un.value.num_channels == 1 ?
mc.un.value.level[AUDIO_MIXER_LEVEL_MONO] :
(mc.un.value.level[AUDIO_MIXER_LEVEL_LEFT] >
mc.un.value.level[AUDIO_MIXER_LEVEL_RIGHT] ?
mc.un.value.level[AUDIO_MIXER_LEVEL_LEFT] :
mc.un.value.level[AUDIO_MIXER_LEVEL_RIGHT]);
else if (mc.type == AUDIO_MIXER_ENUM)
m = mc.un.ord;
}
} }
close(afd);
return bprintf("%d", m ? 0 : v * 100 / 255);
} }
#else
#include <sys/soundcard.h>
close(afd); const char *
vol_perc(const char *card)
{
size_t i;
int v, afd, devmask;
char *vnames[] = SOUND_DEVICE_NAMES;
return bprintf("%d", v & 0xff); if ((afd = open(card, O_RDONLY | O_NONBLOCK)) < 0) {
} warn("open '%s':", card);
return NULL;
}
if (ioctl(afd, (int)SOUND_MIXER_READ_DEVMASK, &devmask) < 0) {
warn("ioctl 'SOUND_MIXER_READ_DEVMASK':");
close(afd);
return NULL;
}
for (i = 0; i < LEN(vnames); i++) {
if (devmask & (1 << i) && !strcmp("vol", vnames[i])) {
if (ioctl(afd, MIXER_READ(i), &v) < 0) {
warn("ioctl 'MIXER_READ(%ld)':", i);
close(afd);
return NULL;
}
}
}
close(afd);
return bprintf("%d", v & 0xff);
}
#endif

View file

@ -8,6 +8,11 @@
#include "../util.h" #include "../util.h"
#define RSSI_TO_PERC(rssi) \
rssi >= -50 ? 100 : \
(rssi <= -100 ? 0 : \
(2 * (rssi + 100)))
#if defined(__linux__) #if defined(__linux__)
#include <limits.h> #include <limits.h>
#include <linux/wireless.h> #include <linux/wireless.h>
@ -150,9 +155,7 @@
if (nr.nr_max_rssi) { if (nr.nr_max_rssi) {
q = IEEE80211_NODEREQ_RSSI(&nr); q = IEEE80211_NODEREQ_RSSI(&nr);
} else { } else {
q = nr.nr_rssi >= -50 ? 100 : q = RSSI_TO_PERC(nr.nr_rssi);
(nr.nr_rssi <= -100 ? 0 :
(2 * (nr.nr_rssi + 100)));
} }
return bprintf("%d", q); return bprintf("%d", q);
} }
@ -171,4 +174,99 @@
return NULL; return NULL;
} }
#elif defined(__FreeBSD__)
#include <net/if.h>
#include <net80211/ieee80211_ioctl.h>
int
load_ieee80211req(int sock, const char *interface, void *data, int type, size_t *len)
{
char warn_buf[256];
struct ieee80211req ireq;
memset(&ireq, 0, sizeof(ireq));
ireq.i_type = type;
ireq.i_data = (caddr_t) data;
ireq.i_len = *len;
strlcpy(ireq.i_name, interface, sizeof(ireq.i_name));
if (ioctl(sock, SIOCG80211, &ireq) < 0) {
snprintf(warn_buf, sizeof(warn_buf),
"ioctl: 'SIOCG80211': %d", type);
warn(warn_buf);
return 0;
}
*len = ireq.i_len;
return 1;
}
const char *
wifi_perc(const char *interface)
{
union {
struct ieee80211req_sta_req sta;
uint8_t buf[24 * 1024];
} info;
uint8_t bssid[IEEE80211_ADDR_LEN];
int rssi_dbm;
int sockfd;
size_t len;
const char *fmt;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
warn("socket 'AF_INET':");
return NULL;
}
/* Retreive MAC address of interface */
len = IEEE80211_ADDR_LEN;
fmt = NULL;
if (load_ieee80211req(sockfd, interface, &bssid, IEEE80211_IOC_BSSID, &len))
{
/* Retrieve info on station with above BSSID */
memset(&info, 0, sizeof(info));
memcpy(info.sta.is_u.macaddr, bssid, sizeof(bssid));
len = sizeof(info);
if (load_ieee80211req(sockfd, interface, &info, IEEE80211_IOC_STA_INFO, &len)) {
rssi_dbm = info.sta.info[0].isi_noise +
info.sta.info[0].isi_rssi / 2;
fmt = bprintf("%d", RSSI_TO_PERC(rssi_dbm));
}
}
close(sockfd);
return fmt;
}
const char *
wifi_essid(const char *interface)
{
char ssid[IEEE80211_NWID_LEN + 1];
size_t len;
int sockfd;
const char *fmt;
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
warn("socket 'AF_INET':");
return NULL;
}
fmt = NULL;
len = sizeof(ssid);
memset(&ssid, 0, len);
if (load_ieee80211req(sockfd, interface, &ssid, IEEE80211_IOC_SSID, &len )) {
if (len < sizeof(ssid))
len += 1;
else
len = sizeof(ssid);
ssid[len - 1] = '\0';
fmt = bprintf("%s", ssid);
}
close(sockfd);
return fmt;
}
#endif #endif

View file

@ -63,5 +63,14 @@ static const char unknown_str[] = "n/a";
*/ */
static const struct arg args[] = { static const struct arg args[] = {
/* function format argument */ /* function format argument */
{ datetime, "%s", "%F %T" }, { wifi_essid, " [WIFI: %s" , "wlp58s0" },
{ wifi_perc, " SS: %s" , "wlp58s0" },
{ netspeed_tx, " TX: %s" , "wlp58s0" },
{ netspeed_rx, " RX: %s]" , "wlp58s0" },
{ battery_perc, " [ %s]" , "BAT0" },
{ load_avg, " [LOAD: %s]" , NULL },
{ cpu_perc, " [ %s%%]" , NULL },
{ ram_perc, " [ %s%%]" , NULL },
{ datetime, " |  %s |" , "%a, %b %d"},
{ datetime, "  %s " , "%I:%M %p" },
}; };

View file

@ -14,7 +14,6 @@ X11LIB = /usr/X11R6/lib
CPPFLAGS = -I$(X11INC) -D_DEFAULT_SOURCE CPPFLAGS = -I$(X11INC) -D_DEFAULT_SOURCE
CFLAGS = -std=c99 -pedantic -Wall -Wextra -Os CFLAGS = -std=c99 -pedantic -Wall -Wextra -Os
LDFLAGS = -L$(X11LIB) -s LDFLAGS = -L$(X11LIB) -s
# OpenBSD: add -lossaudio
LDLIBS = -lX11 LDLIBS = -lX11
# compiler and linker # compiler and linker

2
util.c
View file

@ -123,7 +123,7 @@ fmt_human(uintmax_t num, int base)
scaled /= base; scaled /= base;
} }
return bprintf("%.1f%s", scaled, prefix[i]); return bprintf("%.1f %s", scaled, prefix[i]);
} }
int int