rssdl/save.c

115 lines
2.2 KiB
C
Raw Permalink Normal View History

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#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;
}