plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

download.c (1671B)


      1 #include "a.h"
      2 
      3 typedef struct DEntry DEntry;
      4 struct DEntry
      5 {
      6 	CEntry ce;
      7 	HTTPHeader hdr;
      8 	char *tmpfile;
      9 	int fd;
     10 };
     11 
     12 static void
     13 dfree(CEntry *ce)
     14 {
     15 	DEntry *d;
     16 
     17 	d = (DEntry*)ce;
     18 	if(d->tmpfile){
     19 		remove(d->tmpfile);
     20 		free(d->tmpfile);
     21 		close(d->fd);
     22 	}
     23 }
     24 
     25 static Cache *downloadcache;
     26 
     27 static char*
     28 parseurl(char *url, char **path)
     29 {
     30 	char *host, *p;
     31 	int len;
     32 
     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 }
     47 
     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;
     57 
     58 	if(downloadcache == nil)
     59 		downloadcache = newcache(sizeof(DEntry), 128, dfree);
     60 
     61 	host = parseurl(url, &path);
     62 	if(host == nil)
     63 		return -1;
     64 
     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
     72 
     73 	if((fd = opentemp(buf, ORDWR|ORCLOSE)) < 0){
     74 		free(host);
     75 		return -1;
     76 	}
     77 
     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);
     84 
     85 	fprint(2, "Get %s\n", url);
     86 
     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 }
     99 
    100 void
    101 downloadflush(char *substr)
    102 {
    103 	if(downloadcache)
    104 		cacheflush(downloadcache, substr);
    105 }