smugfs(4): new program
This commit is contained in:
parent
3d36f44373
commit
18824b5868
17 changed files with 4299 additions and 0 deletions
171
src/cmd/smugfs/icache.c
Normal file
171
src/cmd/smugfs/icache.c
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
#include "a.h"
|
||||
|
||||
// This code is almost certainly wrong.
|
||||
|
||||
typedef struct Icache Icache;
|
||||
struct Icache
|
||||
{
|
||||
char *url;
|
||||
HTTPHeader hdr;
|
||||
char *tmpfile;
|
||||
int fd;
|
||||
Icache *next;
|
||||
Icache *prev;
|
||||
Icache *hash;
|
||||
};
|
||||
|
||||
enum {
|
||||
NHASH = 128,
|
||||
MAXCACHE = 128,
|
||||
};
|
||||
static struct {
|
||||
Icache *hash[NHASH];
|
||||
Icache *head;
|
||||
Icache *tail;
|
||||
int n;
|
||||
} icache;
|
||||
|
||||
static Icache*
|
||||
icachefind(char *url)
|
||||
{
|
||||
int h;
|
||||
Icache *ic;
|
||||
|
||||
h = hash(url) % NHASH;
|
||||
for(ic=icache.hash[h]; ic; ic=ic->hash){
|
||||
if(strcmp(ic->url, url) == 0){
|
||||
/* move to front */
|
||||
if(ic->prev) {
|
||||
ic->prev->next = ic->next;
|
||||
if(ic->next)
|
||||
ic->next->prev = ic->prev;
|
||||
else
|
||||
icache.tail = ic->prev;
|
||||
ic->prev = nil;
|
||||
ic->next = icache.head;
|
||||
icache.head->prev = ic;
|
||||
icache.head = ic;
|
||||
}
|
||||
return ic;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
static Icache*
|
||||
icacheinsert(char *url, HTTPHeader *hdr, char *file, int fd)
|
||||
{
|
||||
int h;
|
||||
Icache *ic, **l;
|
||||
|
||||
if(icache.n == MAXCACHE){
|
||||
ic = icache.tail;
|
||||
icache.tail = ic->prev;
|
||||
if(ic->prev)
|
||||
ic->prev->next = nil;
|
||||
else
|
||||
icache.head = ic->prev;
|
||||
h = hash(ic->url) % NHASH;
|
||||
for(l=&icache.hash[h]; *l; l=&(*l)->hash){
|
||||
if(*l == ic){
|
||||
*l = ic->hash;
|
||||
goto removed;
|
||||
}
|
||||
}
|
||||
sysfatal("cannot find ic in cache");
|
||||
removed:
|
||||
free(ic->url);
|
||||
close(ic->fd);
|
||||
remove(ic->file);
|
||||
free(ic->file);
|
||||
}else{
|
||||
ic = emalloc(sizeof *ic);
|
||||
icache.n++;
|
||||
}
|
||||
|
||||
ic->url = estrdup(url);
|
||||
ic->fd = dup(fd, -1);
|
||||
ic->file = estrdup(file);
|
||||
ic->hdr = *hdr;
|
||||
h = hash(url) % NHASH;
|
||||
ic->hash = icache.hash[h];
|
||||
icache.hash[h] = ic;
|
||||
ic->prev = nil;
|
||||
ic->next = icache.head;
|
||||
if(ic->next)
|
||||
ic->next->prev = ic;
|
||||
else
|
||||
icache.tail = ic;
|
||||
return ic;
|
||||
}
|
||||
|
||||
void
|
||||
icacheflush(char *substr)
|
||||
{
|
||||
Icache **l, *ic;
|
||||
|
||||
for(l=&icache.head; (ic=*l); ) {
|
||||
if(substr == nil || strstr(ic->url, substr)) {
|
||||
icache.n--;
|
||||
*l = ic->next;
|
||||
free(ic->url);
|
||||
close(ic->fd);
|
||||
remove(ic->file);
|
||||
free(ic->file);
|
||||
free(ic);
|
||||
}else
|
||||
l = &ic->next;
|
||||
}
|
||||
|
||||
if(icache.head) {
|
||||
icache.head->prev = nil;
|
||||
for(ic=icache.head; ic; ic=ic->next){
|
||||
if(ic->next)
|
||||
ic->next->prev = ic;
|
||||
else
|
||||
icache.tail = ic;
|
||||
}
|
||||
}else
|
||||
icache.tail = nil;
|
||||
}
|
||||
|
||||
int
|
||||
urlfetch(char *url, HTTPHeader hdr)
|
||||
{
|
||||
Icache *ic;
|
||||
char buf[50], *host, *path, *p;
|
||||
int fd, len;
|
||||
|
||||
ic = icachefind(url);
|
||||
if(ic != nil){
|
||||
*hdr = ic->hdr;
|
||||
return dup(ic->fd, -1);
|
||||
}
|
||||
|
||||
if(memcmp(url, "http://", 7) != 0){
|
||||
werrstr("non-http url");
|
||||
return -1;
|
||||
}
|
||||
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 = "/";
|
||||
|
||||
strcpy(buf, "/var/tmp/smugfs.XXXXXX");
|
||||
fd = opentemp(buf, ORDWR|ORCLOSE);
|
||||
if(fd < 0)
|
||||
return -1;
|
||||
if(httptofile(http, host, req, &hdr, fd) < 0){
|
||||
free(host);
|
||||
return -1;
|
||||
}
|
||||
free(host);
|
||||
icacheinsert(url, &hdr, buf, fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue