summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..01bc02a
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,163 @@
+#undef _POSIX_C_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdbool.h>
+#include <errno.h>
+
+#define LINE_LENGTH 256
+#define NUM_LENGTH 32
+#define MAX_LINES 64
+#define INIT_BUFFER_LEN 8
+
+static char* get_line(char* buf, int len, FILE* file) {
+ char* ptr = fgets(buf, len, file);
+ if (ptr == NULL) return NULL;
+ buf[strcspn(buf, "\n")] = 0;
+ return ptr;
+}
+
+#define LINE(buf, line) buf + line * LINE_LENGTH
+#define MAX(a, b) a > b ? a : b
+static char* read_logo(FILE* file, uint16_t* height) {
+ uint16_t capacity = INIT_BUFFER_LEN;
+ uint16_t h = 0;
+
+ char* buf = malloc(LINE_LENGTH * capacity);
+ while (h < MAX_LINES && get_line(LINE(buf, h), LINE_LENGTH - 1, file) != NULL) {
+ h++;
+ if (h == capacity) {
+ capacity *= 2;
+ buf = realloc(buf, LINE_LENGTH * capacity);
+ }
+ }
+
+ *height = h;
+ return buf;
+}
+
+static char* read_data(FILE* file, uint16_t* height, uint16_t* offset) {
+ uint16_t capacity = INIT_BUFFER_LEN;
+ uint16_t h = 2, o = 0;
+ char accent_color[NUM_LENGTH], normal_color[NUM_LENGTH], offset_buffer[NUM_LENGTH], title_buffer[LINE_LENGTH];
+
+ char* end;
+ if (get_line(offset_buffer, NUM_LENGTH - 1, file) == NULL) {
+ printf("error: data file missing offset\n");
+ exit(EXIT_FAILURE);
+ }
+ o = strtol(offset_buffer, &end, 10);
+ if (offset_buffer == end) {
+ printf("error: data offset is not a valid numver\n");
+ exit(EXIT_FAILURE);
+ }
+ *offset = o;
+
+ if (get_line(accent_color, NUM_LENGTH - 1, file) == NULL) {
+ printf("error: data file missing accent color\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (get_line(normal_color, NUM_LENGTH - 1, file) == NULL) {
+ printf("error: data file missing normal color\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (get_line(title_buffer, LINE_LENGTH - 1, file) == NULL) {
+ printf("error: data file missing title\n");
+ exit(EXIT_FAILURE);
+ }
+
+ char* buf = malloc(LINE_LENGTH * capacity);
+
+ // funny stuff be goofy ahh'ing here
+ size_t title_len = strlen(title_buffer);
+ snprintf(LINE(buf, 1), LINE_LENGTH, "\x1b[%sm", normal_color);
+ size_t ansi_len = strlen(LINE(buf, 1));
+ memset(LINE(buf, 1) + ansi_len, '~', title_len);
+ (LINE(buf, 1))[title_len + ansi_len] = 0;
+ snprintf(LINE(buf, 0), LINE_LENGTH, "\x1b[%sm%s", accent_color, title_buffer);
+
+ char key[LINE_LENGTH];
+ char value[LINE_LENGTH];
+
+ while(h < MAX_LINES) {
+ if (get_line(key, LINE_LENGTH - 1, file) == NULL) break;
+ if (get_line(value, LINE_LENGTH - 1, file) == NULL) break;
+
+ #pragma GCC diagnostic ignored "-Wformat-truncation"
+ snprintf(LINE(buf, h), LINE_LENGTH, "\x1b[%sm%s\x1b[%sm: %s", accent_color, key, normal_color, value);
+
+ h++;
+ if (h == capacity) {
+ capacity *= 2;
+ buf = realloc(buf, LINE_LENGTH * capacity);
+ }
+ }
+
+ *height = h;
+ return buf;
+}
+
+__attribute__ ((__format__(printf, 1, 2)))
+static FILE* run_command(const char* format, ...) {
+ va_list valist;
+ va_start(valist, format);
+
+ char buf[LINE_LENGTH];
+ vsnprintf(buf, LINE_LENGTH, format, valist);
+
+ FILE* out = popen(buf, "r");
+ if (out == NULL) {
+ printf("error: failed to run command %s: %s\n", buf, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ return out;
+}
+
+static void close_command(FILE* out) {
+ int code = pclose(out);
+ if (code != 0) {
+ printf("error: command errored with exit code %d\n", code);
+ exit(EXIT_FAILURE);
+ }
+}
+
+int main(int argc, char** argv) {
+
+ if (argc != 2) {
+ printf("usage: ritfetch domain\n");
+ return EXIT_FAILURE;
+ }
+
+ FILE* out;
+
+ out = run_command("curl -Lsf %s/.well-known/ritfetch/logo", argv[1]);
+ uint16_t logo_height;
+ char* logo = read_logo(out, &logo_height);
+ close_command(out);
+
+ out = run_command("curl -Lsf %s/.well-known/ritfetch/data", argv[1]);
+ uint16_t data_height, offset;
+ char* data = read_data(out, &data_height, &offset);
+ close_command(out);
+
+ uint16_t max_height = MAX(logo_height, data_height);
+ for (uint16_t i = 0; i < max_height; i++) {
+ if (i < logo_height) {
+ printf("%s", LINE(logo, i));
+ }
+ if (i < data_height) {
+ printf("\x1b[%uG\x1b[m", offset);
+ printf("%s", LINE(data, i));
+ }
+ printf("\n");
+ }
+
+ free(data);
+ free(logo);
+
+ return EXIT_SUCCESS;
+}