commit 0dea7100b0dabcbe8458ad1f913a194fa7ad7e97
parent 99f12d209eb0712cd3b02cf7ca1a146038550d9c
Author: benjamin paul <bpaul@bpaul.xyz>
Date: Thu, 5 Aug 2021 21:32:55 +1000
everything
Diffstat:
M | Makefile | | | 3 | +++ |
M | main.c | | | 166 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 169 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -10,3 +10,6 @@ all: $(NAME)
$(NAME): $(OBJS)
$(CC) $(LDFLAGS) -o $(NAME) $(OBJS)
+
+clean:
+ rm $(OBJS) $(NAME)
diff --git a/main.c b/main.c
@@ -1,10 +1,176 @@
+#include <dirent.h>
+#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+struct links_entry {
+ char *href;
+ int minx, miny;
+ int maxx, maxy;
+};
+
+size_t
+line_count(const char *buf) {
+ const char *ptr = buf;
+ size_t cnt = 0;
+ while (*ptr != '\0') {
+ if (*ptr == '\n') cnt++;
+ ptr++;
+ }
+ return cnt;
+}
+
+size_t
+fsize(FILE *f) {
+ size_t len;
+ fseek(f, 0, SEEK_END);
+ len = ftell(f);
+ fseek(f, 0, SEEK_SET);
+ return len;
+}
+
+char *
+add_path(const char *dir, const char *name) {
+ size_t len = strlen(dir) + strlen(name) + 1;
+ char *buf = malloc(len);
+ memcpy(buf, dir, len);
+
+ strcat(buf, name);
+
+ return buf;
+}
+
+void
+iterate(DIR *d, const char *curdir) {
+ struct dirent *entry;
+
+ /* If the end of the stream is reached, exit.
+ * Errno is reset to determine whether the NULL value means end of stream
+ * of error */
+ errno = 0;
+ if ((entry = readdir(d)) == NULL) {
+ if (errno) {
+ perror("readdir");
+ }
+ return;
+ }
+
+ /* Skip dotfiles */
+ if (entry->d_name[0] == '.') { goto skip; }
+
+ if (entry->d_type == DT_REG) {
+ /* Only want files without file extensions */
+ if (strrchr(entry->d_name, '.') != NULL) { goto skip; }
+
+ char *buf = add_path(curdir, entry->d_name);
+ char *link = add_path(buf, ".links");
+ char *html = add_path(buf, ".html");
+
+ /* Only want files which have a .links file */
+ if (access(link, F_OK) != 0) { goto skip; }
+
+ /* Read the .links file */
+ char *links_buf;
+ size_t len;
+ FILE *linkf = fopen(link, "r");
+ len = fsize(linkf);
+ links_buf = malloc(len);
+ fread(links_buf, 1, len, linkf);
+
+ fclose(linkf);
+
+ size_t entry_cnt;
+ entry_cnt = line_count(links_buf);
+
+ /* Store each entry in the .links file into this struct array */
+ struct links_entry *entries =
+ malloc(sizeof(struct links_entry) * entry_cnt);
+
+ for (size_t i = 0; i < entry_cnt; i++, links_buf = NULL) {
+ entries[i].href = strtok(links_buf, " \n");
+ entries[i].miny = atoi(strtok(NULL, " \n"));
+ entries[i].minx = atoi(strtok(NULL, " \n"));
+ entries[i].maxy = atoi(strtok(NULL, " \n"));
+ entries[i].maxx = atoi(strtok(NULL, " \n"));
+ }
+
+ /* Read ascii file and add links when needed */
+ FILE *f = fopen(buf, "r");
+ char *c = malloc(1);
+ len = fsize(f);
+ int x=1, y=1;
+ int opened = 0;
+ for (size_t j = 0; j < len; j++) {
+ fread(c, 1, 1, f);
+ for (size_t i = 0; i < entry_cnt; i++) {
+ if (y >= entries[i].miny
+ && y <= entries[i].maxy
+ && x == entries[i].minx) {
+ printf("<a href=\"%s\">", entries[i].href);
+ opened = i;
+ } else if (y >= entries[i].miny
+ && y <= entries[i].maxy
+ && x == entries[i].maxx+1) {
+ printf("</a>");
+ opened = 0;
+ }
+ }
+ x++;
+ if (*c == '\n') {
+ if (opened) {
+ while (x <= entries[opened].maxx+1) { putchar(' '); x++; }
+ printf("</a>");
+ }
+ x=1; y++;
+ }
+ putchar(*c);
+ }
+
+ free(buf);
+ free(link);
+ free(links_buf);
+ } else if (entry->d_type == DT_DIR) {
+ /* For directories, reiterate */
+
+ /* Create a string that appends the directory name to the current
+ * directory name */
+ char *buf = add_path(curdir, entry->d_name);
+ strcat(buf, "/");
+
+ DIR *newd;
+ if ((newd = opendir((buf))) == NULL) {
+ perror("opendir");
+ return;
+ }
+
+ /* Iterate */
+ iterate(newd, buf);
+
+ free(buf);
+ }
+skip:
+ seekdir(d, entry->d_off);
+ iterate(d, curdir);
+}
int
main(int argc, char **argv) {
if (argc < 2) {
puts("Please specify a directory");
+ exit(0);
+ }
+
+ DIR *d;
+
+ if ((d = opendir(argv[1])) == NULL) {
+ puts("That is not a valid directory");
+ exit(0);
}
+ strcat(argv[1], "/");
+ iterate(d, argv[1]);
return 0;
}