commit 4ae2d93217cddfe7630d3f2f989cffc7028c8e98
parent e5d21c3fdff551b74a46fba6f2d3f5359e4324df
Author: amrfti <andrew@kloet.net>
Date: Mon, 19 Jan 2026 12:39:58 -0500
POSIX c99
Diffstat:
4 files changed, 72 insertions(+), 43 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
CC = cc
-CFLAGS = -Wall -Wextra -O3
+CFLAGS = -Wall -Wextra -pedantic -std=c99 -O3
CURL_LIBS = -lcurl
SOURCES = vidir.c sb-cpu.c sb-date.c sb-memory.c sb-time.c sb-weather.c sb-battery.c
diff --git a/sb-time.c b/sb-time.c
@@ -5,7 +5,7 @@ int main() {
time_t t = time(NULL);
char time_str[10];
- strftime(time_str, sizeof(time_str), "%I:%M%P", localtime(&t));
+ strftime(time_str, sizeof(time_str), "%I:%M%p", localtime(&t));
printf("%s\n", time_str);
return 0;
}
diff --git a/sb-weather.c b/sb-weather.c
@@ -18,7 +18,8 @@ int main(int argc, char *argv[]) {
}
char url[MAX_SIZE], weather_data[MAX_SIZE] = {0}, cache_path[MAX_SIZE];
- const char *cache_dir = getenv("XDG_CACHE_HOME") ?: "/tmp";
+ const char *cache_dir =
+ getenv("XDG_CACHE_HOME") ? 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);
diff --git a/vidir.c b/vidir.c
@@ -1,5 +1,9 @@
-// vidir.c - rewrite of Joey Hess's vidir in C
-// usage: ./vidir [--verbose] [dir|file|-]
+/*
+ * vidir.c - rewrite of Joey Hess's vidir in C
+ * usage: ./vidir [--verbose] [dir|file|-]
+ */
+
+#define _XOPEN_SOURCE 700
#include <ctype.h>
#include <dirent.h>
@@ -29,13 +33,22 @@ void die(const char *msg) {
exit(1);
}
+char *my_strdup(const char *s) {
+ size_t len = strlen(s) + 1;
+ char *new = malloc(len);
+ if (new) {
+ memcpy(new, s, len);
+ }
+ return new;
+}
+
void add_item(const char *path) {
if (n_items >= MAX_FILES) {
fprintf(stderr, "too many files\n");
exit(1);
}
items[n_items].id = n_items + 1;
- items[n_items].path = strdup(path);
+ items[n_items].path = my_strdup(path);
n_items++;
}
@@ -103,7 +116,7 @@ int main(int argc, char *argv[]) {
if (n_items == 0)
read_dir(".");
- // write numbered list
+ /* Write numbered list */
fd = mkstemp(tmpname);
if (fd < 0)
die("mkstemp");
@@ -115,7 +128,7 @@ int main(int argc, char *argv[]) {
fprintf(tmp, "%0*d\t%s\n", digits, items[i].id, items[i].path);
fclose(tmp);
- // pick editor
+ /* Pick editor */
editor = getenv("VISUAL");
if (!editor)
editor = getenv("EDITOR");
@@ -130,7 +143,9 @@ int main(int argc, char *argv[]) {
exit(1);
}
- // re-read edited list
+ int seen[MAX_FILES] = {0};
+
+ /* Re-read edited list */
tmp = fopen(tmpname, "r");
if (!tmp)
die("fopen tmp");
@@ -140,66 +155,79 @@ int main(int argc, char *argv[]) {
line[strcspn(line, "\r\n")] = 0;
if (strlen(line) == 0)
continue;
+
int num;
if (sscanf(line, "%d%[^\n]", &num, newname) < 1)
continue;
+
+ if (num <= 0 || num > n_items)
+ continue;
+
+ /* Mark this file as still existing in the list */
+ seen[num - 1] = 1;
+
char *p = newname;
while (isspace((unsigned char)*p))
p++;
- if (num <= 0 || num > n_items)
- continue;
+
char *old = items[num - 1].path;
- if (*p == '\0') {
- // deleted line -> remove file
- if (rm_path(old) != 0) {
- fprintf(stderr, "failed to remove %s: %s\n", old, strerror(errno));
- error_flag = 1;
- } else if (verbose) {
- printf("removed '%s'\n", old);
- }
- } else if (strcmp(p, old) != 0) {
- // rename
+
+ /* Logic for renaming */
+ if (strcmp(p, old) != 0) {
char dirbuf[PATH_MAX];
- strlcpy(dirbuf, p, sizeof(dirbuf));
+ strncpy(dirbuf, p, sizeof(dirbuf) - 1);
+ dirbuf[sizeof(dirbuf) - 1] = '\0';
char *d = dirname(dirbuf);
mkdir(d, 0777);
+
+ /* Handle collisions */
if (access(p, F_OK) == 0) {
- char tmpname[PATH_MAX + 16]; // allow space for suffixes
+ char collision_tmp[PATH_MAX + 16];
int suffix = 0;
- snprintf(tmpname, sizeof(tmpname), "%s~", p);
- while (access(tmpname, F_OK) == 0) {
+ snprintf(collision_tmp, sizeof(collision_tmp), "%s~", p);
+ while (access(collision_tmp, F_OK) == 0) {
suffix++;
- snprintf(tmpname, sizeof(tmpname), "%s~%d", p, suffix);
+ snprintf(collision_tmp, sizeof(collision_tmp), "%s~%d", p, suffix);
}
- if (rename(p, tmpname) != 0) {
- fprintf(stderr, "failed to rename '%s' -> '%s': %s\n", p, tmpname,
- strerror(errno));
- error_flag = 1;
- } else if (verbose) {
- printf("renamed '%s' -> '%s'\n", p, tmpname);
- }
- // update internal mapping so future renames see the new tmp location
- for (int j = 0; j < n_items; j++) {
- if (strcmp(items[j].path, p) == 0) {
- free(items[j].path);
- items[j].path = strdup(tmpname);
+ if (rename(p, collision_tmp) == 0) {
+ if (verbose)
+ printf("collision: renamed '%s' -> '%s'\n", p, collision_tmp);
+ for (int j = 0; j < n_items; j++) {
+ if (strcmp(items[j].path, p) == 0) {
+ free(items[j].path);
+ items[j].path = my_strdup(collision_tmp);
+ }
}
}
}
- // now perform the intended rename
if (rename(old, p) != 0) {
fprintf(stderr, "failed to rename %s -> %s: %s\n", old, p,
strerror(errno));
error_flag = 1;
- } else if (verbose) {
- printf("renamed '%s' -> '%s'\n", old, p);
+ } else {
+ if (verbose)
+ printf("renamed '%s' -> '%s'\n", old, p);
+ free(items[num - 1].path);
+ items[num - 1].path = my_strdup(p);
}
- free(items[num - 1].path);
- items[num - 1].path = strdup(p);
}
}
fclose(tmp);
+
+ /* Delete files that were not in the edited file */
+ for (int i = 0; i < n_items; i++) {
+ if (!seen[i]) {
+ if (rm_path(items[i].path) != 0) {
+ fprintf(stderr, "failed to remove %s: %s\n", items[i].path,
+ strerror(errno));
+ error_flag = 1;
+ } else if (verbose) {
+ printf("removed '%s'\n", items[i].path);
+ }
+ }
+ }
+
unlink(tmpname);
return error_flag;
}