/* Copyright (C) 2025 awy This file is part of stbar. stbar is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. stbar is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with stbar. If not, see . */ #include #include "util.h" #include #include #include #include #include #include #include #include void die(const char *fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); if (fmt[0] && fmt[strlen(fmt) - 1] == ':') { fputc(' ', stderr); perror(NULL); } else { fputc('\n', stderr); } exit(1); } void sendnotif(const char *appname, const char *title, const char *body) { notify_init(appname); NotifyNotification *n; n = notify_notification_new(title, body, NULL); notify_notification_show(n, NULL); g_object_unref(G_OBJECT(n)); notify_uninit(); } int getbtnint(const char *blkbtn) { char *endptr; int errno; long val; errno = 0; if (blkbtn == NULL) return 0; val = strtol(blkbtn, &endptr, 10); if (errno == 0 && *endptr == '\0' && val >= 1 && val <= 8) return (int)val; return 0; } pid_t spawn(const char *const argv[]) { pid_t pid = fork(); if (pid == 0) { dup2(STDERR_FILENO, STDOUT_FILENO); setsid(); execvp(argv[0], (char *const *)argv); die("spawn %s failed:", (argv)[0]); } return pid; } int find_pid_by_name(const char *process_name) { DIR *dir = opendir("/proc"); if (!dir) return -1; struct dirent *entry; while ((entry = readdir(dir)) != NULL) { if (!isdigit(entry->d_name[0])) continue; char path[PATH_MAX], name[NAME_MAX]; snprintf(path, sizeof(path), "/proc/%s/comm", entry->d_name); FILE *fp = fopen(path, "r"); if (!fp) continue; if (fgets(name, sizeof(name), fp)) { name[strcspn(name, "\n")] = 0; if (strcmp(name, process_name) == 0) { fclose(fp); closedir(dir); return atoi(entry->d_name); } } fclose(fp); } closedir(dir); return -1; } int updatebar(const int signal) { int pid_to_kill; const int wbar = find_pid_by_name("waybar"); const int sblk = find_pid_by_name("someblocks"); const int i3blk = find_pid_by_name("i3blocks"); if (wbar == -1 && sblk == -1 && i3blk == -1) die("no bar running"); if (wbar != -1) pid_to_kill = wbar; else if (sblk != -1) pid_to_kill = sblk; else pid_to_kill = i3blk; kill(pid_to_kill, SIGRTMIN + signal); return 0; } int lscanf(FILE *fp, const char *key, const char *fmt, void *res) { int n; char line[256]; n = -1; while (fgets(line, sizeof(line), fp)) if (strncmp(line, key, strlen(key)) == 0) { n = sscanf(line + strlen(key), fmt, res); break; } rewind(fp); return (n == 1) ? 1 : -1; }