#include "a.h" typedef struct DEntry DEntry; struct DEntry { CEntry ce; HTTPHeader hdr; char *tmpfile; int fd; }; static void dfree(CEntry *ce) { DEntry *d; d = (DEntry*)ce; if(d->tmpfile){ remove(d->tmpfile); free(d->tmpfile); close(d->fd); } } static Cache *downloadcache; static char* parseurl(char *url, char **path) { char *host, *p; int len; if(memcmp(url, "http://", 7) != 0) return nil; p = strchr(url+7, '/'); if(p == nil) p = url+strlen(url); len = p - (url+7); host = emalloc(len+1); memmove(host, url+7, len); host[len] = 0; if(*p == 0) p = "/"; *path = p; return host; } int download(char *url, HTTPHeader *hdr) { DEntry *d; char *host, *path; char buf[] = "/var/tmp/smugfs.XXXXXX"; char *req; int fd; Fmt fmt; if(downloadcache == nil) downloadcache = newcache(sizeof(DEntry), 128, dfree); host = parseurl(url, &path); if(host == nil) return -1; d = (DEntry*)cachelookup(downloadcache, url, 1); if(d->tmpfile){ free(host); *hdr = d->hdr; return dup(d->fd, -1); } d->fd = -1; // paranoia if((fd = opentemp(buf, ORDWR|ORCLOSE)) < 0){ free(host); return -1; } fmtstrinit(&fmt); fmtprint(&fmt, "GET %s HTTP/1.0\r\n", path); fmtprint(&fmt, "Host: %s\r\n", host); fmtprint(&fmt, "User-Agent: " USER_AGENT "\r\n"); fmtprint(&fmt, "\r\n"); req = fmtstrflush(&fmt); fprint(2, "Get %s\n", url); if(httptofile(&http, host, req, hdr, fd) < 0){ free(host); free(req); return -1; } free(host); free(req); d->tmpfile = estrdup(buf); d->fd = dup(fd, -1); d->hdr = *hdr; return fd; } void downloadflush(char *substr) { if(downloadcache) cacheflush(downloadcache, substr); }