Merge branch 'master' into module_mpris

This commit is contained in:
haruInDisguise 2024-08-28 23:34:09 +00:00
commit 0d8ef94921
9 changed files with 211 additions and 75 deletions

View file

@ -16,8 +16,16 @@
### Added ### Added
* environment variable substitution in config files ([#96][96]). * environment variable substitution in config files ([#96][96]).
* Log output now respects the [`NO_COLOR`](http://no-color.org/)
environment variable.
* network: `type` tag ([#380][380]).
* network: `type` and `kind` tags ([#380][380]).
* tags: `b` tag formatter; divides the tag's decimal value with `8`
([#392][392]).
[96]: https://codeberg.org/dnkl/yambar/issues/96 [96]: https://codeberg.org/dnkl/yambar/issues/96
[380]: https://codeberg.org/dnkl/yambar/issues/380
[392]: https://codeberg.org/dnkl/yambar/issues/392
### Changed ### Changed
@ -34,6 +42,8 @@
* network: fix missing break in switch statement ([#377][377]). * network: fix missing break in switch statement ([#377][377]).
* i3/sway: crash when output is turned off an on ([#300][300]). * i3/sway: crash when output is turned off an on ([#300][300]).
* mpd: yambar never attempting to reconnect after MPD closed the
connection (for example, when MPD is restarted).
[377]: https://codeberg.org/dnkl/yambar/issues/377 [377]: https://codeberg.org/dnkl/yambar/issues/377
[300]: https://codeberg.org/dnkl/yambar/issues/300 [300]: https://codeberg.org/dnkl/yambar/issues/300

View file

@ -2,7 +2,7 @@
# Yambar # Yambar
[![Packaging status](https://repology.org/badge/vertical-allrepos/yambar.svg)](https://repology.org/project/yambar/versions) [![Packaging status](https://repology.org/badge/vertical-allrepos/yambar.svg?columns=4)](https://repology.org/project/yambar/versions)
## Index ## Index

View file

@ -21,6 +21,16 @@ address per network interface.
| name | name
: string : string
: Network interface name : Network interface name
| type
: string
: Interface type (*ether*, *wlan*, *loopback*, or *ARPHRD_NNN*, where
*N* is a number).
| kind
: string
: Interface kind. Empty for non-virtual interfaces. For virtual
interfaces, this value is taken from the _IFLA\_INFO\_KIND_ netlink
attribute. Examples of valid values are *bond*, *bridge*, *gre*, *tun*
and *veth*.
| index | index
: int : int
: Network interface index : Network interface index
@ -91,17 +101,23 @@ address per network interface.
# EXAMPLES # EXAMPLES
Display all Ethernet (including WLAN) devices. This excludes loopback,
bridges etc.
``` ```
bar: bar:
left: left:
- network: - network:
content: content:
map: map:
default:
string: {text: "{name}: {state} ({ipv4})"}
conditions: conditions:
ipv4 == "": type == ether || type == wlan:
string: {text: "{name}: {state}"} map:
default:
string: {text: "{name}: {state} ({ipv4})"}
conditions:
ipv4 == "":
string: {text: "{name}: {state}"}
``` ```
# SEE ALSO # SEE ALSO

View file

@ -86,11 +86,16 @@ be used.
: format : format
: Range tags : Range tags
: Renders a range tag's value as a percentage value : Renders a range tag's value as a percentage value
| b
: format
: All tag types
: Renders a tag's value (in decimal) divided by 8. Note: no unit
suffix is appended
| kb, mb, gb | kb, mb, gb
: format : format
: All tag types : All tag types
: Renders a tag's value (in decimal) divided by 1000, 1000^2 or : Renders a tag's value (in decimal) divided by 1000, 1000^2 or
1000^3. Note: no unit suffix is appended) 1000^3. Note: no unit suffix is appended
| kib, mib, gib | kib, mib, gib
: format : format
: All tag types : All tag types

12
log.c
View file

@ -39,9 +39,15 @@ log_init(enum log_colorize _colorize, bool _do_syslog, enum log_facility syslog_
[LOG_FACILITY_DAEMON] = LOG_DAEMON, [LOG_FACILITY_DAEMON] = LOG_DAEMON,
}; };
colorize = _colorize == LOG_COLORIZE_NEVER ? false /* Don't use colors if NO_COLOR is defined and not empty */
: _colorize == LOG_COLORIZE_ALWAYS ? true const char *no_color_str = getenv("NO_COLOR");
: isatty(STDERR_FILENO); const bool no_color = no_color_str != NULL && no_color_str[0] != '\0';
colorize = _colorize == LOG_COLORIZE_NEVER
? false
: _colorize == LOG_COLORIZE_ALWAYS
? true
: !no_color && isatty(STDERR_FILENO);
do_syslog = _do_syslog; do_syslog = _do_syslog;
log_level = _log_level; log_level = _log_level;

View file

@ -12,7 +12,9 @@ plugs_as_libs = get_option('core-plugins-as-shared-libraries')
cc = meson.get_compiler('c') cc = meson.get_compiler('c')
if cc.has_function('memfd_create') if cc.has_function('memfd_create',
args: ['-D_GNU_SOURCE=200809L'],
prefix: '#include <sys/mman.h>')
add_project_arguments('-DMEMFD_CREATE', language: 'c') add_project_arguments('-DMEMFD_CREATE', language: 'c')
endif endif

View file

@ -437,7 +437,7 @@ run(struct module *mod)
*/ */
while (!aborted) { while (!aborted) {
struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}}; struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}};
int res = poll(fds, sizeof(fds) / sizeof(fds[0]), 10 * 1000); int res = poll(fds, sizeof(fds) / sizeof(fds[0]), 2 * 1000);
if (res < 0) { if (res < 0) {
if (errno == EINTR) if (errno == EINTR)
@ -448,10 +448,16 @@ run(struct module *mod)
break; break;
} }
if (res == 1) { if (res == 0) {
ret = 0;
break;
}
else if (res == 1) {
assert(fds[0].revents & POLLIN); assert(fds[0].revents & POLLIN);
aborted = true; aborted = true;
} }
} }
} }

View file

@ -17,6 +17,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <linux/genetlink.h> #include <linux/genetlink.h>
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/nl80211.h> #include <linux/nl80211.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
@ -24,7 +25,7 @@
#include <tllist.h> #include <tllist.h>
#define LOG_MODULE "network" #define LOG_MODULE "network"
#define LOG_ENABLE_DBG 0 #define LOG_ENABLE_DBG 1
#include "../bar/bar.h" #include "../bar/bar.h"
#include "../config-verify.h" #include "../config-verify.h"
#include "../config.h" #include "../config.h"
@ -52,6 +53,8 @@ struct af_addr {
struct iface { struct iface {
char *name; char *name;
char *type; /* ARPHRD_NNN */
char *kind; /* IFLA_LINKINFO::IFLA_INFO_KIND */
uint32_t get_stats_seq_nr; uint32_t get_stats_seq_nr;
@ -104,6 +107,8 @@ free_iface(struct iface iface)
{ {
tll_free(iface.addrs); tll_free(iface.addrs);
free(iface.ssid); free(iface.ssid);
free(iface.kind);
free(iface.type);
free(iface.name); free(iface.name);
} }
@ -207,6 +212,8 @@ content(struct module *mod)
struct tag_set tags = { struct tag_set tags = {
.tags = (struct tag *[]){ .tags = (struct tag *[]){
tag_new_string(mod, "name", iface->name), tag_new_string(mod, "name", iface->name),
tag_new_string(mod, "type", iface->type),
tag_new_string(mod, "kind", iface->kind),
tag_new_int(mod, "index", iface->index), tag_new_int(mod, "index", iface->index),
tag_new_bool(mod, "carrier", iface->carrier), tag_new_bool(mod, "carrier", iface->carrier),
tag_new_string(mod, "state", state), tag_new_string(mod, "state", state),
@ -221,7 +228,7 @@ content(struct module *mod)
tag_new_float(mod, "dl-speed", iface->dl_speed), tag_new_float(mod, "dl-speed", iface->dl_speed),
tag_new_float(mod, "ul-speed", iface->ul_speed), tag_new_float(mod, "ul-speed", iface->ul_speed),
}, },
.count = 14, .count = 16,
}; };
exposables[idx++] = m->label->instantiate(m->label, &tags); exposables[idx++] = m->label->instantiate(m->label, &tags);
tag_set_destroy(&tags); tag_set_destroy(&tags);
@ -549,6 +556,79 @@ send_nl80211_get_scan(struct private *m)
return true; return true;
} }
static bool
foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr *genl, size_t len,
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload,
size_t len, void *ctx),
void *ctx)
{
const uint8_t *raw = (const uint8_t *)genl + GENL_HDRLEN;
const uint8_t *end = (const uint8_t *)genl + len;
for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end;
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) {
uint16_t type = attr->nla_type & NLA_TYPE_MASK;
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;
;
const void *payload = raw + NLA_HDRLEN;
if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx))
return false;
}
return true;
}
static bool
foreach_nlattr_nested(struct module *mod, struct iface *iface, const void *parent_payload, size_t len,
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested,
const void *payload, size_t len, void *ctx),
void *ctx)
{
const uint8_t *raw = parent_payload;
const uint8_t *end = parent_payload + len;
for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end;
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) {
uint16_t type = attr->nla_type & NLA_TYPE_MASK;
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;
const void *payload = raw + NLA_HDRLEN;
if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx))
return false;
}
return true;
}
static bool
parse_linkinfo(struct module *mod, struct iface *iface, uint16_t type,
bool nested, const void *payload, size_t len, void *_void)
{
switch (type) {
case IFLA_INFO_KIND: {
const char *kind = payload;
free(iface->kind);
iface->kind = strndup(kind, len);
LOG_DBG("%s: IFLA_INFO_KIND: %s", iface->name, iface->kind);
break;
}
case IFLA_INFO_DATA:
//LOG_DBG("%s: IFLA_INFO_DATA", iface->name);
break;
default:
LOG_WARN("unrecognized IFLA_LINKINFO attribute: "
"type=%hu, nested=%d, len=%zu",
type, nested, len);
break;
}
return true;
}
static void static void
handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size_t len) handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size_t len)
{ {
@ -581,9 +661,31 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size
} }
if (iface == NULL) { if (iface == NULL) {
char *type = NULL;
switch (msg->ifi_type) {
case ARPHRD_ETHER:
type = strdup("ether");
break;
case ARPHRD_LOOPBACK:
type = strdup("loopback");
break;
case ARPHRD_IEEE80211:
type = strdup("wlan");
break;
default:
if (asprintf(&type, "ARPHRD_%hu", msg->ifi_type) < 0)
type = strdup("unknown");
break;
}
mtx_lock(&mod->lock); mtx_lock(&mod->lock);
tll_push_back(m->ifaces, ((struct iface){ tll_push_back(m->ifaces, ((struct iface){
.index = msg->ifi_index, .index = msg->ifi_index,
.type = type,
.state = IF_OPER_DOWN, .state = IF_OPER_DOWN,
.addrs = tll_init(), .addrs = tll_init(),
})); }));
@ -596,9 +698,10 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size
case IFLA_IFNAME: case IFLA_IFNAME:
mtx_lock(&mod->lock); mtx_lock(&mod->lock);
iface->name = strdup((const char *)RTA_DATA(attr)); iface->name = strdup((const char *)RTA_DATA(attr));
LOG_DBG("%s: index=%d", iface->name, iface->index); LOG_DBG("%s: index=%d, type=%s", iface->name, iface->index, iface->type);
mtx_unlock(&mod->lock); mtx_unlock(&mod->lock);
break; break;
case IFLA_OPERSTATE: { case IFLA_OPERSTATE: {
uint8_t operstate = *(const uint8_t *)RTA_DATA(attr); uint8_t operstate = *(const uint8_t *)RTA_DATA(attr);
if (iface->state == operstate) if (iface->state == operstate)
@ -633,7 +736,8 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size
if (memcmp(iface->mac, mac, sizeof(iface->mac)) == 0) if (memcmp(iface->mac, mac, sizeof(iface->mac)) == 0)
break; break;
LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x", iface->name, mac[0], mac[1], mac[2], mac[3], LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x",
iface->name, mac[0], mac[1], mac[2], mac[3],
mac[4], mac[5]); mac[4], mac[5]);
mtx_lock(&mod->lock); mtx_lock(&mod->lock);
@ -641,6 +745,13 @@ handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size
mtx_unlock(&mod->lock); mtx_unlock(&mod->lock);
break; break;
} }
case IFLA_LINKINFO: {
foreach_nlattr_nested(
mod, iface, RTA_DATA(attr), RTA_PAYLOAD(attr),
&parse_linkinfo, NULL);
break;
}
} }
} }
@ -723,51 +834,6 @@ handle_address(struct module *mod, uint16_t type, const struct ifaddrmsg *msg, s
mod->bar->refresh(mod->bar); mod->bar->refresh(mod->bar);
} }
static bool
foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr *genl, size_t len,
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload,
size_t len, void *ctx),
void *ctx)
{
const uint8_t *raw = (const uint8_t *)genl + GENL_HDRLEN;
const uint8_t *end = (const uint8_t *)genl + len;
for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end;
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) {
uint16_t type = attr->nla_type & NLA_TYPE_MASK;
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;
;
const void *payload = raw + NLA_HDRLEN;
if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx))
return false;
}
return true;
}
static bool
foreach_nlattr_nested(struct module *mod, struct iface *iface, const void *parent_payload, size_t len,
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested,
const void *payload, size_t len, void *ctx),
void *ctx)
{
const uint8_t *raw = parent_payload;
const uint8_t *end = parent_payload + len;
for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end;
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) {
uint16_t type = attr->nla_type & NLA_TYPE_MASK;
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;
const void *payload = raw + NLA_HDRLEN;
if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx))
return false;
}
return true;
}
struct mcast_group { struct mcast_group {
uint32_t id; uint32_t id;
const char *name; const char *name;
@ -1304,6 +1370,8 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
continue; continue;
LOG_DBG("%s: got interface information", iface->name); LOG_DBG("%s: got interface information", iface->name);
free(iface->type);
iface->type = strdup("wlan");
foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_new_interface, NULL); foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_new_interface, NULL);
break; break;

51
tag.c
View file

@ -510,6 +510,7 @@ tags_expand_template(const char *template, const struct tag_set *tags)
FMT_HEX, FMT_HEX,
FMT_OCT, FMT_OCT,
FMT_PERCENT, FMT_PERCENT,
FMT_BYTE,
FMT_KBYTE, FMT_KBYTE,
FMT_MBYTE, FMT_MBYTE,
FMT_GBYTE, FMT_GBYTE,
@ -541,6 +542,8 @@ tags_expand_template(const char *template, const struct tag_set *tags)
format = FMT_OCT; format = FMT_OCT;
else if (strcmp(tag_args[i], "%") == 0) else if (strcmp(tag_args[i], "%") == 0)
format = FMT_PERCENT; format = FMT_PERCENT;
else if (strcmp(tag_args[i], "b") == 0)
format = FMT_BYTE;
else if (strcmp(tag_args[i], "kb") == 0) else if (strcmp(tag_args[i], "kb") == 0)
format = FMT_KBYTE; format = FMT_KBYTE;
else if (strcmp(tag_args[i], "mb") == 0) else if (strcmp(tag_args[i], "mb") == 0)
@ -634,19 +637,29 @@ tags_expand_template(const char *template, const struct tag_set *tags)
break; break;
} }
case FMT_BYTE:
case FMT_KBYTE: case FMT_KBYTE:
case FMT_MBYTE: case FMT_MBYTE:
case FMT_GBYTE: case FMT_GBYTE:
case FMT_KIBYTE: case FMT_KIBYTE:
case FMT_MIBYTE: case FMT_MIBYTE:
case FMT_GIBYTE: { case FMT_GIBYTE: {
const long divider = format == FMT_KBYTE ? 1000 const long divider =
: format == FMT_MBYTE ? 1000 * 1000 format == FMT_BYTE
: format == FMT_GBYTE ? 1000 * 1000 * 1000 ? 8
: format == FMT_KIBYTE ? 1024 : format == FMT_KBYTE
: format == FMT_MIBYTE ? 1024 * 1024 ? 1000
: format == FMT_GIBYTE ? 1024 * 1024 * 1024 : format == FMT_MBYTE
: 1; ? 1000 * 1000
: format == FMT_GBYTE
? 1000 * 1000 * 1000
: format == FMT_KIBYTE
? 1024
: format == FMT_MIBYTE
? 1024 * 1024
: format == FMT_GIBYTE
? 1024 * 1024 * 1024
: 1;
char str[24]; char str[24];
if (tag->type(tag) == TAG_TYPE_FLOAT) { if (tag->type(tag) == TAG_TYPE_FLOAT) {
@ -684,19 +697,29 @@ tags_expand_template(const char *template, const struct tag_set *tags)
fmt = zero_pad ? "%0*lu" : "%*lu"; fmt = zero_pad ? "%0*lu" : "%*lu";
break; break;
case FMT_BYTE:
case FMT_KBYTE: case FMT_KBYTE:
case FMT_MBYTE: case FMT_MBYTE:
case FMT_GBYTE: case FMT_GBYTE:
case FMT_KIBYTE: case FMT_KIBYTE:
case FMT_MIBYTE: case FMT_MIBYTE:
case FMT_GIBYTE: { case FMT_GIBYTE: {
const long divider = format == FMT_KBYTE ? 1024 const long divider =
: format == FMT_MBYTE ? 1024 * 1024 format == FMT_BYTE
: format == FMT_GBYTE ? 1024 * 1024 * 1024 ? 8
: format == FMT_KIBYTE ? 1000 : format == FMT_KBYTE
: format == FMT_MIBYTE ? 1000 * 1000 ? 1024
: format == FMT_GIBYTE ? 1000 * 1000 * 1000 : format == FMT_MBYTE
: 1; ? 1024 * 1024
: format == FMT_GBYTE
? 1024 * 1024 * 1024
: format == FMT_KIBYTE
? 1000
: format == FMT_MIBYTE
? 1000 * 1000
: format == FMT_GIBYTE
? 1000 * 1000 * 1000
: 1;
value /= divider; value /= divider;
fmt = zero_pad ? "%0*lu" : "%*lu"; fmt = zero_pad ? "%0*lu" : "%*lu";
break; break;