blob: 8740c7ca89e319c1d8ed354700dafc3f8fd33297 [file] [log] [blame]
rsc76193d72003-09-30 17:47:42 +00001#include "sam.h"
2
3#define NSYSFILE 3
4#define NOFILE 128
5
6void
7checkqid(File *f)
8{
9 int i, w;
10 File *g;
11
12 w = whichmenu(f);
13 for(i=1; i<file.nused; i++){
14 g = file.filepptr[i];
15 if(w == i)
16 continue;
17 if(f->dev==g->dev && f->qidpath==g->qidpath)
18 warn_SS(Wdupfile, &f->name, &g->name);
19 }
20}
21
22void
23writef(File *f)
24{
25 Posn n;
26 char *name;
27 int i, samename, newfile;
28 ulong dev;
29 uvlong qid;
30 long mtime, appendonly, length;
31
32 newfile = 0;
33 samename = Strcmp(&genstr, &f->name) == 0;
34 name = Strtoc(&f->name);
35 i = statfile(name, &dev, &qid, &mtime, 0, 0);
36 if(i == -1)
37 newfile++;
38 else if(samename &&
39 (f->dev!=dev || f->qidpath!=qid || f->mtime<mtime)){
40 f->dev = dev;
41 f->qidpath = qid;
42 f->mtime = mtime;
43 warn_S(Wdate, &genstr);
44 return;
45 }
46 if(genc)
47 free(genc);
48 genc = Strtoc(&genstr);
49 if((io=create(genc, 1, 0666L)) < 0)
50 error_r(Ecreate, genc);
51 dprint("%s: ", genc);
52 if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0)
53 error(Eappend);
54 n = writeio(f);
55 if(f->name.s[0]==0 || samename){
rsc522b0682003-09-30 19:05:50 +000056 if(addr.r.p1==0 && addr.r.p2==f->b.nc)
rsc76193d72003-09-30 17:47:42 +000057 f->cleanseq = f->seq;
58 state(f, f->cleanseq==f->seq? Clean : Dirty);
59 }
60 if(newfile)
61 dprint("(new file) ");
62 if(addr.r.p2>0 && filereadc(f, addr.r.p2-1)!='\n')
63 warn(Wnotnewline);
64 closeio(n);
65 if(f->name.s[0]==0 || samename){
66 if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){
67 f->dev = dev;
68 f->qidpath = qid;
69 f->mtime = mtime;
70 checkqid(f);
71 }
72 }
73}
74
75Posn
76readio(File *f, int *nulls, int setdate, int toterm)
77{
78 int n, b, w;
79 Rune *r;
80 Posn nt;
81 Posn p = addr.r.p2;
82 ulong dev;
83 uvlong qid;
84 long mtime;
85 char buf[BLOCKSIZE+1], *s;
86
87 *nulls = FALSE;
88 b = 0;
89 if(f->unread){
rsc522b0682003-09-30 19:05:50 +000090 nt = bufload(&f->b, 0, io, nulls);
rsc76193d72003-09-30 17:47:42 +000091 if(toterm)
92 raspload(f);
93 }else
94 for(nt = 0; (n = read(io, buf+b, BLOCKSIZE-b))>0; nt+=(r-genbuf)){
95 n += b;
96 b = 0;
97 r = genbuf;
98 s = buf;
99 while(n > 0){
100 if((*r = *(uchar*)s) < Runeself){
101 if(*r)
102 r++;
103 else
104 *nulls = TRUE;
105 --n;
106 s++;
107 continue;
108 }
109 if(fullrune(s, n)){
110 w = chartorune(r, s);
111 if(*r)
112 r++;
113 else
114 *nulls = TRUE;
115 n -= w;
116 s += w;
117 continue;
118 }
119 b = n;
120 memmove(buf, s, b);
121 break;
122 }
123 loginsert(f, p, genbuf, r-genbuf);
124 }
125 if(b)
126 *nulls = TRUE;
127 if(*nulls)
128 warn(Wnulls);
129 if(setdate){
130 if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){
131 f->dev = dev;
132 f->qidpath = qid;
133 f->mtime = mtime;
134 checkqid(f);
135 }
136 }
137 return nt;
138}
139
140Posn
141writeio(File *f)
142{
143 int m, n;
144 Posn p = addr.r.p1;
145 char *c;
146
147 while(p < addr.r.p2){
148 if(addr.r.p2-p>BLOCKSIZE)
149 n = BLOCKSIZE;
150 else
151 n = addr.r.p2-p;
rsc522b0682003-09-30 19:05:50 +0000152 bufread(&f->b, p, genbuf, n);
rsc76193d72003-09-30 17:47:42 +0000153 c = Strtoc(tmprstr(genbuf, n));
154 m = strlen(c);
155 if(Write(io, c, m) != m){
156 free(c);
157 if(p > 0)
158 p += n;
159 break;
160 }
161 free(c);
162 p += n;
163 }
164 return p-addr.r.p1;
165}
166void
167closeio(Posn p)
168{
169 close(io);
170 io = 0;
171 if(p >= 0)
172 dprint("#%lud\n", p);
173}
174
175int remotefd0 = 0;
176int remotefd1 = 1;
177
178void
rsc17ab31a2005-01-27 06:10:35 +0000179bootterm(char *machine, char **argv)
rsc76193d72003-09-30 17:47:42 +0000180{
181 int ph2t[2], pt2h[2];
182
183 if(machine){
184 dup(remotefd0, 0);
185 dup(remotefd1, 1);
186 close(remotefd0);
187 close(remotefd1);
188 argv[0] = "samterm";
rsce6c43462003-11-23 17:50:36 +0000189 execvp(samterm, argv);
rsc522b0682003-09-30 19:05:50 +0000190 fprint(2, "can't exec %s: %r\n", samterm);
rsc76193d72003-09-30 17:47:42 +0000191 _exits("damn");
192 }
193 if(pipe(ph2t)==-1 || pipe(pt2h)==-1)
194 panic("pipe");
195 switch(fork()){
196 case 0:
197 dup(ph2t[0], 0);
198 dup(pt2h[1], 1);
199 close(ph2t[0]);
200 close(ph2t[1]);
201 close(pt2h[0]);
202 close(pt2h[1]);
203 argv[0] = "samterm";
rsce6c43462003-11-23 17:50:36 +0000204 execvp(samterm, argv);
rsc76193d72003-09-30 17:47:42 +0000205 fprint(2, "can't exec: ");
206 perror(samterm);
207 _exits("damn");
208 case -1:
209 panic("can't fork samterm");
210 }
211 dup(pt2h[0], 0);
212 dup(ph2t[1], 1);
213 close(ph2t[0]);
214 close(ph2t[1]);
215 close(pt2h[0]);
216 close(pt2h[1]);
217}
218
219void
rsc8538a662004-05-14 18:25:49 +0000220connectto(char *machine, char **argv)
rsc76193d72003-09-30 17:47:42 +0000221{
222 int p1[2], p2[2];
rsc8538a662004-05-14 18:25:49 +0000223 char **av;
224 int ac;
rsc76193d72003-09-30 17:47:42 +0000225
rsccbeb0b22006-04-01 19:24:03 +0000226 /* count args */
rsc8538a662004-05-14 18:25:49 +0000227 for(av = argv; *av; av++)
228 ;
rsc23874952006-03-20 04:02:36 +0000229 av = malloc(sizeof(char*)*((av-argv) + 5));
rsc8538a662004-05-14 18:25:49 +0000230 if(av == nil){
231 dprint("out of memory\n");
232 exits("fork/exec");
233 }
234 ac = 0;
235 av[ac++] = RX;
236 av[ac++] = machine;
237 av[ac++] = rsamname;
238 av[ac++] = "-R";
239 while(*argv)
240 av[ac++] = *argv++;
241 av[ac] = 0;
rsc76193d72003-09-30 17:47:42 +0000242 if(pipe(p1)<0 || pipe(p2)<0){
243 dprint("can't pipe\n");
244 exits("pipe");
245 }
246 remotefd0 = p1[0];
247 remotefd1 = p2[1];
248 switch(fork()){
249 case 0:
250 dup(p2[0], 0);
251 dup(p1[1], 1);
252 close(p1[0]);
253 close(p1[1]);
254 close(p2[0]);
255 close(p2[1]);
rsc8538a662004-05-14 18:25:49 +0000256 execvp(RXPATH, av);
rsc76193d72003-09-30 17:47:42 +0000257 dprint("can't exec %s\n", RXPATH);
258 exits("exec");
259
260 case -1:
261 dprint("can't fork\n");
262 exits("fork");
263 }
rsc8538a662004-05-14 18:25:49 +0000264 free(av);
rsc76193d72003-09-30 17:47:42 +0000265 close(p1[1]);
266 close(p2[0]);
267}
268
269void
rsc17ab31a2005-01-27 06:10:35 +0000270startup(char *machine, int Rflag, char **argv, char **files)
rsc76193d72003-09-30 17:47:42 +0000271{
272 if(machine)
rsc8538a662004-05-14 18:25:49 +0000273 connectto(machine, files);
rsc76193d72003-09-30 17:47:42 +0000274 if(!Rflag)
rsc17ab31a2005-01-27 06:10:35 +0000275 bootterm(machine, argv);
rsc76193d72003-09-30 17:47:42 +0000276 downloaded = 1;
277 outTs(Hversion, VERSION);
278}