# File view spooler, for use with spool
implement Spooler;
include "sys.m";
sys: Sys;
Dir, pctl, NEWPGRP, DMDIR, open, OREAD, FD, OWRITE, ORCLOSE, FORKFD,
ORDWR, FORKNS, NEWFD, MREPL, MBEFORE, MAFTER, MCREATE, pipe, mount,
fprint, sprint, create, pwrite, read, QTDIR, QTFILE, fildes, Qid: import sys;
include "error.m";
err: Error;
checkload, stderr, panic, kill, error: import err;
include "string.m";
str: String;
splitl, splitstrr : import str;
include "os.m";
os: Os;
include "spooler.m";
viewurlcmd(url: string): string
{
cmd: string;
host := os->host;
case host {
"Plan9" or "PlanB" =>
cmd = sprint("plumb '%s'", url);
"MacOSX" =>
cmd = sprint("open %s", url);
* =>
# BUG: "Nt" and "Linux"
cmd = sprint("open %s", url);
}
return cmd;
}
viewcmd(file: string): string
{
cmd : string;
(pref, suf) := splitstrr(file, ".url");
if (suf == nil || suf == "")
if (pref != nil && pref != ""){
url := readall(file);
if (url != nil)
(url, suf) = splitl(url, "\n");
return viewurlcmd(url);
}
r := os->filename(file);
host := os->host;
case host {
"Plan9" or "PlanB" =>
cmd = sprint("plumb %s", r);
"MacOSX" =>
# lsof may report when we're done viewing the file
cmd = sprint("open %s", r);
* =>
# BUG: "Nt" and "Linux"
cmd = sprint("open %s", r);
}
return cmd;
}
Sfile.start(path: string, endc: chan of string): (ref Sfile, string)
{
cmd := viewcmd(path);
if (debug)
fprint(stderr, "view: cmd %s\n", cmd);
cfd := open("/cmd/clone", ORDWR);
if (cfd == nil) {
if (endc != nil)
endc <-= sprint("viewer: cmd: %r\n");
return (nil, sprint("viewer: cmd: %r\n"));
}
fprint(cfd, "killonclose");
fprint(cfd, "exec %s", cmd);
if (endc != nil)
endc <-= nil;
return (ref Sfile(cfd, nil), nil);
}
Sfile.stop(f: self ref Sfile)
{
f.fd = nil;
}
Sfile.status(nil: self ref Sfile): string
{
return "started";
}
readall(fname: string) : string
{
fd := open(fname, OREAD);
if (fd == nil)
return "none";
max : con int 1024;
data := array[max] of byte;
tot := nr := 0;
do {
nr = read(fd, data[tot:], len data - tot);
if (nr > 0)
tot += nr;
} while(nr > 0 && tot < len data);
if (tot == 0)
return "none";
return string data[0:tot];
}
init(nil: list of string)
{
sys = load Sys Sys->PATH;
err = load Error Error->PATH;
err->init();
str = checkload(load String String->PATH, String->PATH);
os = checkload(load Os Os->PATH, Os->PATH);
os->init();
}
status(): string
{
return "ok";
}
|