Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
}