]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/sam/io.c
usb lib: add maxpkt and ntds to Altc struct
[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                 free(name);
45                 return;
46         }
47         if(genc)
48                 free(genc);
49         genc = Strtoc(&genstr);
50         if((io=create(genc, 1, 0666L)) < 0)
51                 error_r(Ecreate, genc);
52         dprint("%s: ", genc);
53         if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0){
54                 free(name);
55                 error(Eappend);
56         }
57         n = writeio(f);
58         if(f->name.s[0]==0 || samename){
59                 if(addr.r.p1==0 && addr.r.p2==f->nc)
60                         f->cleanseq = f->seq;
61                 state(f, f->cleanseq==f->seq? Clean : Dirty);
62         }
63         if(newfile)
64                 dprint("(new file) ");
65         if(addr.r.p2>0 && filereadc(f, addr.r.p2-1)!='\n')
66                 warn(Wnotnewline);
67         closeio(n);
68         if(f->name.s[0]==0 || samename){
69                 if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){
70                         f->dev = dev;
71                         f->qidpath = qid;
72                         f->mtime = mtime;
73                         checkqid(f);
74                 }
75         }
76         free(name);
77 }
78
79 Posn
80 readio(File *f, int *nulls, int setdate, int toterm)
81 {
82         int n, b, w;
83         Rune *r;
84         Posn nt;
85         Posn p = addr.r.p2;
86         ulong dev;
87         uvlong qid;
88         long mtime;
89         char buf[BLOCKSIZE+1], *s;
90
91         *nulls = FALSE;
92         b = 0;
93         if(f->unread){
94                 nt = bufload(f, 0, io, nulls);
95                 if(toterm)
96                         raspload(f);
97         }else
98                 for(nt = 0; (n = read(io, buf+b, BLOCKSIZE-b))>0; nt+=(r-genbuf)){
99                         n += b;
100                         b = 0;
101                         r = genbuf;
102                         s = buf;
103                         while(n > 0){
104                                 if((*r = *(uchar*)s) < Runeself){
105                                         if(*r)
106                                                 r++;
107                                         else
108                                                 *nulls = TRUE;
109                                         --n;
110                                         s++;
111                                         continue;
112                                 }
113                                 if(fullrune(s, n)){
114                                         w = chartorune(r, s);
115                                         if(*r)
116                                                 r++;
117                                         else
118                                                 *nulls = TRUE;
119                                         n -= w;
120                                         s += w;
121                                         continue;
122                                 }
123                                 b = n;
124                                 memmove(buf, s, b);
125                                 break;
126                         }
127                         loginsert(f, p, genbuf, r-genbuf);
128                 }
129         if(b)
130                 *nulls = TRUE;
131         if(*nulls)
132                 warn(Wnulls);
133         if(setdate){
134                 if(statfd(io, &dev, &qid, &mtime, 0, 0) > 0){
135                         f->dev = dev;
136                         f->qidpath = qid;
137                         f->mtime = mtime;
138                         checkqid(f);
139                 }
140         }
141         return nt;
142 }
143
144 Posn
145 writeio(File *f)
146 {
147         int m, n;
148         Posn p = addr.r.p1;
149         char *c;
150
151         while(p < addr.r.p2){
152                 if(addr.r.p2-p>BLOCKSIZE)
153                         n = BLOCKSIZE;
154                 else
155                         n = addr.r.p2-p;
156                 bufread(f, p, genbuf, n);
157                 c = Strtoc(tmprstr(genbuf, n));
158                 m = strlen(c);
159                 if(Write(io, c, m) != m){
160                         free(c);
161                         if(p > 0)
162                                 p += n;
163                         break;
164                 }
165                 free(c);
166                 p += n;
167         }
168         return p-addr.r.p1;
169 }
170 void
171 closeio(Posn p)
172 {
173         close(io);
174         io = 0;
175         if(p >= 0)
176                 dprint("#%lud\n", p);
177 }
178
179 int     remotefd0 = 0;
180 int     remotefd1 = 1;
181
182 void
183 bootterm(char *machine, char **argv)
184 {
185         int ph2t[2], pt2h[2];
186
187         if(machine){
188                 dup(remotefd0, 0);
189                 dup(remotefd1, 1);
190                 close(remotefd0);
191                 close(remotefd1);
192                 argv[0] = "samterm";
193                 exec(samterm, argv);
194                 fprint(2, "can't exec: ");
195                 perror(samterm);
196                 _exits("damn");
197         }
198         if(pipe(ph2t)==-1 || pipe(pt2h)==-1)
199                 panic("pipe");
200         switch(fork()){
201         case 0:
202                 dup(ph2t[0], 0);
203                 dup(pt2h[1], 1);
204                 close(ph2t[0]);
205                 close(ph2t[1]);
206                 close(pt2h[0]);
207                 close(pt2h[1]);
208                 argv[0] = "samterm";
209                 exec(samterm, argv);
210                 fprint(2, "can't exec: ");
211                 perror(samterm);
212                 _exits("damn");
213         case -1:
214                 panic("can't fork samterm");
215         }
216         dup(pt2h[0], 0);
217         dup(ph2t[1], 1);
218         close(ph2t[0]);
219         close(ph2t[1]);
220         close(pt2h[0]);
221         close(pt2h[1]);
222 }
223
224 void
225 connectto(char *machine, char **argv)
226 {
227         int p1[2], p2[2];
228         char **av;
229         int ac;
230         
231         // count args
232         for(av = argv; *av; av++)
233                 ;
234         av = malloc(sizeof(char*)*((av-argv) + 5));
235         if(av == nil){
236                 dprint("out of memory\n");
237                 exits("fork/exec");
238         }
239         ac = 0;
240         av[ac++] = RX;
241         av[ac++] = machine;
242         av[ac++] = rsamname;
243         av[ac++] = "-R";
244         while(*argv)
245                 av[ac++] = *argv++;
246         av[ac] = 0;
247         if(pipe(p1)<0 || pipe(p2)<0){
248                 dprint("can't pipe\n");
249                 exits("pipe");
250         }
251         remotefd0 = p1[0];
252         remotefd1 = p2[1];
253         switch(fork()){
254         case 0:
255                 dup(p2[0], 0);
256                 dup(p1[1], 1);
257                 close(p1[0]);
258                 close(p1[1]);
259                 close(p2[0]);
260                 close(p2[1]);
261                 exec(RXPATH, av);
262                 dprint("can't exec %s\n", RXPATH);
263                 exits("exec");
264
265         case -1:
266                 dprint("can't fork\n");
267                 exits("fork");
268         }
269         free(av);
270         close(p1[1]);
271         close(p2[0]);
272 }
273
274 void
275 startup(char *machine, int Rflag, char **argv, char **files)
276 {
277         if(machine)
278                 connectto(machine, files);
279         if(!Rflag)
280                 bootterm(machine, argv);
281         downloaded = 1;
282         outTs(Hversion, VERSION);
283 }