V9/jtools/src/sam/io.c
#include "sam.h"
#include <sys/ioctl.h>
#ifdef SUN
/* a hack to get around redef of ushort in sys/types.h .
this depends on non-use of ushort in this file */
#define ushort USHORT
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifndef SUN
#include "/usr/jerq/include/jioctl.h"
#endif
writef(f)
register File *f;
{
uchar c;
Posn n;
struct stat statb;
int newfile=0;
if(stat((char *)genstr.s, &statb)==-1)
newfile++;
else if(strcmp(genstr.s, f->name.s)==0 &&
(f->inumber!=statb.st_ino || f->date<statb.st_mtime)){
f->inumber=statb.st_ino;
f->date=statb.st_mtime;
warn_s(Wdate, (char *)genstr.s);
return;
}
if((io=creat((char *)genstr.s, 0666))<0)
error_s(Ecreate, (char *)genstr.s);
dprint("%s: ", (char *)genstr.s);
n=writeio(f);
if(f->name.s[0]==0 || strcmp(genstr.s, f->name.s)==0)
state(f, addr.r.p1==0 && addr.r.p2==f->nbytes? Clean : Dirty);
if(newfile)
dprint("(new file) ");
if(addr.r.p2>0 && Fchars(f, &c, addr.r.p2-1, addr.r.p2) && c!='\n')
warn(Wnotnewline);
if(f->name.s[0]==0 || strcmp(genstr.s, f->name.s)==0){
fstat(io, &statb);
f->inumber=statb.st_ino;
f->date=statb.st_mtime;
}
closeio(n);
}
Posn
readio(f, nonascii, setdate)
register File *f;
int *nonascii;
{
register n;
register Posn nt;
register Posn p=addr.r.p2;
struct stat statb;
if(nonascii)
*nonascii=FALSE;
for(nt=0; (n=read(io, (char *)genbuf, BLOCKSIZE))>0; nt+=n){
n=clean(genbuf, n, nonascii);
Finsert(f, tempstr(genbuf, n), p);
}
if(nonascii && *nonascii)
warn(Wnonascii);
if(setdate){
fstat(io, &statb);
f->inumber=statb.st_ino;
f->date=statb.st_mtime;
}
return nt;
}
Posn
writeio(f)
register File *f;
{
register n;
register Posn p=addr.r.p1;
while(p<addr.r.p2){
if(addr.r.p2-p>BLOCKSIZE)
n=BLOCKSIZE;
else
n=addr.r.p2-p;
if(Fchars(f, genbuf, p, p+n)!=n)
panic("writef read");
(void)Write(io, genbuf, n);
p+=n;
}
return addr.r.p2-addr.r.p1;
}
closeio(p)
Posn p;
{
(void)close(io);
io=0;
if(p>=0)
dprint("#%lud\n", p);
}
clean(s, n, nonascii)
register uchar *s;
register n;
int *nonascii;
{
register uchar *p, *q;
register i;
/* for speed, just look first */
p=s;
if(i=n)
do
if(*p==0 || (*p++&HIGHBIT))
goto Cleanup;
while(--i);
return n; /* usual case */
Cleanup:
for(q=p=s, i=0; i<n; i++, p++)
if(*p!=0 && (*p&HIGHBIT)==0)
*q++= *p;
if(nonascii)
*nonascii=TRUE;
return q-s;
}
#ifndef SUN
bootterm(zflag)
{
if(system("/usr/jerq/bin/32ld", "32ld",
#ifdef DIST
zflag? "-z" : "-", "/usr/jerq/mbin/sam.m")){
#else
zflag? "-z" : "-", "/n/ikeya/usr/rob/sam/term/a.out")){
#endif
dprint("sam: can't boot terminal program\n");
return 0;
}
return 1;
}
#endif !SUN
rawmode(raw)
{
struct sgttyb buf;
ioctl(0, TIOCGETP, &buf);
if(raw){
ioctl(0, TIOCEXCL, (struct sgttyb *)0);
buf.sg_flags|=RAW|ANYP;
}else{
ioctl(0, TIOCNXCL, (struct sgttyb *)0);
#ifndef SUN
ioctl(0, JTERM, (struct sgttyb *)0);
#endif
buf.sg_flags&=~(RAW|ANYP);
}
ioctl(0, TIOCSETP, &buf);
}
system(s, t, u, v)
char *s, *t, *u, *v;
{
int status, pid, l;
if((pid=fork()) == 0) {
execl(s, t, u, v, 0);
_exit(127);
}
do; while((l=wait(&status))!=pid && l!=-1);
if(l==-1)
status= -1;
return(status);
}
closeonexec(fd){
ioctl(fd, FIOCLEX, (struct sgttyb *)0);
}
#ifndef SUN
static int remotefd;
connectto(machine)
char *machine;
{
if(strncmp((uchar *)machine, (uchar *)"inet/", 5)==0)
remotefd=tcpexec(machine+5, "exec /usr/jerq/bin/sam -R");
else
remotefd=tdkexec(machine, "exec /usr/jerq/bin/sam -R");
if(remotefd<0){
dprint("sam: can't call %s\n", machine);
exit(1);
}
}
join(){
switch(fork()){
case 0:
close(0);
dup(remotefd);
execl("/bin/cat", 0);
default:
close(1);
dup(remotefd);
execl("/bin/cat", 0);
case -1:
dprint("sam: can't fork\n");
}
exit(1);
}
int
tcpexec(host, cmd)
char *host;
char *cmd;
{
int pfd[2];
if (pipe(pfd)<0)
return -1;
switch(fork()) {
case -1:
return -1;
case 0:
break;
default:
close(pfd[0]);
return(pfd[1]);
}
close(pfd[1]);
if (dup2(pfd[0], 0)<0 || dup2(pfd[0], 1)<0 || dup2(pfd[0], 2)<0) {
dprint("sam: can't redirect\n");
exit(1);
}
close(pfd[0]);
execl("/usr/inet/bin/rsh", host, cmd, 0);
dprint("sam: can't exec rsh\n");
exit(1);
return -1; /* for cyntax */
}
#endif !SUN