115 lines
2.2 KiB
C
115 lines
2.2 KiB
C
|
#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;
|
||
|
}
|