aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/smugfs/download.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@swtch.com>2008-08-03 07:42:27 -0700
committerRuss Cox <rsc@swtch.com>2008-08-03 07:42:27 -0700
commit18824b586835525594cde126fbc90b8281d5af8b (patch)
treee8b69c05eda4543b6d2f3d30777abe6109b48b7f /src/cmd/smugfs/download.c
parent3d36f4437348227c5bad62587dc12b5fd4a3e95e (diff)
downloadplan9port-18824b586835525594cde126fbc90b8281d5af8b.tar.gz
plan9port-18824b586835525594cde126fbc90b8281d5af8b.tar.bz2
plan9port-18824b586835525594cde126fbc90b8281d5af8b.zip
smugfs(4): new program
Diffstat (limited to 'src/cmd/smugfs/download.c')
-rw-r--r--src/cmd/smugfs/download.c105
1 files changed, 105 insertions, 0 deletions
diff --git a/src/cmd/smugfs/download.c b/src/cmd/smugfs/download.c
new file mode 100644
index 00000000..e23d49e1
--- /dev/null
+++ b/src/cmd/smugfs/download.c
@@ -0,0 +1,105 @@
+#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);
+}