]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/sam/io.c
merge
[plan9front.git] / sys / src / cmd / sam / io.c
1 #include "sam.h"
2
3 #define NSYSFILE        3
4 #define NOFILE          128
5
6 void
7 checkqid(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
22 void
23 writef(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){
56                 if(addr.r.p1==0 && addr.r.p2==f->nc)
57                         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
75 Posn
76 readio(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){
90                 nt = bufload(f, 0, io, nulls);
91                 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
140 Posn
141 writeio(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;
152                 bufread(f, p, genbuf, n);
153                 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 }
166 void
167 closeio(Posn p)
168 {
169         close(io);
170         io = 0;
171         if(p >= 0)
172                 dprint("#%lud\n", p);
173 }
174
175 int     remotefd0 = 0;
176 int     remotefd1 = 1;
177
178 void
179 bootterm(char *machine, char **argv)
180 {
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";
189                 exec(samterm, argv);
190                 fprint(2, "can't exec: ");
191                 perror(samterm);
192                 _exits("damn");
193         }
194         if(pipe(ph2t)==-1 || pipe(pt2h)==-1)
195                 panic("pipe");
196         switch(fork()){
197         case 0:
198                 dup(ph2t[0], 0);
199                 dup(pt2h[1], 1);
200                 close(ph2t[0]);
201                 close(ph2t[1]);
202                 close(pt2h[0]);
203                 close(pt2h[1]);
204                 argv[0] = "samterm";
205                 exec(samterm, argv);
206                 fprint(2, "can't exec: ");
207                 perror(samterm);
208                 _exits("damn");
209         case -1:
210                 panic("can't fork samterm");
211         }
212         dup(pt2h[0], 0);
213         dup(ph2t[1], 1);
214         close(ph2t[0]);
215         close(ph2t[1]);
216         close(pt2h[0]);
217         close(pt2h[1]);
218 }
219
220 void
221 connectto(char *machine, char **argv)
222 {
223         int p1[2], p2[2];
224         char **av;
225         int ac;
226         
227         // count args
228         for(av = argv; *av; av++)
229                 ;
230         av = malloc(sizeof(char*)*((av-argv) + 5));
231         if(av == nil){
232                 dprint("out of memory\n");
233                 exits("fork/exec");
234         }
235         ac = 0;
236         av[ac++] = RX;
237         av[ac++] = machine;
238         av[ac++] = rsamname;
239         av[ac++] = "-R";
240         while(*argv)
241                 av[ac++] = *argv++;
242         av[ac] = 0;
243         if(pipe(p1)<0 || pipe(p2)<0){
244                 dprint("can't pipe\n");
245                 exits("pipe");
246         }
247         remotefd0 = p1[0];
248         remotefd1 = p2[1];
249         switch(fork()){
250         case 0:
251                 dup(p2[0], 0);
252                 dup(p1[1], 1);
253                 close(p1[0]);
254                 close(p1[1]);
255                 close(p2[0]);
256                 close(p2[1]);
257                 exec(RXPATH, av);
258                 dprint("can't exec %s\n", RXPATH);
259                 exits("exec");
260
261         case -1:
262                 dprint("can't fork\n");
263                 exits("fork");
264         }
265         free(av);
266         close(p1[1]);
267         close(p2[0]);
268 }
269
270 void
271 startup(char *machine, int Rflag, char **argv, char **files)
272 {
273         if(machine)
274                 connectto(machine, files);
275         if(!Rflag)
276                 bootterm(machine, argv);
277         downloaded = 1;
278         outTs(Hversion, VERSION);
279 }