002
2022-01-10
op
* Copyright (c) 2022 Omar Polo <op@omarpolo.com>
004
2022-01-10
op
* Permission to use, copy, modify, and distribute this software for any
005
2022-01-10
op
* purpose with or without fee is hereby granted, provided that the above
006
2022-01-10
op
* copyright notice and this permission notice appear in all copies.
008
2022-01-10
op
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
009
2022-01-10
op
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
010
2022-01-10
op
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
011
2022-01-10
op
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
012
2022-01-10
op
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
013
2022-01-10
op
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
014
2022-01-10
op
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
017
2022-01-10
op
#include "compat.h"
019
2022-01-10
op
#include <stdlib.h>
020
2022-01-10
op
#include <stdint.h>
021
2022-01-10
op
#include <string.h>
023
2022-01-10
op
#include "telescope.h"
024
2022-01-10
op
#include "mcache.h"
025
2022-01-11
op
#include "parser.h"
026
2022-01-11
op
#include "utils.h"
028
2022-01-12
op
static struct timeval tv = { 5 * 60, 0 };
029
2022-01-11
op
static struct event timerev;
031
2022-01-11
op
static struct ohash h;
032
2022-01-11
op
static size_t npages;
033
2022-01-11
op
static size_t tot;
035
2022-01-10
op
struct mcache_entry {
036
2022-01-11
op
time_t ts;
037
2022-01-19
op
parserfn parser;
038
2022-01-10
op
int trust;
039
2022-04-13
op
char *buf;
040
2022-04-13
op
size_t buflen;
041
2022-01-10
op
char url[];
044
2022-01-11
op
static void
045
2022-01-11
op
mcache_free_entry(const char *url)
047
2022-01-11
op
struct mcache_entry *e;
048
2022-01-11
op
unsigned int slot;
050
2022-01-11
op
slot = ohash_qlookup(&h, url);
051
2022-01-11
op
if ((e = ohash_remove(&h, slot)) == NULL)
054
2022-01-11
op
npages--;
055
2022-04-13
op
tot -= e->buflen;
057
2022-04-13
op
free(e->buf);
061
2022-01-11
op
static void
062
2022-01-11
op
clean_old_entries(int fd, short ev, void *data)
064
2022-01-11
op
struct mcache_entry *e;
065
2022-01-11
op
unsigned int i;
066
2022-01-11
op
time_t treshold;
068
2022-01-12
op
/* delete pages older than an hour */
069
2022-01-12
op
treshold = time(NULL) - 60 * 60;
071
2022-01-11
op
for (e = ohash_first(&h, &i); e != NULL; e = ohash_next(&h, &i))
072
2022-01-11
op
if (e->ts < treshold)
073
2022-01-11
op
mcache_free_entry(e->url);
075
2022-01-11
op
evtimer_add(&timerev, &tv);
079
2022-01-10
op
mcache_init(void)
081
2022-01-10
op
struct ohash_info info = {
082
2022-01-10
op
.key_offset = offsetof(struct mcache_entry, url),
083
2022-01-10
op
.calloc = hash_calloc,
084
2022-01-10
op
.free = hash_free,
085
2022-01-10
op
.alloc = hash_alloc,
088
2022-01-11
op
ohash_init(&h, 5, &info);
090
2022-01-11
op
evtimer_set(&timerev, clean_old_entries, NULL);
094
2022-01-11
op
mcache_tab(struct tab *tab)
096
2022-01-10
op
struct mcache_entry *e;
097
2022-01-10
op
unsigned int slot;
098
2022-01-10
op
size_t l, len;
099
2022-01-11
op
const char *url;
100
2022-04-13
op
FILE *fp;
102
2022-01-11
op
url = tab->hist_cur->h;
103
2022-01-10
op
l = strlen(url);
104
2022-01-10
op
len = sizeof(*e) + l + 1;
106
2022-01-10
op
if ((e = calloc(1, len)) == NULL)
107
2022-01-10
op
return -1;
108
2022-01-11
op
e->ts = time(NULL);
109
2022-01-19
op
e->parser = tab->buffer.page.init;
110
2022-01-11
op
e->trust = tab->trust;
111
2022-01-10
op
memcpy(e->url, url, l);
113
2022-04-13
op
if ((fp = open_memstream(&e->buf, &e->buflen)) == NULL)
114
2022-01-10
op
goto err;
116
2022-04-13
op
if (!parser_serialize(tab, fp))
117
2022-01-19
op
goto err;
119
2022-04-13
op
fclose(fp);
121
2022-01-11
op
/* free any previously cached copies of this page */
122
2022-01-11
op
mcache_free_entry(url);
124
2022-01-11
op
slot = ohash_qlookup(&h, url);
125
2022-01-11
op
ohash_insert(&h, slot, e);
127
2022-01-11
op
npages++;
128
2022-04-13
op
tot += e->buflen;
130
2022-01-11
op
if (!evtimer_pending(&timerev, NULL))
131
2022-01-11
op
evtimer_add(&timerev, &tv);
133
2022-01-10
op
return 0;
136
2022-04-13
op
if (fp != NULL)
137
2022-04-13
op
fclose(fp);
138
2022-04-13
op
if (e->buf != NULL)
139
2022-04-13
op
free(e->buf);
141
2022-01-10
op
return -1;
145
2022-01-11
op
mcache_lookup(const char *url, struct tab *tab)
147
2022-01-10
op
struct mcache_entry *e;
148
2022-01-10
op
unsigned int slot;
150
2022-01-11
op
slot = ohash_qlookup(&h, url);
151
2022-01-11
op
if ((e = ohash_find(&h, slot)) == NULL)
152
2022-01-10
op
return 0;
154
2022-01-19
op
parser_init(tab, e->parser);
155
2022-04-13
op
if (!parser_parse(tab, e->buf, e->buflen))
156
2022-01-11
op
goto err;
157
2022-01-11
op
if (!parser_free(tab))
158
2022-01-11
op
goto err;
160
2022-01-11
op
tab->trust = e->trust;
161
2022-01-10
op
return 1;
164
2022-01-11
op
parser_free(tab);
165
2022-01-11
op
erase_buffer(&tab->buffer);
166
2022-01-11
op
return 0;
170
2022-01-11
op
mcache_info(size_t *r_npages, size_t *r_tot)
172
2022-01-11
op
*r_npages = npages;
173
2022-01-11
op
*r_tot = tot;