diff options
Diffstat (limited to 'appl/charon/file.b')
| -rw-r--r-- | appl/charon/file.b | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/appl/charon/file.b b/appl/charon/file.b new file mode 100644 index 00000000..1a5947c1 --- /dev/null +++ b/appl/charon/file.b @@ -0,0 +1,134 @@ +implement Transport; + +include "common.m"; +include "transport.m"; + +# local copies from CU +sys: Sys; +U: Url; + Parsedurl: import U; +CU: CharonUtils; + Netconn, ByteSource, Header, config : import CU; + +dbg := 0; + +init(c: CharonUtils) +{ + CU = c; + sys = load Sys Sys->PATH; + U = load Url Url->PATH; + if (U != nil) + U->init(); + dbg = int (CU->config).dbg['n']; +} + +connect(nc: ref Netconn, nil: ref ByteSource) +{ + nc.connected = 1; + nc.state = CU->NCgethdr; + return; +} + +writereq(nil: ref Netconn, nil: ref ByteSource) +{ + return; +} + +gethdr(nc: ref Netconn, bs: ref ByteSource) +{ + u := bs.req.url; + f := u.path; + hdr := Header.new(); + nc.conn.dfd = sys->open(f, sys->OREAD); + if(nc.conn.dfd == nil) { + if(dbg) + sys->print("file %d: can't open %s: %r\n", nc.id, f); + # Could examine %r to distinguish between NotFound + # and Forbidden and other, but string is OS-dependent. + hdr.code = CU->HCNotFound; + bs.hdr = hdr; + nc.connected = 0; + return; + } + + (ok, statbuf) := sys->fstat(nc.conn.dfd); + if(ok < 0) { + bs.err = "stat error"; + return; + } + + if (statbuf.mode & Sys->DMDIR) { + bs.err = "Directories not implemented"; + return; + } + + # assuming file (not directory) + n := int statbuf.length; + hdr.length = n; + if(n > sys->ATOMICIO) + n = sys->ATOMICIO; + a := array[n] of byte; + n = sys->read(nc.conn.dfd, a, n); + if(dbg) + sys->print("file %d: initial read %d bytes\n", nc.id, n); + if(n < 0) { + bs.err = "read error"; + return; + } + hdr.setmediatype(f, a[0:n]); + hdr.base = hdr.actual = bs.req.url; + if(dbg) + sys->print("file %d: hdr has mediatype=%s, length=%d\n", + nc.id, CU->mnames[hdr.mtype], hdr.length); + bs.hdr = hdr; + if(n == len a) + nc.tbuf = a; + else + nc.tbuf = a[0:n]; +} + +getdata(nc: ref Netconn, bs: ref ByteSource): int +{ + dfd := nc.conn.dfd; + if (dfd == nil) + return -1; + if (bs.data == nil || bs.edata >= len bs.data) { + closeconn(nc); + return 0; + } + buf := bs.data[bs.edata:]; + n := len buf; + if (nc.tbuf != nil) { + # initial overread of header + if (n >= len nc.tbuf) { + n = len nc.tbuf; + buf[:] = nc.tbuf; + nc.tbuf = nil; + return n; + } + buf[:] = nc.tbuf[:n]; + nc.tbuf = nc.tbuf[n:]; + return n; + } + n = sys->read(dfd, buf, n); + if(dbg > 1) + sys->print("ftp %d: read %d bytes\n", nc.id, n); + if(n <= 0) { + bs.err = sys->sprint("%r"); + closeconn(nc); + } + return n; +} + +defaultport(nil: string) : int +{ + return 0; +} + +closeconn(nc: ref Netconn) +{ + nc.conn.dfd = nil; + nc.conn.cfd = nil; + nc.conn.dir = ""; + nc.connected = 0; +} |
