sfeed

Simple RSS and Atom feed parser
git clone https://git.sinitax.com/codemadness/sfeed
Log | Files | Refs | README | LICENSE | Upstream | sfeed.txt

commit 5a5f26540bf525d23b4650e0b558e0cdaedcd396
parent 068a4dec639ab6a9b270785d605bef4b0abcec91
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Wed, 24 Apr 2019 21:00:55 +0200

sfeed_mbox: use simpler djb2 hash, fix message-id as intended

The message-id has not been working as intended for a while. It only hashed the
timestamp field because parseline() modifies the buffer in-place.

Diffstat:
Msfeed_mbox.c | 65+++++++++--------------------------------------------------------
1 file changed, 9 insertions(+), 56 deletions(-)

diff --git a/sfeed_mbox.c b/sfeed_mbox.c @@ -1,7 +1,4 @@ -#include <sys/types.h> - #include <err.h> -#include <inttypes.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> @@ -14,59 +11,14 @@ static char *line; static size_t linesize; static char host[256], *user, mtimebuf[32]; -static const uint32_t seed = 1167266473; - -#define ROT32(x, y) ((x << y) | (x >> (32 - y))) -static uint32_t -murmur3_32(const char *key, uint32_t len, uint32_t seed) +static unsigned long +djb2(unsigned char *s, unsigned long hash) { - static const uint32_t c1 = 0xcc9e2d51; - static const uint32_t c2 = 0x1b873593; - static const uint32_t r1 = 15; - static const uint32_t r2 = 13; - static const uint32_t m = 5; - static const uint32_t n = 0xe6546b64; - uint32_t hash = seed; - const int nblocks = len / 4; - const uint32_t *blocks = (const uint32_t *) key; - int i; - uint32_t k, k1; - const uint8_t *tail; - - for (i = 0; i < nblocks; i++) { - k = blocks[i]; - k *= c1; - k = ROT32(k, r1); - k *= c2; - - hash ^= k; - hash = ROT32(hash, r2) * m + n; - } - tail = (const uint8_t *) (key + nblocks * 4); - - k1 = 0; - switch (len & 3) { - case 3: - k1 ^= tail[2] << 16; - case 2: - k1 ^= tail[1] << 8; - case 1: - k1 ^= tail[0]; - - k1 *= c1; - k1 = ROT32(k1, r1); - k1 *= c2; - hash ^= k1; - } - - hash ^= len; - hash ^= (hash >> 16); - hash *= 0x85ebca6b; - hash ^= (hash >> 13); - hash *= 0xc2b2ae35; - hash ^= (hash >> 16); + int c; + while ((c = *s++)) + hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ return hash; } @@ -76,11 +28,13 @@ printfeed(FILE *fp, const char *feedname) struct tm tm; char *fields[FieldLast], timebuf[32]; time_t parsedtime; + unsigned long hash; ssize_t linelen; while ((linelen = getline(&line, &linesize, fp)) > 0) { if (line[linelen - 1] == '\n') line[--linelen] = '\0'; + hash = djb2((unsigned char *)line, 5381UL); if (!parseline(line, fields)) break; parsedtime = 0; @@ -103,11 +57,10 @@ printfeed(FILE *fp, const char *feedname) printf("Subject: [%s] %s\n", feedname, fields[FieldTitle]); else printf("Subject: %s\n", fields[FieldTitle]); - printf("Message-ID: <%s%s%"PRIu32"@%s>\n", + printf("Message-ID: <%s%s%lu@%s>\n", fields[FieldUnixTimestamp], fields[FieldUnixTimestamp][0] ? "." : "", - murmur3_32(line, (size_t)linelen, seed), - feedname); + hash, feedname); printf("Content-Type: text/plain; charset=\"utf-8\"\n"); printf("Content-Transfer-Encoding: binary\n"); printf("X-Feedname: %s\n\n", feedname);