summaryrefslogtreecommitdiff
path: root/appl/charon/file.b
diff options
context:
space:
mode:
Diffstat (limited to 'appl/charon/file.b')
-rw-r--r--appl/charon/file.b134
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;
+}