initial commit
This commit is contained in:
19
LICENSE
Normal file
19
LICENSE
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2025 Andrew Kloet <andrew@kloet.net>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
32
Makefile
Normal file
32
Makefile
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
CC = cc
|
||||||
|
CFLAGS = -Wall -Wextra -O3
|
||||||
|
CURL_LIBS = -lcurl
|
||||||
|
|
||||||
|
SOURCES = sb-cpu.c sb-date.c sb-memory.c sb-time.c sb-weather.c
|
||||||
|
|
||||||
|
EXECUTABLES = $(SOURCES:.c=)
|
||||||
|
|
||||||
|
all: $(EXECUTABLES)
|
||||||
|
|
||||||
|
sb-weather: sb-weather.c
|
||||||
|
$(CC) $(CFLAGS) $< -o $@ $(CURL_LIBS)
|
||||||
|
|
||||||
|
sb-cpu: sb-cpu.c
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
sb-date: sb-date.c
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
sb-memory: sb-memory.c
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
sb-time: sb-time.c
|
||||||
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXECUTABLES)
|
||||||
|
|
||||||
|
install: all
|
||||||
|
cp $(EXECUTABLES) /usr/local/bin
|
||||||
|
|
||||||
|
.PHONY: all clean
|
||||||
15
README
Normal file
15
README
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
Tiny programs for Linux which print useful info. Suited for piping into other programs which handle window manager statusbar, like Suckless' DWM.
|
||||||
|
Compile with `make`. Install with `make install`.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ ./sb-cpu
|
||||||
|
CPU: 2%
|
||||||
|
$ ./sb-memory
|
||||||
|
Mem: 34%
|
||||||
|
$ ./sb-weather glasgow
|
||||||
|
27°C Overcast
|
||||||
|
$ ./sb-time
|
||||||
|
10:10am
|
||||||
|
$ ./sb-date
|
||||||
|
Jul 10 2025
|
||||||
|
```
|
||||||
53
sb-cpu.c
Normal file
53
sb-cpu.c
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
long long idle;
|
||||||
|
long long total;
|
||||||
|
} cpu_stats_t;
|
||||||
|
|
||||||
|
static int read_cpu_stats(cpu_stats_t *stats) {
|
||||||
|
FILE *fp = fopen("/proc/stat", "r");
|
||||||
|
if (!fp)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
long long user, nice, system, idle, iowait, irq, softirq;
|
||||||
|
int ret = fscanf(fp, "cpu %lld %lld %lld %lld %lld %lld %lld", &user, &nice,
|
||||||
|
&system, &idle, &iowait, &irq, &softirq);
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if (ret != 7)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
stats->idle = idle + iowait;
|
||||||
|
stats->total = user + nice + system + idle + iowait + irq + softirq;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static double calculate_usage(cpu_stats_t *prev, cpu_stats_t *curr) {
|
||||||
|
long long diff_total = curr->total - prev->total;
|
||||||
|
long long diff_idle = curr->idle - prev->idle;
|
||||||
|
|
||||||
|
if (diff_total == 0)
|
||||||
|
return 0.0;
|
||||||
|
return 100.0 * (diff_total - diff_idle) / diff_total;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
cpu_stats_t prev, curr;
|
||||||
|
|
||||||
|
if (read_cpu_stats(&prev) < 0) {
|
||||||
|
fprintf(stderr, "Error reading CPU stats\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
if (read_cpu_stats(&curr) < 0) {
|
||||||
|
fprintf(stderr, "Error reading CPU stats\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("CPU: %.0f%%\n", calculate_usage(&prev, &curr));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
14
sb-date.c
Normal file
14
sb-date.c
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
time_t t = time(NULL);
|
||||||
|
struct tm tm = *localtime(&t);
|
||||||
|
|
||||||
|
const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||||
|
|
||||||
|
printf("%s %02d %d\n", months[tm.tm_mon], tm.tm_mday, tm.tm_year + 1900);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
18
sb-memory.c
Normal file
18
sb-memory.c
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
FILE *fp = fopen("/proc/meminfo", "r");
|
||||||
|
if (!fp)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
long long total = 0, available = 0;
|
||||||
|
char line[256];
|
||||||
|
while (fgets(line, sizeof(line), fp) && (!total || !available)) {
|
||||||
|
sscanf(line, "MemTotal: %lld kB", &total);
|
||||||
|
sscanf(line, "MemAvailable: %lld kB", &available);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
printf("Mem: %.0f%%\n", (double)(total - available) / total * 100);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
11
sb-time.c
Normal file
11
sb-time.c
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
time_t t = time(NULL);
|
||||||
|
char time_str[10];
|
||||||
|
|
||||||
|
strftime(time_str, sizeof(time_str), "%I:%M%P", localtime(&t));
|
||||||
|
printf("%s\n", time_str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
58
sb-weather.c
Normal file
58
sb-weather.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#include <curl/curl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define WEATHER_FORMAT "?format=%f+%C"
|
||||||
|
#define MAX_SIZE 1024
|
||||||
|
|
||||||
|
size_t write_callback(void *ptr, size_t size, size_t nmemb, char *data) {
|
||||||
|
strncat(data, ptr, size * nmemb);
|
||||||
|
return size * nmemb;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "Usage: %s <location>\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char url[MAX_SIZE], weather_data[MAX_SIZE] = {0}, cache_path[MAX_SIZE];
|
||||||
|
const char *cache_dir = getenv("XDG_CACHE_HOME") ?: "/tmp";
|
||||||
|
|
||||||
|
snprintf(url, sizeof(url), "https://wttr.in/%s%s", argv[1], WEATHER_FORMAT);
|
||||||
|
snprintf(cache_path, sizeof(cache_path), "%s/weatherreport", cache_dir);
|
||||||
|
|
||||||
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
|
CURL *curl = curl_easy_init();
|
||||||
|
if (!curl)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, weather_data);
|
||||||
|
|
||||||
|
if (curl_easy_perform(curl) != CURLE_OK) {
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_global_cleanup();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_cleanup(curl);
|
||||||
|
curl_global_cleanup();
|
||||||
|
|
||||||
|
// Remove '+' character
|
||||||
|
for (char *p = weather_data; *p; p++) {
|
||||||
|
if (*p == '+')
|
||||||
|
memmove(p, p + 1, strlen(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp = fopen(cache_path, "w");
|
||||||
|
if (fp) {
|
||||||
|
fputs(weather_data, fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s\n", weather_data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user