Blob


1 #include "a.h"
3 typedef struct DEntry DEntry;
4 struct DEntry
5 {
6 CEntry ce;
7 HTTPHeader hdr;
8 char *tmpfile;
9 int fd;
10 };
12 static void
13 dfree(CEntry *ce)
14 {
15 DEntry *d;
17 d = (DEntry*)ce;
18 if(d->tmpfile){
19 remove(d->tmpfile);
20 free(d->tmpfile);
21 close(d->fd);
22 }
23 }
25 static Cache *downloadcache;
27 static char*
28 parseurl(char *url, char **path)
29 {
30 char *host, *p;
31 int len;
33 if(memcmp(url, "http://", 7) != 0)
34 return nil;
35 p = strchr(url+7, '/');
36 if(p == nil)
37 p = url+strlen(url);
38 len = p - (url+7);
39 host = emalloc(len+1);
40 memmove(host, url+7, len);
41 host[len] = 0;
42 if(*p == 0)
43 p = "/";
44 *path = p;
45 return host;
46 }
48 int
49 download(char *url, HTTPHeader *hdr)
50 {
51 DEntry *d;
52 char *host, *path;
53 char buf[] = "/var/tmp/smugfs.XXXXXX";
54 char *req;
55 int fd;
56 Fmt fmt;
58 if(downloadcache == nil)
59 downloadcache = newcache(sizeof(DEntry), 128, dfree);
61 host = parseurl(url, &path);
62 if(host == nil)
63 return -1;
65 d = (DEntry*)cachelookup(downloadcache, url, 1);
66 if(d->tmpfile){
67 free(host);
68 *hdr = d->hdr;
69 return dup(d->fd, -1);
70 }
71 d->fd = -1; // paranoia
73 if((fd = opentemp(buf, ORDWR|ORCLOSE)) < 0){
74 free(host);
75 return -1;
76 }
78 fmtstrinit(&fmt);
79 fmtprint(&fmt, "GET %s HTTP/1.0\r\n", path);
80 fmtprint(&fmt, "Host: %s\r\n", host);
81 fmtprint(&fmt, "User-Agent: " USER_AGENT "\r\n");
82 fmtprint(&fmt, "\r\n");
83 req = fmtstrflush(&fmt);
85 fprint(2, "Get %s\n", url);
87 if(httptofile(&http, host, req, hdr, fd) < 0){
88 free(host);
89 free(req);
90 return -1;
91 }
92 free(host);
93 free(req);
94 d->tmpfile = estrdup(buf);
95 d->fd = dup(fd, -1);
96 d->hdr = *hdr;
97 return fd;
98 }
100 void
101 downloadflush(char *substr)
103 if(downloadcache)
104 cacheflush(downloadcache, substr);