#undef _POSIX_C_SOURCE #include #include #include #include #include #include #include #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; }