mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
17ab31aac6
clean up argument parsing.
278 lines
4.6 KiB
C
278 lines
4.6 KiB
C
#include "sam.h"
|
|
|
|
#define NSYSFILE 3
|
|
#define NOFILE 128
|
|
|
|
void
|
|
checkqid(File *f)
|
|
{
|
|
int i, w;
|
|
File *g;
|
|
|
|
w = whichmenu(f);
|
|
for(i=1; i<file.nused; i++){
|
|
g = file.filepptr[i];
|
|
if(w == i)
|
|
continue;
|
|
if(f->dev==g->dev && f->qidpath==g->qidpath)
|
|
warn_SS(Wdupfile, &f->name, &g->name);
|
|
}
|
|
}
|
|
|
|
void
|
|
writef(File *f)
|
|
{
|
|
Posn n;
|
|
char *name;
|
|
int i, samename, newfile;
|
|
ulong dev;
|
|
uvlong qid;
|
|
long mtime, appendonly, length;
|
|
|
|
newfile = 0;
|
|
samename = Strcmp(&genstr, &f->name) == 0;
|
|
name = Strtoc(&f->name);
|
|
i = statfile(name, &dev, &qid, &mtime, 0, 0);
|
|
if(i == -1)
|
|
newfile++;
|
|
else if(samename &&
|
|
(f->dev!=dev || f->qidpath!=qid || f->mtime<mtime)){
|
|
f->dev = dev;
|
|
f->qidpath = qid;
|
|
f->mtime = mtime;
|
|
warn_S(Wdate, &genstr);
|
|
return;
|
|
}
|
|
if(genc)
|
|
free(genc);
|
|
genc = Strtoc(&genstr);
|
|
if((io=create(genc, 1, 0666L)) < 0)
|
|
error_r(Ecreate, genc);
|
|
dprint("%s: ", genc);
|
|
if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0)
|
|
error(Eappend);
|
|
n = writeio(f);
|
|
if(f->name.s[0]==0 || samename){
|
|
if(addr.r.p1==0 && addr.r.p2==f->b.nc)
|
|
f->cleanseq = f->seq;
|
|
state(f, f->cleanseq==f->seq? Clean : Dirty);
|
|
}
|
|
if(newfile)
|
|
dprint("(new file) ");
|
|
if(addr.r.p2>0 && filereadc(f, addr.r.p2-1)!='\n')
|
|
warn(Wnotnewline);
|
|
closeio(n);
|
|
if(f->name.s[0]==0 || samename){
|
|
if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){
|
|
f->dev = dev;
|
|
f->qidpath = qid;
|
|
f->mtime = mtime;
|
|
checkqid(f);
|
|
}
|
|
}
|
|
}
|
|
|
|
Posn
|
|
readio(File *f, int *nulls, int setdate, int toterm)
|
|
{
|
|
int n, b, w;
|
|
Rune *r;
|
|
Posn nt;
|
|
Posn p = addr.r.p2;
|
|
ulong dev;
|
|
uvlong qid;
|
|
long mtime;
|
|
char buf[BLOCKSIZE+1], *s;
|
|
|
|
*nulls = FALSE;
|
|
b = 0;
|
|
if(f->unread){
|
|
nt = bufload(&f->b, 0, io, nulls);
|
|
if(toterm)
|
|
raspload(f);
|
|
}else
|
|
for(nt = 0; (n = read(io, buf+b, BLOCKSIZE-b))>0; nt+=(r-genbuf)){
|
|
n += b;
|
|
b = 0;
|
|
r = genbuf;
|
|
s = buf;
|
|
while(n > 0){
|
|
if((*r = *(uchar*)s) < Runeself){
|
|
if(*r)
|
|
r++;
|
|
else
|
|
*nulls = TRUE;
|
|
--n;
|
|
s++;
|
|
continue;
|
|
}
|
|
if(fullrune(s, n)){
|
|
w = chartorune(r, s);
|
|
if(*r)
|
|
r++;
|
|
else
|
|
*nulls = TRUE;
|
|
n -= w;
|
|
s += w;
|
|
continue;
|
|
}
|
|
b = n;
|
|
memmove(buf, s, b);
|
|
break;
|
|
}
|
|
loginsert(f, p, genbuf, r-genbuf);
|
|
}
|
|
if(b)
|
|
*nulls = TRUE;
|
|
if(*nulls)
|
|
warn(Wnulls);
|
|
if(setdate){
|
|
if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){
|
|
f->dev = dev;
|
|
f->qidpath = qid;
|
|
f->mtime = mtime;
|
|
checkqid(f);
|
|
}
|
|
}
|
|
return nt;
|
|
}
|
|
|
|
Posn
|
|
writeio(File *f)
|
|
{
|
|
int m, n;
|
|
Posn p = addr.r.p1;
|
|
char *c;
|
|
|
|
while(p < addr.r.p2){
|
|
if(addr.r.p2-p>BLOCKSIZE)
|
|
n = BLOCKSIZE;
|
|
else
|
|
n = addr.r.p2-p;
|
|
bufread(&f->b, p, genbuf, n);
|
|
c = Strtoc(tmprstr(genbuf, n));
|
|
m = strlen(c);
|
|
if(Write(io, c, m) != m){
|
|
free(c);
|
|
if(p > 0)
|
|
p += n;
|
|
break;
|
|
}
|
|
free(c);
|
|
p += n;
|
|
}
|
|
return p-addr.r.p1;
|
|
}
|
|
void
|
|
closeio(Posn p)
|
|
{
|
|
close(io);
|
|
io = 0;
|
|
if(p >= 0)
|
|
dprint("#%lud\n", p);
|
|
}
|
|
|
|
int remotefd0 = 0;
|
|
int remotefd1 = 1;
|
|
|
|
void
|
|
bootterm(char *machine, char **argv)
|
|
{
|
|
int ph2t[2], pt2h[2];
|
|
|
|
if(machine){
|
|
dup(remotefd0, 0);
|
|
dup(remotefd1, 1);
|
|
close(remotefd0);
|
|
close(remotefd1);
|
|
argv[0] = "samterm";
|
|
execvp(samterm, argv);
|
|
fprint(2, "can't exec %s: %r\n", samterm);
|
|
_exits("damn");
|
|
}
|
|
if(pipe(ph2t)==-1 || pipe(pt2h)==-1)
|
|
panic("pipe");
|
|
switch(fork()){
|
|
case 0:
|
|
dup(ph2t[0], 0);
|
|
dup(pt2h[1], 1);
|
|
close(ph2t[0]);
|
|
close(ph2t[1]);
|
|
close(pt2h[0]);
|
|
close(pt2h[1]);
|
|
argv[0] = "samterm";
|
|
execvp(samterm, argv);
|
|
fprint(2, "can't exec: ");
|
|
perror(samterm);
|
|
_exits("damn");
|
|
case -1:
|
|
panic("can't fork samterm");
|
|
}
|
|
dup(pt2h[0], 0);
|
|
dup(ph2t[1], 1);
|
|
close(ph2t[0]);
|
|
close(ph2t[1]);
|
|
close(pt2h[0]);
|
|
close(pt2h[1]);
|
|
}
|
|
|
|
void
|
|
connectto(char *machine, char **argv)
|
|
{
|
|
int p1[2], p2[2];
|
|
char **av;
|
|
int ac;
|
|
|
|
// count args
|
|
for(av = argv; *av; av++)
|
|
;
|
|
av = malloc(sizeof(char*)*((av-argv) + 5));
|
|
if(av == nil){
|
|
dprint("out of memory\n");
|
|
exits("fork/exec");
|
|
}
|
|
ac = 0;
|
|
av[ac++] = RX;
|
|
av[ac++] = machine;
|
|
av[ac++] = rsamname;
|
|
av[ac++] = "-R";
|
|
while(*argv)
|
|
av[ac++] = *argv++;
|
|
av[ac] = 0;
|
|
if(pipe(p1)<0 || pipe(p2)<0){
|
|
dprint("can't pipe\n");
|
|
exits("pipe");
|
|
}
|
|
remotefd0 = p1[0];
|
|
remotefd1 = p2[1];
|
|
switch(fork()){
|
|
case 0:
|
|
dup(p2[0], 0);
|
|
dup(p1[1], 1);
|
|
close(p1[0]);
|
|
close(p1[1]);
|
|
close(p2[0]);
|
|
close(p2[1]);
|
|
execvp(RXPATH, av);
|
|
dprint("can't exec %s\n", RXPATH);
|
|
exits("exec");
|
|
|
|
case -1:
|
|
dprint("can't fork\n");
|
|
exits("fork");
|
|
}
|
|
free(av);
|
|
close(p1[1]);
|
|
close(p2[0]);
|
|
}
|
|
|
|
void
|
|
startup(char *machine, int Rflag, char **argv, char **files)
|
|
{
|
|
if(machine)
|
|
connectto(machine, files);
|
|
if(!Rflag)
|
|
bootterm(machine, argv);
|
|
downloaded = 1;
|
|
outTs(Hversion, VERSION);
|
|
}
|