#include #include #include #include #include #include #include #include #include "save.h" #include "parse.h" static unsigned int fletcher16_file(FILE *); static int item_file_exists(char *); static unsigned int fletcher16_file(FILE *fp) { unsigned int sum1 = 0, sum2 = 0; int c; while ((c = fgetc(fp)) != EOF) { sum1 += (sum1 + c) % 255; sum2 += (sum2 + sum1) % 255; } return (sum2 << 8) | sum1; } /* check if file exists already in cur/ or new/ */ static int item_file_exists(char *filename) { DIR *dp; struct dirent *dir; if ((dp = opendir("cur/"))) { while ((dir = readdir(dp))) { if (strstr(dir->d_name, filename + 4)) { closedir(dp); return 1; } } } closedir(dp); if ((dp = opendir("new/"))) { while ((dir = readdir(dp))) { if (strstr(dir->d_name, filename + 4)) { closedir(dp); return 1; } } } closedir(dp); return 0; } int save_item(struct rss_item item, char *feedtitle) { FILE *fp; static char hostname[256]; char path[512], newpath[512], line[1024]; unsigned int digest; if (gethostname(hostname, sizeof(hostname)) == -1) { perror("failed to get hostname, setting to localhost"); strncpy(hostname, "localhost", sizeof(hostname)); } snprintf(path, sizeof(path), "tmp/%li.rssdl-tmp.%s:2,", item.epochsec, hostname); fp = fopen(path, "w"); if (!fp) { fprintf(stderr, "failed to open %s for writing\n", path); goto CLEANUP; } fprintf(fp, "From: rssdl@%s\n" "Subject: [%s] %s\n" "Date: %s\n" "Content-Type: text/html\n" "\nArticle Link: %s\n\n", hostname, feedtitle, item.title, item.date, item.link); if (item.desc) { while (fgets(line, sizeof(line), item.desc) != NULL) fputs(line, fp); } fclose(fp); fp = fopen(path, "r"); if (!fp) { fprintf(stderr, "failed to open %s for reading\n", path); goto CLEANUP; } digest = fletcher16_file(fp); snprintf(newpath, sizeof(newpath), "new/%li.%x.%s:2,", item.epochsec, digest, hostname); if (item_file_exists(newpath) == 1) goto CLEANUP; if (rename(path, newpath) == 0) puts(newpath); CLEANUP: fclose(fp); unlink(path); return 0; }