#include "i.h"
int dbgfile = 0;
void
fileinit(void)
{
dbgfile = (config).dbg['n'];
}
void
fileconnect(Netconn* nc, ByteSource* bs)
{
USED(bs);
nc->connected = 1;
nc->state = NCgethdr;
return ;
}
void
filewritereq(Netconn* nc, ByteSource* bs)
{
USED(nc);
USED(bs);
return;
}
void
filegethdr(Netconn* nc, ByteSource* bs)
{
ParsedUrl* u;
Rune* fname;
char* f;
Header* hdr;
int n;
uchar* a;
int alen;
Dir *statbuf;
u = bs->req->url;
assert(u->npstart == 1);
fname = newstr(1+u->npath);
fname[0] = '/';
Stradd(fname+1, u->path, u->npath);
fname[1+u->npath] = 0;
f = (char*)fromStr(fname, Strlen(fname), UTF_8);
hdr = newheader();
nc->dfd = open(f, OREAD);
if(nc->dfd < 0) {
if(dbgfile)
trace("file %d: can't open %s: %r\n", nc->id, f);
hdr->code = HCNotFound;
bs->hdr = hdr;
nc->connected = 0;
}
else {
statbuf = dirfstat(nc->dfd);
if(statbuf == nil)
bs->err = ERRstaterr;
else {
n = statbuf->length;
free(statbuf);
hdr->length = n;
if(n > ATOMICIO)
alen = ATOMICIO;
else
alen = n;
a = (uchar*)emalloc(alen);
n = read(nc->dfd, a, alen);
if(dbgfile)
trace("file %d: initial read %d bytes\n", nc->id, n);
if(n < 0)
bs->err = ERRreaderr;
else {
setmediatype(hdr, fname, a, n);
hdr->base = copyurl(u);
hdr->actual = hdr->base;
if(dbgfile)
trace("file %d: hdr has mediatype=%S, length=%d\n",
nc->id, mnames[hdr->mtype], hdr->length);
bs->hdr = hdr;
nc->tbuf = a;
nc->tbuflen = alen;
nc->tn1 = n;
nc->tn2 = alen;
}
}
}
}
void
filegetdata(Netconn* nc, ByteSource* bs)
{
uchar* buf;
int buflen;
int n;
buf = bs->data;
buflen = bs->dalloclen;
if(nc->tbuf != nil) {
// initial data
if(buflen <= nc->tn1) {
bs->data = nc->tbuf;
bs->dalloclen = nc->tn2;
bs->edata = nc->tn1;
nc->tbuf = nil;
nc->tbuflen = 0;
if(dbgfile)
trace("file %d: eof (%d total bytes)\n", nc->id, bs->edata);
close(nc->dfd);
nc->dfd = -1;
nc->connected = 0;
return ;
}
else {
memmove(buf, nc->tbuf, nc->tn1);
bs->edata = nc->tn1;
nc->tbuf = nil;
nc->tbuflen = 0;
}
}
n = read(nc->dfd, buf+bs->edata, buflen - bs->edata);
if(dbgfile > 1)
trace("file %d: read %d bytes\n", nc->id, n);
if(n <= 0) {
close(nc->dfd);
nc->dfd = -1;
nc->connected = 0;
if(n < 0)
bs->err = ERRreaderr;
}
else {
bs->edata += n;
if(bs->edata == bs->hdr->length) {
if(dbgfile)
trace("file %d: eof (%d total bytes)\n", nc->id, bs->edata);
close(nc->dfd);
nc->dfd = -1;
nc->connected = 0;
}
}
}
int
filedefaultport(int scheme)
{
USED(scheme);
return 0;
}
|