#include #include #include #include #include #include #include #include #include #include #include "gemlog.h" static int find_latest_year(struct gemlog_entry **feed) { int i; int ret; ret = 0; for (i = 0; feed[i] != NULL; i++) { if (feed[i]->date.tm_year > ret) ret = feed[i]->date.tm_year; } return ret; } static int find_latest_month(struct gemlog_entry **feed, int year) { int i; int ret; ret = 0; for (i = 0; feed[i] != NULL; i++) { if (feed[i]->date.tm_year == year) { if (feed[i]->date.tm_mon > ret) ret = feed[i]->date.tm_mon; } } return ret; } static int find_latest_day(struct gemlog_entry **feed, int year, int month) { int i; int ret; ret = 0; for (i = 0; feed[i] != NULL; i++) { if (feed[i]->date.tm_year == year && feed[i]->date.tm_mon == month) { if (feed[i]->date.tm_mday > ret) ret = feed[i]->date.tm_mday; } } return ret; } static int find_latest_hour(struct gemlog_entry **feed, int year, int month, int day) { int i; int ret; ret = 0; for (i = 0; feed[i] != NULL; i++) { if (feed[i]->date.tm_year == year && feed[i]->date.tm_mon == month && feed[i]->date.tm_mday == day) { if (feed[i]->date.tm_hour > ret) ret = feed[i]->date.tm_hour; } } return ret; } static int gemlog_write_index_hour(struct gemlog_entry **feed, int fd, int year, int month, int day, int hour) { int i; int labellen; char *labelbuf; char timestamp[11]; /* 1990-01-01\0 */ char pathbuf[PATH_MAX+1]; struct gemtext *out; labellen = 0; for (i = 0; feed[i] != NULL; i++) { if (feed[i]->date.tm_year == year && feed[i]->date.tm_mon == month && feed[i]->date.tm_mday == day && feed[i]->date.tm_hour == hour) { strftime(timestamp, sizeof(timestamp), "%F", &(feed[i]->date)); labellen += strlen(timestamp); labellen += 2; /* ": " */ labellen += strlen(feed[i]->title); labelbuf = malloc(labellen+1); if (labelbuf == NULL) return -1; strlcpy(labelbuf, timestamp, labellen+1); strlcat(labelbuf, ": ", labellen+1); strlcat(labelbuf, feed[i]->title, labellen+1); snprintf(pathbuf, sizeof(pathbuf), "%d/%d/%d/%d/%s", year+1900, month+1, day, hour, GEMLOG_CONTENT_FILENAME); out = gemtext_link_new(pathbuf, labelbuf); free(labelbuf); if (out == NULL) return -1; if (gemtext_encode_fd(out, fd) == -1) { gemtext_free(out); return -1; } gemtext_free(out); if (write(fd, "\n", strlen("\n")) == -1) return -1; } } return 0; } static int gemlog_write_index_day(struct gemlog_entry **feed, int fd, int year, int month, int day) { int hour; for (hour = find_latest_hour(feed, year, month, day); hour != 0; hour--) { if (gemlog_write_index_hour(feed, fd, year, month, day, hour) == -1) return -1; } return 0; } static int gemlog_write_index_month(struct gemlog_entry **feed, int fd, int year, int month) { int day; for (day = find_latest_day(feed, year, month); day != 0; day--) { if (gemlog_write_index_day(feed, fd, year, month, day) == -1) return -1; } return 0; } static int gemlog_write_index_year(struct gemlog_entry **feed, int fd, int year) { int month; for (month = find_latest_month(feed, year); month != 0; month--) { if (gemlog_write_index_month(feed, fd, year, month) == -1) return -1; } return 0; } int gemlog_write_index(struct gemlog_entry **feed, const char *path) { int year; int fd; fd = open(path, O_WRONLY|O_CREAT|O_TRUNC); if (fd == -1) return -1; if (chmod(path, 0644) == -1) { close(fd); return -1; } for (year = find_latest_year(feed); year != 0; year--) { if (gemlog_write_index_year(feed, fd, year) == -1) { close(fd); return -1; } } close(fd); return 0; }