Blame


1 18824b58 2008-08-03 rsc #include "a.h"
2 18824b58 2008-08-03 rsc
3 18824b58 2008-08-03 rsc // This code is almost certainly wrong.
4 18824b58 2008-08-03 rsc
5 18824b58 2008-08-03 rsc typedef struct Icache Icache;
6 18824b58 2008-08-03 rsc struct Icache
7 18824b58 2008-08-03 rsc {
8 18824b58 2008-08-03 rsc char *url;
9 18824b58 2008-08-03 rsc HTTPHeader hdr;
10 18824b58 2008-08-03 rsc char *tmpfile;
11 18824b58 2008-08-03 rsc int fd;
12 18824b58 2008-08-03 rsc Icache *next;
13 18824b58 2008-08-03 rsc Icache *prev;
14 18824b58 2008-08-03 rsc Icache *hash;
15 18824b58 2008-08-03 rsc };
16 18824b58 2008-08-03 rsc
17 18824b58 2008-08-03 rsc enum {
18 18824b58 2008-08-03 rsc NHASH = 128,
19 18824b58 2008-08-03 rsc MAXCACHE = 128,
20 18824b58 2008-08-03 rsc };
21 18824b58 2008-08-03 rsc static struct {
22 18824b58 2008-08-03 rsc Icache *hash[NHASH];
23 18824b58 2008-08-03 rsc Icache *head;
24 18824b58 2008-08-03 rsc Icache *tail;
25 18824b58 2008-08-03 rsc int n;
26 18824b58 2008-08-03 rsc } icache;
27 18824b58 2008-08-03 rsc
28 18824b58 2008-08-03 rsc static Icache*
29 18824b58 2008-08-03 rsc icachefind(char *url)
30 18824b58 2008-08-03 rsc {
31 18824b58 2008-08-03 rsc int h;
32 18824b58 2008-08-03 rsc Icache *ic;
33 18824b58 2008-08-03 rsc
34 18824b58 2008-08-03 rsc h = hash(url) % NHASH;
35 18824b58 2008-08-03 rsc for(ic=icache.hash[h]; ic; ic=ic->hash){
36 18824b58 2008-08-03 rsc if(strcmp(ic->url, url) == 0){
37 18824b58 2008-08-03 rsc /* move to front */
38 18824b58 2008-08-03 rsc if(ic->prev) {
39 18824b58 2008-08-03 rsc ic->prev->next = ic->next;
40 18824b58 2008-08-03 rsc if(ic->next)
41 18824b58 2008-08-03 rsc ic->next->prev = ic->prev;
42 18824b58 2008-08-03 rsc else
43 18824b58 2008-08-03 rsc icache.tail = ic->prev;
44 18824b58 2008-08-03 rsc ic->prev = nil;
45 18824b58 2008-08-03 rsc ic->next = icache.head;
46 18824b58 2008-08-03 rsc icache.head->prev = ic;
47 18824b58 2008-08-03 rsc icache.head = ic;
48 18824b58 2008-08-03 rsc }
49 18824b58 2008-08-03 rsc return ic;
50 18824b58 2008-08-03 rsc }
51 18824b58 2008-08-03 rsc }
52 18824b58 2008-08-03 rsc return nil;
53 18824b58 2008-08-03 rsc }
54 18824b58 2008-08-03 rsc
55 18824b58 2008-08-03 rsc static Icache*
56 18824b58 2008-08-03 rsc icacheinsert(char *url, HTTPHeader *hdr, char *file, int fd)
57 18824b58 2008-08-03 rsc {
58 18824b58 2008-08-03 rsc int h;
59 18824b58 2008-08-03 rsc Icache *ic, **l;
60 18824b58 2008-08-03 rsc
61 18824b58 2008-08-03 rsc if(icache.n == MAXCACHE){
62 18824b58 2008-08-03 rsc ic = icache.tail;
63 18824b58 2008-08-03 rsc icache.tail = ic->prev;
64 18824b58 2008-08-03 rsc if(ic->prev)
65 18824b58 2008-08-03 rsc ic->prev->next = nil;
66 18824b58 2008-08-03 rsc else
67 18824b58 2008-08-03 rsc icache.head = ic->prev;
68 18824b58 2008-08-03 rsc h = hash(ic->url) % NHASH;
69 18824b58 2008-08-03 rsc for(l=&icache.hash[h]; *l; l=&(*l)->hash){
70 18824b58 2008-08-03 rsc if(*l == ic){
71 18824b58 2008-08-03 rsc *l = ic->hash;
72 18824b58 2008-08-03 rsc goto removed;
73 18824b58 2008-08-03 rsc }
74 18824b58 2008-08-03 rsc }
75 18824b58 2008-08-03 rsc sysfatal("cannot find ic in cache");
76 18824b58 2008-08-03 rsc removed:
77 18824b58 2008-08-03 rsc free(ic->url);
78 18824b58 2008-08-03 rsc close(ic->fd);
79 18824b58 2008-08-03 rsc remove(ic->file);
80 18824b58 2008-08-03 rsc free(ic->file);
81 18824b58 2008-08-03 rsc }else{
82 18824b58 2008-08-03 rsc ic = emalloc(sizeof *ic);
83 18824b58 2008-08-03 rsc icache.n++;
84 18824b58 2008-08-03 rsc }
85 18824b58 2008-08-03 rsc
86 18824b58 2008-08-03 rsc ic->url = estrdup(url);
87 18824b58 2008-08-03 rsc ic->fd = dup(fd, -1);
88 18824b58 2008-08-03 rsc ic->file = estrdup(file);
89 18824b58 2008-08-03 rsc ic->hdr = *hdr;
90 18824b58 2008-08-03 rsc h = hash(url) % NHASH;
91 18824b58 2008-08-03 rsc ic->hash = icache.hash[h];
92 18824b58 2008-08-03 rsc icache.hash[h] = ic;
93 18824b58 2008-08-03 rsc ic->prev = nil;
94 18824b58 2008-08-03 rsc ic->next = icache.head;
95 18824b58 2008-08-03 rsc if(ic->next)
96 18824b58 2008-08-03 rsc ic->next->prev = ic;
97 18824b58 2008-08-03 rsc else
98 18824b58 2008-08-03 rsc icache.tail = ic;
99 18824b58 2008-08-03 rsc return ic;
100 18824b58 2008-08-03 rsc }
101 18824b58 2008-08-03 rsc
102 18824b58 2008-08-03 rsc void
103 18824b58 2008-08-03 rsc icacheflush(char *substr)
104 18824b58 2008-08-03 rsc {
105 18824b58 2008-08-03 rsc Icache **l, *ic;
106 18824b58 2008-08-03 rsc
107 18824b58 2008-08-03 rsc for(l=&icache.head; (ic=*l); ) {
108 18824b58 2008-08-03 rsc if(substr == nil || strstr(ic->url, substr)) {
109 18824b58 2008-08-03 rsc icache.n--;
110 18824b58 2008-08-03 rsc *l = ic->next;
111 18824b58 2008-08-03 rsc free(ic->url);
112 18824b58 2008-08-03 rsc close(ic->fd);
113 18824b58 2008-08-03 rsc remove(ic->file);
114 18824b58 2008-08-03 rsc free(ic->file);
115 18824b58 2008-08-03 rsc free(ic);
116 18824b58 2008-08-03 rsc }else
117 18824b58 2008-08-03 rsc l = &ic->next;
118 18824b58 2008-08-03 rsc }
119 18824b58 2008-08-03 rsc
120 18824b58 2008-08-03 rsc if(icache.head) {
121 18824b58 2008-08-03 rsc icache.head->prev = nil;
122 18824b58 2008-08-03 rsc for(ic=icache.head; ic; ic=ic->next){
123 18824b58 2008-08-03 rsc if(ic->next)
124 18824b58 2008-08-03 rsc ic->next->prev = ic;
125 18824b58 2008-08-03 rsc else
126 18824b58 2008-08-03 rsc icache.tail = ic;
127 18824b58 2008-08-03 rsc }
128 18824b58 2008-08-03 rsc }else
129 18824b58 2008-08-03 rsc icache.tail = nil;
130 18824b58 2008-08-03 rsc }
131 18824b58 2008-08-03 rsc
132 18824b58 2008-08-03 rsc int
133 18824b58 2008-08-03 rsc urlfetch(char *url, HTTPHeader hdr)
134 18824b58 2008-08-03 rsc {
135 18824b58 2008-08-03 rsc Icache *ic;
136 18824b58 2008-08-03 rsc char buf[50], *host, *path, *p;
137 18824b58 2008-08-03 rsc int fd, len;
138 18824b58 2008-08-03 rsc
139 18824b58 2008-08-03 rsc ic = icachefind(url);
140 18824b58 2008-08-03 rsc if(ic != nil){
141 18824b58 2008-08-03 rsc *hdr = ic->hdr;
142 18824b58 2008-08-03 rsc return dup(ic->fd, -1);
143 18824b58 2008-08-03 rsc }
144 18824b58 2008-08-03 rsc
145 18824b58 2008-08-03 rsc if(memcmp(url, "http://", 7) != 0){
146 18824b58 2008-08-03 rsc werrstr("non-http url");
147 18824b58 2008-08-03 rsc return -1;
148 18824b58 2008-08-03 rsc }
149 18824b58 2008-08-03 rsc p = strchr(url+7, '/');
150 18824b58 2008-08-03 rsc if(p == nil)
151 18824b58 2008-08-03 rsc p = url+strlen(url);
152 18824b58 2008-08-03 rsc len = p - (url+7);
153 18824b58 2008-08-03 rsc host = emalloc(len+1);
154 18824b58 2008-08-03 rsc memmove(host, url+7, len);
155 18824b58 2008-08-03 rsc host[len] = 0;
156 18824b58 2008-08-03 rsc if(*p == 0)
157 18824b58 2008-08-03 rsc p = "/";
158 18824b58 2008-08-03 rsc
159 18824b58 2008-08-03 rsc strcpy(buf, "/var/tmp/smugfs.XXXXXX");
160 18824b58 2008-08-03 rsc fd = opentemp(buf, ORDWR|ORCLOSE);
161 18824b58 2008-08-03 rsc if(fd < 0)
162 18824b58 2008-08-03 rsc return -1;
163 18824b58 2008-08-03 rsc if(httptofile(http, host, req, &hdr, fd) < 0){
164 18824b58 2008-08-03 rsc free(host);
165 18824b58 2008-08-03 rsc return -1;
166 18824b58 2008-08-03 rsc }
167 18824b58 2008-08-03 rsc free(host);
168 18824b58 2008-08-03 rsc icacheinsert(url, &hdr, buf, fd);
169 18824b58 2008-08-03 rsc return fd;
170 18824b58 2008-08-03 rsc }
171 18824b58 2008-08-03 rsc