xref: /plan9-contrib/sys/src/cmd/fossil/Ccmd.c (revision 5e96a66c77eb9140492ca53f857cbbf108e128ed)
1*5e96a66cSDavid du Colombier #include "stdinc.h"
2*5e96a66cSDavid du Colombier 
3*5e96a66cSDavid du Colombier #include "9.h"
4*5e96a66cSDavid du Colombier 
5*5e96a66cSDavid du Colombier static struct {
6*5e96a66cSDavid du Colombier 	VtLock*	lock;
7*5e96a66cSDavid du Colombier 
8*5e96a66cSDavid du Colombier 	Con*	con;
9*5e96a66cSDavid du Colombier 	int	confd[2];
10*5e96a66cSDavid du Colombier 	ushort	tag;
11*5e96a66cSDavid du Colombier } cbox;
12*5e96a66cSDavid du Colombier 
13*5e96a66cSDavid du Colombier static ulong
14*5e96a66cSDavid du Colombier cmd9pStrtoul(char* s)
15*5e96a66cSDavid du Colombier {
16*5e96a66cSDavid du Colombier 	if(strcmp(s, "~0") == 0)
17*5e96a66cSDavid du Colombier 		return ~0UL;
18*5e96a66cSDavid du Colombier 	return strtoul(s, 0, 0);
19*5e96a66cSDavid du Colombier }
20*5e96a66cSDavid du Colombier 
21*5e96a66cSDavid du Colombier static uvlong
22*5e96a66cSDavid du Colombier cmd9pStrtoull(char* s)
23*5e96a66cSDavid du Colombier {
24*5e96a66cSDavid du Colombier 	if(strcmp(s, "~0") == 0)
25*5e96a66cSDavid du Colombier 		return ~0ULL;
26*5e96a66cSDavid du Colombier 	return strtoull(s, 0, 0);
27*5e96a66cSDavid du Colombier }
28*5e96a66cSDavid du Colombier 
29*5e96a66cSDavid du Colombier static int
30*5e96a66cSDavid du Colombier cmd9pTag(Fcall*, int, char **argv)
31*5e96a66cSDavid du Colombier {
32*5e96a66cSDavid du Colombier 	cbox.tag = strtoul(argv[0], 0, 0)-1;
33*5e96a66cSDavid du Colombier 
34*5e96a66cSDavid du Colombier 	return 1;
35*5e96a66cSDavid du Colombier }
36*5e96a66cSDavid du Colombier 
37*5e96a66cSDavid du Colombier static int
38*5e96a66cSDavid du Colombier cmd9pTwstat(Fcall* f, int, char **argv)
39*5e96a66cSDavid du Colombier {
40*5e96a66cSDavid du Colombier 	Dir d;
41*5e96a66cSDavid du Colombier 	static uchar buf[DIRMAX];
42*5e96a66cSDavid du Colombier 
43*5e96a66cSDavid du Colombier 	memset(&d, 0, sizeof d);
44*5e96a66cSDavid du Colombier 	nulldir(&d);
45*5e96a66cSDavid du Colombier 	d.name = argv[1];
46*5e96a66cSDavid du Colombier 	d.uid = argv[2];
47*5e96a66cSDavid du Colombier 	d.gid = argv[3];
48*5e96a66cSDavid du Colombier 	d.mode = cmd9pStrtoul(argv[4]);
49*5e96a66cSDavid du Colombier 	d.mtime = cmd9pStrtoul(argv[5]);
50*5e96a66cSDavid du Colombier 	d.length = cmd9pStrtoull(argv[6]);
51*5e96a66cSDavid du Colombier 
52*5e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
53*5e96a66cSDavid du Colombier 	f->stat = buf;
54*5e96a66cSDavid du Colombier 	f->nstat = convD2M(&d, buf, sizeof buf);
55*5e96a66cSDavid du Colombier 	if(f->nstat < BIT16SZ){
56*5e96a66cSDavid du Colombier 		vtSetError("Twstat: convD2M failed (internal error)");
57*5e96a66cSDavid du Colombier 		return 0;
58*5e96a66cSDavid du Colombier 	}
59*5e96a66cSDavid du Colombier 
60*5e96a66cSDavid du Colombier 	return 1;
61*5e96a66cSDavid du Colombier }
62*5e96a66cSDavid du Colombier 
63*5e96a66cSDavid du Colombier static int
64*5e96a66cSDavid du Colombier cmd9pTstat(Fcall* f, int, char** argv)
65*5e96a66cSDavid du Colombier {
66*5e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
67*5e96a66cSDavid du Colombier 
68*5e96a66cSDavid du Colombier 	return 1;
69*5e96a66cSDavid du Colombier }
70*5e96a66cSDavid du Colombier 
71*5e96a66cSDavid du Colombier static int
72*5e96a66cSDavid du Colombier cmd9pTremove(Fcall* f, int, char** argv)
73*5e96a66cSDavid du Colombier {
74*5e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
75*5e96a66cSDavid du Colombier 
76*5e96a66cSDavid du Colombier 	return 1;
77*5e96a66cSDavid du Colombier }
78*5e96a66cSDavid du Colombier 
79*5e96a66cSDavid du Colombier static int
80*5e96a66cSDavid du Colombier cmd9pTclunk(Fcall* f, int, char** argv)
81*5e96a66cSDavid du Colombier {
82*5e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
83*5e96a66cSDavid du Colombier 
84*5e96a66cSDavid du Colombier 	return 1;
85*5e96a66cSDavid du Colombier }
86*5e96a66cSDavid du Colombier 
87*5e96a66cSDavid du Colombier static int
88*5e96a66cSDavid du Colombier cmd9pTwrite(Fcall* f, int, char** argv)
89*5e96a66cSDavid du Colombier {
90*5e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
91*5e96a66cSDavid du Colombier 	f->offset = strtoll(argv[1], 0, 0);
92*5e96a66cSDavid du Colombier 	f->data = argv[2];
93*5e96a66cSDavid du Colombier 	f->count = strlen(argv[2]);
94*5e96a66cSDavid du Colombier 
95*5e96a66cSDavid du Colombier 	return 1;
96*5e96a66cSDavid du Colombier }
97*5e96a66cSDavid du Colombier 
98*5e96a66cSDavid du Colombier static int
99*5e96a66cSDavid du Colombier cmd9pTread(Fcall* f, int, char** argv)
100*5e96a66cSDavid du Colombier {
101*5e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
102*5e96a66cSDavid du Colombier 	f->offset = strtoll(argv[1], 0, 0);
103*5e96a66cSDavid du Colombier 	f->count = strtol(argv[2], 0, 0);
104*5e96a66cSDavid du Colombier 
105*5e96a66cSDavid du Colombier 	return 1;
106*5e96a66cSDavid du Colombier }
107*5e96a66cSDavid du Colombier 
108*5e96a66cSDavid du Colombier static int
109*5e96a66cSDavid du Colombier cmd9pTcreate(Fcall* f, int, char** argv)
110*5e96a66cSDavid du Colombier {
111*5e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
112*5e96a66cSDavid du Colombier 	f->name = argv[1];
113*5e96a66cSDavid du Colombier 	f->perm = strtol(argv[2], 0, 8);
114*5e96a66cSDavid du Colombier 	f->mode = strtol(argv[3], 0, 0);
115*5e96a66cSDavid du Colombier 
116*5e96a66cSDavid du Colombier 	return 1;
117*5e96a66cSDavid du Colombier }
118*5e96a66cSDavid du Colombier 
119*5e96a66cSDavid du Colombier static int
120*5e96a66cSDavid du Colombier cmd9pTopen(Fcall* f, int, char** argv)
121*5e96a66cSDavid du Colombier {
122*5e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
123*5e96a66cSDavid du Colombier 	f->mode = strtol(argv[1], 0, 0);
124*5e96a66cSDavid du Colombier 
125*5e96a66cSDavid du Colombier 	return 1;
126*5e96a66cSDavid du Colombier }
127*5e96a66cSDavid du Colombier 
128*5e96a66cSDavid du Colombier static int
129*5e96a66cSDavid du Colombier cmd9pTwalk(Fcall* f, int argc, char** argv)
130*5e96a66cSDavid du Colombier {
131*5e96a66cSDavid du Colombier 	int i;
132*5e96a66cSDavid du Colombier 
133*5e96a66cSDavid du Colombier 	if(argc < 2){
134*5e96a66cSDavid du Colombier 		vtSetError("usage: Twalk tag fid newfid [name...]");
135*5e96a66cSDavid du Colombier 		return 0;
136*5e96a66cSDavid du Colombier 	}
137*5e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
138*5e96a66cSDavid du Colombier 	f->newfid = strtol(argv[1], 0, 0);
139*5e96a66cSDavid du Colombier 	f->nwname = argc-2;
140*5e96a66cSDavid du Colombier 	if(f->nwname > MAXWELEM){
141*5e96a66cSDavid du Colombier 		vtSetError("Twalk: too many names");
142*5e96a66cSDavid du Colombier 		return 0;
143*5e96a66cSDavid du Colombier 	}
144*5e96a66cSDavid du Colombier 	for(i = 0; i < argc-2; i++)
145*5e96a66cSDavid du Colombier 		f->wname[i] = argv[2+i];
146*5e96a66cSDavid du Colombier 
147*5e96a66cSDavid du Colombier 	return 1;
148*5e96a66cSDavid du Colombier }
149*5e96a66cSDavid du Colombier 
150*5e96a66cSDavid du Colombier static int
151*5e96a66cSDavid du Colombier cmd9pTflush(Fcall* f, int, char** argv)
152*5e96a66cSDavid du Colombier {
153*5e96a66cSDavid du Colombier 	f->oldtag = strtol(argv[0], 0, 0);
154*5e96a66cSDavid du Colombier 
155*5e96a66cSDavid du Colombier 	return 1;
156*5e96a66cSDavid du Colombier }
157*5e96a66cSDavid du Colombier 
158*5e96a66cSDavid du Colombier static int
159*5e96a66cSDavid du Colombier cmd9pTattach(Fcall* f, int, char** argv)
160*5e96a66cSDavid du Colombier {
161*5e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
162*5e96a66cSDavid du Colombier 	f->afid = strtol(argv[1], 0, 0);
163*5e96a66cSDavid du Colombier 	f->uname = argv[2];
164*5e96a66cSDavid du Colombier 	f->aname = argv[3];
165*5e96a66cSDavid du Colombier 
166*5e96a66cSDavid du Colombier 	return 1;
167*5e96a66cSDavid du Colombier }
168*5e96a66cSDavid du Colombier 
169*5e96a66cSDavid du Colombier static int
170*5e96a66cSDavid du Colombier cmd9pTauth(Fcall* f, int, char** argv)
171*5e96a66cSDavid du Colombier {
172*5e96a66cSDavid du Colombier 	f->afid = strtol(argv[0], 0, 0);
173*5e96a66cSDavid du Colombier 	f->uname = argv[1];
174*5e96a66cSDavid du Colombier 	f->aname = argv[2];
175*5e96a66cSDavid du Colombier 
176*5e96a66cSDavid du Colombier 	return 1;
177*5e96a66cSDavid du Colombier }
178*5e96a66cSDavid du Colombier 
179*5e96a66cSDavid du Colombier static int
180*5e96a66cSDavid du Colombier cmd9pTversion(Fcall* f, int, char** argv)
181*5e96a66cSDavid du Colombier {
182*5e96a66cSDavid du Colombier 	f->msize = strtoul(argv[0], 0, 0);
183*5e96a66cSDavid du Colombier 	if(f->msize > cbox.con->msize){
184*5e96a66cSDavid du Colombier 		vtSetError("msize too big");
185*5e96a66cSDavid du Colombier 		return 0;
186*5e96a66cSDavid du Colombier 	}
187*5e96a66cSDavid du Colombier 	f->version = argv[1];
188*5e96a66cSDavid du Colombier 
189*5e96a66cSDavid du Colombier 	return 1;
190*5e96a66cSDavid du Colombier }
191*5e96a66cSDavid du Colombier 
192*5e96a66cSDavid du Colombier typedef struct Cmd9p Cmd9p;
193*5e96a66cSDavid du Colombier struct Cmd9p {
194*5e96a66cSDavid du Colombier 	char*	name;
195*5e96a66cSDavid du Colombier 	int	type;
196*5e96a66cSDavid du Colombier 	int	argc;
197*5e96a66cSDavid du Colombier 	char*	usage;
198*5e96a66cSDavid du Colombier 	int	(*f)(Fcall*, int, char**);
199*5e96a66cSDavid du Colombier };
200*5e96a66cSDavid du Colombier 
201*5e96a66cSDavid du Colombier static Cmd9p cmd9pTmsg[] = {
202*5e96a66cSDavid du Colombier 	"Tversion", Tversion, 2, "msize version", cmd9pTversion,
203*5e96a66cSDavid du Colombier 	"Tauth", Tauth, 3, "afid uname aname", cmd9pTauth,
204*5e96a66cSDavid du Colombier 	"Tflush", Tflush, 1, "oldtag", cmd9pTflush,
205*5e96a66cSDavid du Colombier 	"Tattach", Tattach, 4, "fid afid uname aname", cmd9pTattach,
206*5e96a66cSDavid du Colombier 	"Twalk", Twalk, 0, "fid newfid [name...]", cmd9pTwalk,
207*5e96a66cSDavid du Colombier 	"Topen", Topen, 2, "fid mode", cmd9pTopen,
208*5e96a66cSDavid du Colombier 	"Tcreate", Tcreate, 4, "fid name perm mode", cmd9pTcreate,
209*5e96a66cSDavid du Colombier 	"Tread", Tread, 3, "fid offset count", cmd9pTread,
210*5e96a66cSDavid du Colombier 	"Twrite", Twrite, 3, "fid offset data", cmd9pTwrite,
211*5e96a66cSDavid du Colombier 	"Tclunk", Tclunk, 1, "fid", cmd9pTclunk,
212*5e96a66cSDavid du Colombier 	"Tremove", Tremove, 1, "fid", cmd9pTremove,
213*5e96a66cSDavid du Colombier 	"Tstat", Tstat, 1, "fid", cmd9pTstat,
214*5e96a66cSDavid du Colombier 	"Twstat", Twstat, 7, "fid name uid gid mode mtime length", cmd9pTwstat,
215*5e96a66cSDavid du Colombier 	"nexttag", 0, 0, "", cmd9pTag,
216*5e96a66cSDavid du Colombier };
217*5e96a66cSDavid du Colombier 
218*5e96a66cSDavid du Colombier static int
219*5e96a66cSDavid du Colombier cmd9p(int argc, char* argv[])
220*5e96a66cSDavid du Colombier {
221*5e96a66cSDavid du Colombier 	int i, n;
222*5e96a66cSDavid du Colombier 	Fcall f, t;
223*5e96a66cSDavid du Colombier 	uchar *buf;
224*5e96a66cSDavid du Colombier 	char *usage;
225*5e96a66cSDavid du Colombier 	u32int msize;
226*5e96a66cSDavid du Colombier 
227*5e96a66cSDavid du Colombier 	usage = "usage: 9p T-message ...";
228*5e96a66cSDavid du Colombier 
229*5e96a66cSDavid du Colombier 	ARGBEGIN{
230*5e96a66cSDavid du Colombier 	default:
231*5e96a66cSDavid du Colombier 		return cliError(usage);
232*5e96a66cSDavid du Colombier 	}ARGEND
233*5e96a66cSDavid du Colombier 	if(argc < 1)
234*5e96a66cSDavid du Colombier 		return cliError(usage);
235*5e96a66cSDavid du Colombier 
236*5e96a66cSDavid du Colombier 	for(i = 0; i < nelem(cmd9pTmsg); i++){
237*5e96a66cSDavid du Colombier 		if(strcmp(cmd9pTmsg[i].name, argv[0]) == 0)
238*5e96a66cSDavid du Colombier 			break;
239*5e96a66cSDavid du Colombier 	}
240*5e96a66cSDavid du Colombier 	if(i == nelem(cmd9pTmsg))
241*5e96a66cSDavid du Colombier 		return cliError(usage);
242*5e96a66cSDavid du Colombier 	argc--;
243*5e96a66cSDavid du Colombier 	argv++;
244*5e96a66cSDavid du Colombier 	if(cmd9pTmsg[i].argc && argc != cmd9pTmsg[i].argc){
245*5e96a66cSDavid du Colombier 		vtSetError("usage: %s %s",
246*5e96a66cSDavid du Colombier 			cmd9pTmsg[i].name, cmd9pTmsg[i].usage);
247*5e96a66cSDavid du Colombier 		return 0;
248*5e96a66cSDavid du Colombier 	}
249*5e96a66cSDavid du Colombier 
250*5e96a66cSDavid du Colombier 	memset(&t, 0, sizeof(t));
251*5e96a66cSDavid du Colombier 	t.type = cmd9pTmsg[i].type;
252*5e96a66cSDavid du Colombier 	if(t.type == Tversion)
253*5e96a66cSDavid du Colombier 		t.tag = NOTAG;
254*5e96a66cSDavid du Colombier 	else
255*5e96a66cSDavid du Colombier 		t.tag = ++cbox.tag;
256*5e96a66cSDavid du Colombier 	msize = cbox.con->msize;
257*5e96a66cSDavid du Colombier 	if(!cmd9pTmsg[i].f(&t, argc, argv))
258*5e96a66cSDavid du Colombier 		return 0;
259*5e96a66cSDavid du Colombier 	buf = vtMemAlloc(msize);
260*5e96a66cSDavid du Colombier 	n = convS2M(&t, buf, msize);
261*5e96a66cSDavid du Colombier 	if(n <= BIT16SZ){
262*5e96a66cSDavid du Colombier 		vtSetError("%s: convS2M error", cmd9pTmsg[i].name);
263*5e96a66cSDavid du Colombier 		vtMemFree(buf);
264*5e96a66cSDavid du Colombier 		return 0;
265*5e96a66cSDavid du Colombier 	}
266*5e96a66cSDavid du Colombier 	if(write(cbox.confd[0], buf, n) != n){
267*5e96a66cSDavid du Colombier 		vtSetError("%s: write error: %r", cmd9pTmsg[i].name);
268*5e96a66cSDavid du Colombier 		vtMemFree(buf);
269*5e96a66cSDavid du Colombier 		return 0;
270*5e96a66cSDavid du Colombier 	}
271*5e96a66cSDavid du Colombier 	consPrint("\t-> %F\n", &t);
272*5e96a66cSDavid du Colombier 
273*5e96a66cSDavid du Colombier 	if((n = read9pmsg(cbox.confd[0], buf, msize)) <= 0){
274*5e96a66cSDavid du Colombier 		vtSetError("%s: read error: %r", cmd9pTmsg[i].name);
275*5e96a66cSDavid du Colombier 		vtMemFree(buf);
276*5e96a66cSDavid du Colombier 		return 0;
277*5e96a66cSDavid du Colombier 	}
278*5e96a66cSDavid du Colombier 	if(convM2S(buf, n, &f) == 0){
279*5e96a66cSDavid du Colombier 		vtSetError("%s: convM2S error", cmd9pTmsg[i].name);
280*5e96a66cSDavid du Colombier 		vtMemFree(buf);
281*5e96a66cSDavid du Colombier 		return 0;
282*5e96a66cSDavid du Colombier 	}
283*5e96a66cSDavid du Colombier 	consPrint("\t<- %F\n", &f);
284*5e96a66cSDavid du Colombier 
285*5e96a66cSDavid du Colombier 	vtMemFree(buf);
286*5e96a66cSDavid du Colombier 	return 1;
287*5e96a66cSDavid du Colombier }
288*5e96a66cSDavid du Colombier 
289*5e96a66cSDavid du Colombier static int
290*5e96a66cSDavid du Colombier cmdDot(int argc, char* argv[])
291*5e96a66cSDavid du Colombier {
292*5e96a66cSDavid du Colombier 	long l;
293*5e96a66cSDavid du Colombier 	Dir *dir;
294*5e96a66cSDavid du Colombier 	int fd, r;
295*5e96a66cSDavid du Colombier 	vlong length;
296*5e96a66cSDavid du Colombier 	char *f, *p, *s, *usage;
297*5e96a66cSDavid du Colombier 
298*5e96a66cSDavid du Colombier 	usage = "usage: . file";
299*5e96a66cSDavid du Colombier 
300*5e96a66cSDavid du Colombier 	ARGBEGIN{
301*5e96a66cSDavid du Colombier 	default:
302*5e96a66cSDavid du Colombier 		return cliError(usage);
303*5e96a66cSDavid du Colombier 	}ARGEND
304*5e96a66cSDavid du Colombier 	if(argc != 1)
305*5e96a66cSDavid du Colombier 		return cliError(usage);
306*5e96a66cSDavid du Colombier 
307*5e96a66cSDavid du Colombier 	if((dir = dirstat(argv[0])) == nil)
308*5e96a66cSDavid du Colombier 		return cliError(". dirstat %s: %r", argv[0]);
309*5e96a66cSDavid du Colombier 	length = dir->length;
310*5e96a66cSDavid du Colombier 	free(dir);
311*5e96a66cSDavid du Colombier 
312*5e96a66cSDavid du Colombier 	r = 0;
313*5e96a66cSDavid du Colombier 	if(length != 0){
314*5e96a66cSDavid du Colombier 		/*
315*5e96a66cSDavid du Colombier 		 * Read the whole file in.
316*5e96a66cSDavid du Colombier 		 */
317*5e96a66cSDavid du Colombier 		if((fd = open(argv[0], OREAD)) < 0)
318*5e96a66cSDavid du Colombier 			return cliError(". open %s: %r", argv[0]);
319*5e96a66cSDavid du Colombier 		f = vtMemAlloc(dir->length+1);
320*5e96a66cSDavid du Colombier 		if((l = read(fd, f, length)) < 0){
321*5e96a66cSDavid du Colombier 			vtMemFree(f);
322*5e96a66cSDavid du Colombier 			close(fd);
323*5e96a66cSDavid du Colombier 			return cliError(". read %s: %r", argv[0]);
324*5e96a66cSDavid du Colombier 		}
325*5e96a66cSDavid du Colombier 		close(fd);
326*5e96a66cSDavid du Colombier 		f[l] = '\0';
327*5e96a66cSDavid du Colombier 
328*5e96a66cSDavid du Colombier 		/*
329*5e96a66cSDavid du Colombier 		 * Call cliExec() for each line.
330*5e96a66cSDavid du Colombier 		 */
331*5e96a66cSDavid du Colombier 		for(p = s = f; *p != '\0'; p++){
332*5e96a66cSDavid du Colombier 			if(*p == '\n'){
333*5e96a66cSDavid du Colombier 				*p = '\0';
334*5e96a66cSDavid du Colombier 				if((r = cliExec(s)) == 0)
335*5e96a66cSDavid du Colombier 					break;
336*5e96a66cSDavid du Colombier 				s = p+1;
337*5e96a66cSDavid du Colombier 			}
338*5e96a66cSDavid du Colombier 		}
339*5e96a66cSDavid du Colombier 		vtMemFree(f);
340*5e96a66cSDavid du Colombier 	}
341*5e96a66cSDavid du Colombier 
342*5e96a66cSDavid du Colombier 	return r;
343*5e96a66cSDavid du Colombier }
344*5e96a66cSDavid du Colombier 
345*5e96a66cSDavid du Colombier static int
346*5e96a66cSDavid du Colombier cmdDflag(int argc, char* argv[])
347*5e96a66cSDavid du Colombier {
348*5e96a66cSDavid du Colombier 	char *usage;
349*5e96a66cSDavid du Colombier 
350*5e96a66cSDavid du Colombier 	usage = "usage: dflag";
351*5e96a66cSDavid du Colombier 
352*5e96a66cSDavid du Colombier 	ARGBEGIN{
353*5e96a66cSDavid du Colombier 	default:
354*5e96a66cSDavid du Colombier 		return cliError(usage);
355*5e96a66cSDavid du Colombier 	}ARGEND
356*5e96a66cSDavid du Colombier 	if(argc)
357*5e96a66cSDavid du Colombier 		return cliError(usage);
358*5e96a66cSDavid du Colombier 
359*5e96a66cSDavid du Colombier 	Dflag ^= 1;
360*5e96a66cSDavid du Colombier 	consPrint("dflag %d\n", Dflag);
361*5e96a66cSDavid du Colombier 
362*5e96a66cSDavid du Colombier 	return 1;
363*5e96a66cSDavid du Colombier }
364*5e96a66cSDavid du Colombier 
365*5e96a66cSDavid du Colombier static int
366*5e96a66cSDavid du Colombier cmdEcho(int argc, char* argv[])
367*5e96a66cSDavid du Colombier {
368*5e96a66cSDavid du Colombier 	char *usage;
369*5e96a66cSDavid du Colombier 	int i, nflag;
370*5e96a66cSDavid du Colombier 
371*5e96a66cSDavid du Colombier 	nflag = 0;
372*5e96a66cSDavid du Colombier 	usage = "usage: echo [-n] ...";
373*5e96a66cSDavid du Colombier 
374*5e96a66cSDavid du Colombier 	ARGBEGIN{
375*5e96a66cSDavid du Colombier 	default:
376*5e96a66cSDavid du Colombier 		return cliError(usage);
377*5e96a66cSDavid du Colombier 	case 'n':
378*5e96a66cSDavid du Colombier 		nflag = 1;
379*5e96a66cSDavid du Colombier 		break;
380*5e96a66cSDavid du Colombier 	}ARGEND
381*5e96a66cSDavid du Colombier 
382*5e96a66cSDavid du Colombier 	for(i = 0; i < argc; i++){
383*5e96a66cSDavid du Colombier 		if(i != 0)
384*5e96a66cSDavid du Colombier 			consPrint(" %s", argv[i]);
385*5e96a66cSDavid du Colombier 		else
386*5e96a66cSDavid du Colombier 			consPrint(argv[i]);
387*5e96a66cSDavid du Colombier 	}
388*5e96a66cSDavid du Colombier 	if(!nflag)
389*5e96a66cSDavid du Colombier 		consPrint("\n");
390*5e96a66cSDavid du Colombier 
391*5e96a66cSDavid du Colombier 	return 1;
392*5e96a66cSDavid du Colombier }
393*5e96a66cSDavid du Colombier 
394*5e96a66cSDavid du Colombier int
395*5e96a66cSDavid du Colombier cmdInit(void)
396*5e96a66cSDavid du Colombier {
397*5e96a66cSDavid du Colombier 	cbox.lock = vtLockAlloc();
398*5e96a66cSDavid du Colombier 	cbox.confd[0] = cbox.confd[1] = -1;
399*5e96a66cSDavid du Colombier 
400*5e96a66cSDavid du Colombier 	cliAddCmd(".", cmdDot);
401*5e96a66cSDavid du Colombier 	cliAddCmd("9p", cmd9p);
402*5e96a66cSDavid du Colombier 	cliAddCmd("dflag", cmdDflag);
403*5e96a66cSDavid du Colombier 	cliAddCmd("echo", cmdEcho);
404*5e96a66cSDavid du Colombier 
405*5e96a66cSDavid du Colombier 	if(pipe(cbox.confd) < 0)
406*5e96a66cSDavid du Colombier 		return 0;
407*5e96a66cSDavid du Colombier 	if((cbox.con = conAlloc(cbox.confd[1], "internal-command")) == nil){
408*5e96a66cSDavid du Colombier 		close(cbox.confd[0]);
409*5e96a66cSDavid du Colombier 		close(cbox.confd[1]);
410*5e96a66cSDavid du Colombier 		cbox.confd[0] = cbox.confd[1] = -1;
411*5e96a66cSDavid du Colombier 		return 0;
412*5e96a66cSDavid du Colombier 
413*5e96a66cSDavid du Colombier 	}
414*5e96a66cSDavid du Colombier 	cbox.con->isconsole = 1;
415*5e96a66cSDavid du Colombier 
416*5e96a66cSDavid du Colombier 	return 1;
417*5e96a66cSDavid du Colombier }
418