xref: /plan9/sys/src/cmd/fossil/Ccmd.c (revision 2cca75a1b2b8c6083390679d69d5c50cf66d9a01)
15e96a66cSDavid du Colombier #include "stdinc.h"
25e96a66cSDavid du Colombier 
35e96a66cSDavid du Colombier #include "9.h"
45e96a66cSDavid du Colombier 
55e96a66cSDavid du Colombier static struct {
65e96a66cSDavid du Colombier 	VtLock*	lock;
75e96a66cSDavid du Colombier 
85e96a66cSDavid du Colombier 	Con*	con;
95e96a66cSDavid du Colombier 	int	confd[2];
105e96a66cSDavid du Colombier 	ushort	tag;
115e96a66cSDavid du Colombier } cbox;
125e96a66cSDavid du Colombier 
135e96a66cSDavid du Colombier static ulong
cmd9pStrtoul(char * s)145e96a66cSDavid du Colombier cmd9pStrtoul(char* s)
155e96a66cSDavid du Colombier {
165e96a66cSDavid du Colombier 	if(strcmp(s, "~0") == 0)
175e96a66cSDavid du Colombier 		return ~0UL;
185e96a66cSDavid du Colombier 	return strtoul(s, 0, 0);
195e96a66cSDavid du Colombier }
205e96a66cSDavid du Colombier 
215e96a66cSDavid du Colombier static uvlong
cmd9pStrtoull(char * s)225e96a66cSDavid du Colombier cmd9pStrtoull(char* s)
235e96a66cSDavid du Colombier {
245e96a66cSDavid du Colombier 	if(strcmp(s, "~0") == 0)
255e96a66cSDavid du Colombier 		return ~0ULL;
265e96a66cSDavid du Colombier 	return strtoull(s, 0, 0);
275e96a66cSDavid du Colombier }
285e96a66cSDavid du Colombier 
295e96a66cSDavid du Colombier static int
cmd9pTag(Fcall *,int,char ** argv)305e96a66cSDavid du Colombier cmd9pTag(Fcall*, int, char **argv)
315e96a66cSDavid du Colombier {
325e96a66cSDavid du Colombier 	cbox.tag = strtoul(argv[0], 0, 0)-1;
335e96a66cSDavid du Colombier 
345e96a66cSDavid du Colombier 	return 1;
355e96a66cSDavid du Colombier }
365e96a66cSDavid du Colombier 
375e96a66cSDavid du Colombier static int
cmd9pTwstat(Fcall * f,int,char ** argv)385e96a66cSDavid du Colombier cmd9pTwstat(Fcall* f, int, char **argv)
395e96a66cSDavid du Colombier {
405e96a66cSDavid du Colombier 	Dir d;
415e96a66cSDavid du Colombier 	static uchar buf[DIRMAX];
425e96a66cSDavid du Colombier 
435e96a66cSDavid du Colombier 	memset(&d, 0, sizeof d);
445e96a66cSDavid du Colombier 	nulldir(&d);
455e96a66cSDavid du Colombier 	d.name = argv[1];
465e96a66cSDavid du Colombier 	d.uid = argv[2];
475e96a66cSDavid du Colombier 	d.gid = argv[3];
485e96a66cSDavid du Colombier 	d.mode = cmd9pStrtoul(argv[4]);
495e96a66cSDavid du Colombier 	d.mtime = cmd9pStrtoul(argv[5]);
505e96a66cSDavid du Colombier 	d.length = cmd9pStrtoull(argv[6]);
515e96a66cSDavid du Colombier 
525e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
535e96a66cSDavid du Colombier 	f->stat = buf;
545e96a66cSDavid du Colombier 	f->nstat = convD2M(&d, buf, sizeof buf);
555e96a66cSDavid du Colombier 	if(f->nstat < BIT16SZ){
565e96a66cSDavid du Colombier 		vtSetError("Twstat: convD2M failed (internal error)");
575e96a66cSDavid du Colombier 		return 0;
585e96a66cSDavid du Colombier 	}
595e96a66cSDavid du Colombier 
605e96a66cSDavid du Colombier 	return 1;
615e96a66cSDavid du Colombier }
625e96a66cSDavid du Colombier 
635e96a66cSDavid du Colombier static int
cmd9pTstat(Fcall * f,int,char ** argv)645e96a66cSDavid du Colombier cmd9pTstat(Fcall* f, int, char** argv)
655e96a66cSDavid du Colombier {
665e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
675e96a66cSDavid du Colombier 
685e96a66cSDavid du Colombier 	return 1;
695e96a66cSDavid du Colombier }
705e96a66cSDavid du Colombier 
715e96a66cSDavid du Colombier static int
cmd9pTremove(Fcall * f,int,char ** argv)725e96a66cSDavid du Colombier cmd9pTremove(Fcall* f, int, char** argv)
735e96a66cSDavid du Colombier {
745e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
755e96a66cSDavid du Colombier 
765e96a66cSDavid du Colombier 	return 1;
775e96a66cSDavid du Colombier }
785e96a66cSDavid du Colombier 
795e96a66cSDavid du Colombier static int
cmd9pTclunk(Fcall * f,int,char ** argv)805e96a66cSDavid du Colombier cmd9pTclunk(Fcall* f, int, char** argv)
815e96a66cSDavid du Colombier {
825e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
835e96a66cSDavid du Colombier 
845e96a66cSDavid du Colombier 	return 1;
855e96a66cSDavid du Colombier }
865e96a66cSDavid du Colombier 
875e96a66cSDavid du Colombier static int
cmd9pTwrite(Fcall * f,int,char ** argv)885e96a66cSDavid du Colombier cmd9pTwrite(Fcall* f, int, char** argv)
895e96a66cSDavid du Colombier {
905e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
915e96a66cSDavid du Colombier 	f->offset = strtoll(argv[1], 0, 0);
925e96a66cSDavid du Colombier 	f->data = argv[2];
935e96a66cSDavid du Colombier 	f->count = strlen(argv[2]);
945e96a66cSDavid du Colombier 
955e96a66cSDavid du Colombier 	return 1;
965e96a66cSDavid du Colombier }
975e96a66cSDavid du Colombier 
985e96a66cSDavid du Colombier static int
cmd9pTread(Fcall * f,int,char ** argv)995e96a66cSDavid du Colombier cmd9pTread(Fcall* f, int, char** argv)
1005e96a66cSDavid du Colombier {
1015e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
1025e96a66cSDavid du Colombier 	f->offset = strtoll(argv[1], 0, 0);
1035e96a66cSDavid du Colombier 	f->count = strtol(argv[2], 0, 0);
1045e96a66cSDavid du Colombier 
1055e96a66cSDavid du Colombier 	return 1;
1065e96a66cSDavid du Colombier }
1075e96a66cSDavid du Colombier 
1085e96a66cSDavid du Colombier static int
cmd9pTcreate(Fcall * f,int,char ** argv)1095e96a66cSDavid du Colombier cmd9pTcreate(Fcall* f, int, char** argv)
1105e96a66cSDavid du Colombier {
1115e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
1125e96a66cSDavid du Colombier 	f->name = argv[1];
1135e96a66cSDavid du Colombier 	f->perm = strtol(argv[2], 0, 8);
1145e96a66cSDavid du Colombier 	f->mode = strtol(argv[3], 0, 0);
1155e96a66cSDavid du Colombier 
1165e96a66cSDavid du Colombier 	return 1;
1175e96a66cSDavid du Colombier }
1185e96a66cSDavid du Colombier 
1195e96a66cSDavid du Colombier static int
cmd9pTopen(Fcall * f,int,char ** argv)1205e96a66cSDavid du Colombier cmd9pTopen(Fcall* f, int, char** argv)
1215e96a66cSDavid du Colombier {
1225e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
1235e96a66cSDavid du Colombier 	f->mode = strtol(argv[1], 0, 0);
1245e96a66cSDavid du Colombier 
1255e96a66cSDavid du Colombier 	return 1;
1265e96a66cSDavid du Colombier }
1275e96a66cSDavid du Colombier 
1285e96a66cSDavid du Colombier static int
cmd9pTwalk(Fcall * f,int argc,char ** argv)1295e96a66cSDavid du Colombier cmd9pTwalk(Fcall* f, int argc, char** argv)
1305e96a66cSDavid du Colombier {
1315e96a66cSDavid du Colombier 	int i;
1325e96a66cSDavid du Colombier 
1335e96a66cSDavid du Colombier 	if(argc < 2){
1345e96a66cSDavid du Colombier 		vtSetError("usage: Twalk tag fid newfid [name...]");
1355e96a66cSDavid du Colombier 		return 0;
1365e96a66cSDavid du Colombier 	}
1375e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
1385e96a66cSDavid du Colombier 	f->newfid = strtol(argv[1], 0, 0);
1395e96a66cSDavid du Colombier 	f->nwname = argc-2;
1405e96a66cSDavid du Colombier 	if(f->nwname > MAXWELEM){
1415e96a66cSDavid du Colombier 		vtSetError("Twalk: too many names");
1425e96a66cSDavid du Colombier 		return 0;
1435e96a66cSDavid du Colombier 	}
1445e96a66cSDavid du Colombier 	for(i = 0; i < argc-2; i++)
1455e96a66cSDavid du Colombier 		f->wname[i] = argv[2+i];
1465e96a66cSDavid du Colombier 
1475e96a66cSDavid du Colombier 	return 1;
1485e96a66cSDavid du Colombier }
1495e96a66cSDavid du Colombier 
1505e96a66cSDavid du Colombier static int
cmd9pTflush(Fcall * f,int,char ** argv)1515e96a66cSDavid du Colombier cmd9pTflush(Fcall* f, int, char** argv)
1525e96a66cSDavid du Colombier {
1535e96a66cSDavid du Colombier 	f->oldtag = strtol(argv[0], 0, 0);
1545e96a66cSDavid du Colombier 
1555e96a66cSDavid du Colombier 	return 1;
1565e96a66cSDavid du Colombier }
1575e96a66cSDavid du Colombier 
1585e96a66cSDavid du Colombier static int
cmd9pTattach(Fcall * f,int,char ** argv)1595e96a66cSDavid du Colombier cmd9pTattach(Fcall* f, int, char** argv)
1605e96a66cSDavid du Colombier {
1615e96a66cSDavid du Colombier 	f->fid = strtol(argv[0], 0, 0);
1625e96a66cSDavid du Colombier 	f->afid = strtol(argv[1], 0, 0);
1635e96a66cSDavid du Colombier 	f->uname = argv[2];
1645e96a66cSDavid du Colombier 	f->aname = argv[3];
1655e96a66cSDavid du Colombier 
1665e96a66cSDavid du Colombier 	return 1;
1675e96a66cSDavid du Colombier }
1685e96a66cSDavid du Colombier 
1695e96a66cSDavid du Colombier static int
cmd9pTauth(Fcall * f,int,char ** argv)1705e96a66cSDavid du Colombier cmd9pTauth(Fcall* f, int, char** argv)
1715e96a66cSDavid du Colombier {
1725e96a66cSDavid du Colombier 	f->afid = strtol(argv[0], 0, 0);
1735e96a66cSDavid du Colombier 	f->uname = argv[1];
1745e96a66cSDavid du Colombier 	f->aname = argv[2];
1755e96a66cSDavid du Colombier 
1765e96a66cSDavid du Colombier 	return 1;
1775e96a66cSDavid du Colombier }
1785e96a66cSDavid du Colombier 
1795e96a66cSDavid du Colombier static int
cmd9pTversion(Fcall * f,int,char ** argv)1805e96a66cSDavid du Colombier cmd9pTversion(Fcall* f, int, char** argv)
1815e96a66cSDavid du Colombier {
1825e96a66cSDavid du Colombier 	f->msize = strtoul(argv[0], 0, 0);
1835e96a66cSDavid du Colombier 	if(f->msize > cbox.con->msize){
1845e96a66cSDavid du Colombier 		vtSetError("msize too big");
1855e96a66cSDavid du Colombier 		return 0;
1865e96a66cSDavid du Colombier 	}
1875e96a66cSDavid du Colombier 	f->version = argv[1];
1885e96a66cSDavid du Colombier 
1895e96a66cSDavid du Colombier 	return 1;
1905e96a66cSDavid du Colombier }
1915e96a66cSDavid du Colombier 
1925e96a66cSDavid du Colombier typedef struct Cmd9p Cmd9p;
1935e96a66cSDavid du Colombier struct Cmd9p {
1945e96a66cSDavid du Colombier 	char*	name;
1955e96a66cSDavid du Colombier 	int	type;
1965e96a66cSDavid du Colombier 	int	argc;
1975e96a66cSDavid du Colombier 	char*	usage;
1985e96a66cSDavid du Colombier 	int	(*f)(Fcall*, int, char**);
1995e96a66cSDavid du Colombier };
2005e96a66cSDavid du Colombier 
2015e96a66cSDavid du Colombier static Cmd9p cmd9pTmsg[] = {
2025e96a66cSDavid du Colombier 	"Tversion", Tversion, 2, "msize version", cmd9pTversion,
2035e96a66cSDavid du Colombier 	"Tauth", Tauth, 3, "afid uname aname", cmd9pTauth,
2045e96a66cSDavid du Colombier 	"Tflush", Tflush, 1, "oldtag", cmd9pTflush,
2055e96a66cSDavid du Colombier 	"Tattach", Tattach, 4, "fid afid uname aname", cmd9pTattach,
2065e96a66cSDavid du Colombier 	"Twalk", Twalk, 0, "fid newfid [name...]", cmd9pTwalk,
2075e96a66cSDavid du Colombier 	"Topen", Topen, 2, "fid mode", cmd9pTopen,
2085e96a66cSDavid du Colombier 	"Tcreate", Tcreate, 4, "fid name perm mode", cmd9pTcreate,
2095e96a66cSDavid du Colombier 	"Tread", Tread, 3, "fid offset count", cmd9pTread,
2105e96a66cSDavid du Colombier 	"Twrite", Twrite, 3, "fid offset data", cmd9pTwrite,
2115e96a66cSDavid du Colombier 	"Tclunk", Tclunk, 1, "fid", cmd9pTclunk,
2125e96a66cSDavid du Colombier 	"Tremove", Tremove, 1, "fid", cmd9pTremove,
2135e96a66cSDavid du Colombier 	"Tstat", Tstat, 1, "fid", cmd9pTstat,
2145e96a66cSDavid du Colombier 	"Twstat", Twstat, 7, "fid name uid gid mode mtime length", cmd9pTwstat,
2155e96a66cSDavid du Colombier 	"nexttag", 0, 0, "", cmd9pTag,
2165e96a66cSDavid du Colombier };
2175e96a66cSDavid du Colombier 
2185e96a66cSDavid du Colombier static int
cmd9p(int argc,char * argv[])2195e96a66cSDavid du Colombier cmd9p(int argc, char* argv[])
2205e96a66cSDavid du Colombier {
2215e96a66cSDavid du Colombier 	int i, n;
2225e96a66cSDavid du Colombier 	Fcall f, t;
2235e96a66cSDavid du Colombier 	uchar *buf;
2245e96a66cSDavid du Colombier 	char *usage;
2255e96a66cSDavid du Colombier 	u32int msize;
2265e96a66cSDavid du Colombier 
2275e96a66cSDavid du Colombier 	usage = "usage: 9p T-message ...";
2285e96a66cSDavid du Colombier 
2295e96a66cSDavid du Colombier 	ARGBEGIN{
2305e96a66cSDavid du Colombier 	default:
2315e96a66cSDavid du Colombier 		return cliError(usage);
2325e96a66cSDavid du Colombier 	}ARGEND
2335e96a66cSDavid du Colombier 	if(argc < 1)
2345e96a66cSDavid du Colombier 		return cliError(usage);
2355e96a66cSDavid du Colombier 
2365e96a66cSDavid du Colombier 	for(i = 0; i < nelem(cmd9pTmsg); i++){
2375e96a66cSDavid du Colombier 		if(strcmp(cmd9pTmsg[i].name, argv[0]) == 0)
2385e96a66cSDavid du Colombier 			break;
2395e96a66cSDavid du Colombier 	}
2405e96a66cSDavid du Colombier 	if(i == nelem(cmd9pTmsg))
2415e96a66cSDavid du Colombier 		return cliError(usage);
2425e96a66cSDavid du Colombier 	argc--;
2435e96a66cSDavid du Colombier 	argv++;
2445e96a66cSDavid du Colombier 	if(cmd9pTmsg[i].argc && argc != cmd9pTmsg[i].argc){
2455e96a66cSDavid du Colombier 		vtSetError("usage: %s %s",
2465e96a66cSDavid du Colombier 			cmd9pTmsg[i].name, cmd9pTmsg[i].usage);
2475e96a66cSDavid du Colombier 		return 0;
2485e96a66cSDavid du Colombier 	}
2495e96a66cSDavid du Colombier 
2505e96a66cSDavid du Colombier 	memset(&t, 0, sizeof(t));
2515e96a66cSDavid du Colombier 	t.type = cmd9pTmsg[i].type;
2525e96a66cSDavid du Colombier 	if(t.type == Tversion)
2535e96a66cSDavid du Colombier 		t.tag = NOTAG;
2545e96a66cSDavid du Colombier 	else
2555e96a66cSDavid du Colombier 		t.tag = ++cbox.tag;
2565e96a66cSDavid du Colombier 	msize = cbox.con->msize;
2575e96a66cSDavid du Colombier 	if(!cmd9pTmsg[i].f(&t, argc, argv))
2585e96a66cSDavid du Colombier 		return 0;
2595e96a66cSDavid du Colombier 	buf = vtMemAlloc(msize);
2605e96a66cSDavid du Colombier 	n = convS2M(&t, buf, msize);
2615e96a66cSDavid du Colombier 	if(n <= BIT16SZ){
2625e96a66cSDavid du Colombier 		vtSetError("%s: convS2M error", cmd9pTmsg[i].name);
2635e96a66cSDavid du Colombier 		vtMemFree(buf);
2645e96a66cSDavid du Colombier 		return 0;
2655e96a66cSDavid du Colombier 	}
2665e96a66cSDavid du Colombier 	if(write(cbox.confd[0], buf, n) != n){
2675e96a66cSDavid du Colombier 		vtSetError("%s: write error: %r", cmd9pTmsg[i].name);
2685e96a66cSDavid du Colombier 		vtMemFree(buf);
2695e96a66cSDavid du Colombier 		return 0;
2705e96a66cSDavid du Colombier 	}
2715e96a66cSDavid du Colombier 	consPrint("\t-> %F\n", &t);
2725e96a66cSDavid du Colombier 
2735e96a66cSDavid du Colombier 	if((n = read9pmsg(cbox.confd[0], buf, msize)) <= 0){
2745e96a66cSDavid du Colombier 		vtSetError("%s: read error: %r", cmd9pTmsg[i].name);
2755e96a66cSDavid du Colombier 		vtMemFree(buf);
2765e96a66cSDavid du Colombier 		return 0;
2775e96a66cSDavid du Colombier 	}
2785e96a66cSDavid du Colombier 	if(convM2S(buf, n, &f) == 0){
2795e96a66cSDavid du Colombier 		vtSetError("%s: convM2S error", cmd9pTmsg[i].name);
2805e96a66cSDavid du Colombier 		vtMemFree(buf);
2815e96a66cSDavid du Colombier 		return 0;
2825e96a66cSDavid du Colombier 	}
2835e96a66cSDavid du Colombier 	consPrint("\t<- %F\n", &f);
2845e96a66cSDavid du Colombier 
2855e96a66cSDavid du Colombier 	vtMemFree(buf);
2865e96a66cSDavid du Colombier 	return 1;
2875e96a66cSDavid du Colombier }
2885e96a66cSDavid du Colombier 
2895e96a66cSDavid du Colombier static int
cmdDot(int argc,char * argv[])2905e96a66cSDavid du Colombier cmdDot(int argc, char* argv[])
2915e96a66cSDavid du Colombier {
2925e96a66cSDavid du Colombier 	long l;
2935e96a66cSDavid du Colombier 	Dir *dir;
2945e96a66cSDavid du Colombier 	int fd, r;
2955e96a66cSDavid du Colombier 	vlong length;
2965e96a66cSDavid du Colombier 	char *f, *p, *s, *usage;
2975e96a66cSDavid du Colombier 
2985e96a66cSDavid du Colombier 	usage = "usage: . file";
2995e96a66cSDavid du Colombier 
3005e96a66cSDavid du Colombier 	ARGBEGIN{
3015e96a66cSDavid du Colombier 	default:
3025e96a66cSDavid du Colombier 		return cliError(usage);
3035e96a66cSDavid du Colombier 	}ARGEND
3045e96a66cSDavid du Colombier 	if(argc != 1)
3055e96a66cSDavid du Colombier 		return cliError(usage);
3065e96a66cSDavid du Colombier 
3075e96a66cSDavid du Colombier 	if((dir = dirstat(argv[0])) == nil)
3085e96a66cSDavid du Colombier 		return cliError(". dirstat %s: %r", argv[0]);
3095e96a66cSDavid du Colombier 	length = dir->length;
3105e96a66cSDavid du Colombier 	free(dir);
3115e96a66cSDavid du Colombier 
31281cf8742SDavid du Colombier 	r = 1;
3135e96a66cSDavid du Colombier 	if(length != 0){
3145e96a66cSDavid du Colombier 		/*
3155e96a66cSDavid du Colombier 		 * Read the whole file in.
3165e96a66cSDavid du Colombier 		 */
3175e96a66cSDavid du Colombier 		if((fd = open(argv[0], OREAD)) < 0)
3185e96a66cSDavid du Colombier 			return cliError(". open %s: %r", argv[0]);
3195e96a66cSDavid du Colombier 		f = vtMemAlloc(dir->length+1);
3205e96a66cSDavid du Colombier 		if((l = read(fd, f, length)) < 0){
3215e96a66cSDavid du Colombier 			vtMemFree(f);
3225e96a66cSDavid du Colombier 			close(fd);
3235e96a66cSDavid du Colombier 			return cliError(". read %s: %r", argv[0]);
3245e96a66cSDavid du Colombier 		}
3255e96a66cSDavid du Colombier 		close(fd);
3265e96a66cSDavid du Colombier 		f[l] = '\0';
3275e96a66cSDavid du Colombier 
3285e96a66cSDavid du Colombier 		/*
3295e96a66cSDavid du Colombier 		 * Call cliExec() for each line.
3305e96a66cSDavid du Colombier 		 */
3315e96a66cSDavid du Colombier 		for(p = s = f; *p != '\0'; p++){
3325e96a66cSDavid du Colombier 			if(*p == '\n'){
3335e96a66cSDavid du Colombier 				*p = '\0';
33481cf8742SDavid du Colombier 				if(cliExec(s) == 0){
33581cf8742SDavid du Colombier 					r = 0;
33681cf8742SDavid du Colombier 					consPrint("%s: %R\n", s);
33781cf8742SDavid du Colombier 				}
3385e96a66cSDavid du Colombier 				s = p+1;
3395e96a66cSDavid du Colombier 			}
3405e96a66cSDavid du Colombier 		}
3415e96a66cSDavid du Colombier 		vtMemFree(f);
3425e96a66cSDavid du Colombier 	}
3435e96a66cSDavid du Colombier 
34481cf8742SDavid du Colombier 	if(r == 0)
34581cf8742SDavid du Colombier 		vtSetError("errors in . %#q", argv[0]);
3465e96a66cSDavid du Colombier 	return r;
3475e96a66cSDavid du Colombier }
3485e96a66cSDavid du Colombier 
3495e96a66cSDavid du Colombier static int
cmdDflag(int argc,char * argv[])3505e96a66cSDavid du Colombier cmdDflag(int argc, char* argv[])
3515e96a66cSDavid du Colombier {
3525e96a66cSDavid du Colombier 	char *usage;
3535e96a66cSDavid du Colombier 
3545e96a66cSDavid du Colombier 	usage = "usage: dflag";
3555e96a66cSDavid du Colombier 
3565e96a66cSDavid du Colombier 	ARGBEGIN{
3575e96a66cSDavid du Colombier 	default:
3585e96a66cSDavid du Colombier 		return cliError(usage);
3595e96a66cSDavid du Colombier 	}ARGEND
3605e96a66cSDavid du Colombier 	if(argc)
3615e96a66cSDavid du Colombier 		return cliError(usage);
3625e96a66cSDavid du Colombier 
3635e96a66cSDavid du Colombier 	Dflag ^= 1;
3645e96a66cSDavid du Colombier 	consPrint("dflag %d\n", Dflag);
3655e96a66cSDavid du Colombier 
3665e96a66cSDavid du Colombier 	return 1;
3675e96a66cSDavid du Colombier }
3685e96a66cSDavid du Colombier 
3695e96a66cSDavid du Colombier static int
cmdEcho(int argc,char * argv[])3705e96a66cSDavid du Colombier cmdEcho(int argc, char* argv[])
3715e96a66cSDavid du Colombier {
3725e96a66cSDavid du Colombier 	char *usage;
3735e96a66cSDavid du Colombier 	int i, nflag;
3745e96a66cSDavid du Colombier 
3755e96a66cSDavid du Colombier 	nflag = 0;
3765e96a66cSDavid du Colombier 	usage = "usage: echo [-n] ...";
3775e96a66cSDavid du Colombier 
3785e96a66cSDavid du Colombier 	ARGBEGIN{
3795e96a66cSDavid du Colombier 	default:
3805e96a66cSDavid du Colombier 		return cliError(usage);
3815e96a66cSDavid du Colombier 	case 'n':
3825e96a66cSDavid du Colombier 		nflag = 1;
3835e96a66cSDavid du Colombier 		break;
3845e96a66cSDavid du Colombier 	}ARGEND
3855e96a66cSDavid du Colombier 
3865e96a66cSDavid du Colombier 	for(i = 0; i < argc; i++){
3875e96a66cSDavid du Colombier 		if(i != 0)
3885e96a66cSDavid du Colombier 			consPrint(" %s", argv[i]);
3895e96a66cSDavid du Colombier 		else
3905e96a66cSDavid du Colombier 			consPrint(argv[i]);
3915e96a66cSDavid du Colombier 	}
3925e96a66cSDavid du Colombier 	if(!nflag)
3935e96a66cSDavid du Colombier 		consPrint("\n");
3945e96a66cSDavid du Colombier 
3955e96a66cSDavid du Colombier 	return 1;
3965e96a66cSDavid du Colombier }
3975e96a66cSDavid du Colombier 
398c3c4501eSDavid du Colombier static int
cmdBind(int argc,char * argv[])399c3c4501eSDavid du Colombier cmdBind(int argc, char* argv[])
400c3c4501eSDavid du Colombier {
401c3c4501eSDavid du Colombier 	ulong flag = 0;
402c3c4501eSDavid du Colombier 	char *usage;
403c3c4501eSDavid du Colombier 
404c3c4501eSDavid du Colombier 	usage = "usage: bind [-b|-a|-c|-bc|-ac] new old";
405c3c4501eSDavid du Colombier 
406c3c4501eSDavid du Colombier 	ARGBEGIN{
407c3c4501eSDavid du Colombier 	case 'a':
408c3c4501eSDavid du Colombier 		flag |= MAFTER;
409c3c4501eSDavid du Colombier 		break;
410c3c4501eSDavid du Colombier 	case 'b':
411c3c4501eSDavid du Colombier 		flag |= MBEFORE;
412c3c4501eSDavid du Colombier 		break;
413c3c4501eSDavid du Colombier 	case 'c':
414c3c4501eSDavid du Colombier 		flag |= MCREATE;
415c3c4501eSDavid du Colombier 		break;
416c3c4501eSDavid du Colombier 	default:
417c3c4501eSDavid du Colombier 		return cliError(usage);
418c3c4501eSDavid du Colombier 	}ARGEND
419c3c4501eSDavid du Colombier 
420c3c4501eSDavid du Colombier 	if(argc != 2 || (flag&MAFTER)&&(flag&MBEFORE))
421c3c4501eSDavid du Colombier 		return cliError(usage);
422c3c4501eSDavid du Colombier 
423c3c4501eSDavid du Colombier 	if(bind(argv[0], argv[1], flag) < 0){
424c3c4501eSDavid du Colombier 		/* try to give a less confusing error than the default */
425c3c4501eSDavid du Colombier 		if(access(argv[0], 0) < 0)
426c3c4501eSDavid du Colombier 			return cliError("bind: %s: %r", argv[0]);
427c3c4501eSDavid du Colombier 		else if(access(argv[1], 0) < 0)
428c3c4501eSDavid du Colombier 			return cliError("bind: %s: %r", argv[1]);
429c3c4501eSDavid du Colombier 		else
430c3c4501eSDavid du Colombier 			return cliError("bind %s %s: %r", argv[0], argv[1]);
431c3c4501eSDavid du Colombier 	}
432c3c4501eSDavid du Colombier 	return 1;
433c3c4501eSDavid du Colombier }
434c3c4501eSDavid du Colombier 
4355e96a66cSDavid du Colombier int
cmdInit(void)4365e96a66cSDavid du Colombier cmdInit(void)
4375e96a66cSDavid du Colombier {
4385e96a66cSDavid du Colombier 	cbox.lock = vtLockAlloc();
4395e96a66cSDavid du Colombier 	cbox.confd[0] = cbox.confd[1] = -1;
4405e96a66cSDavid du Colombier 
4415e96a66cSDavid du Colombier 	cliAddCmd(".", cmdDot);
4425e96a66cSDavid du Colombier 	cliAddCmd("9p", cmd9p);
4435e96a66cSDavid du Colombier 	cliAddCmd("dflag", cmdDflag);
4445e96a66cSDavid du Colombier 	cliAddCmd("echo", cmdEcho);
445c3c4501eSDavid du Colombier 	cliAddCmd("bind", cmdBind);
4465e96a66cSDavid du Colombier 
4475e96a66cSDavid du Colombier 	if(pipe(cbox.confd) < 0)
4485e96a66cSDavid du Colombier 		return 0;
449*2cca75a1SDavid du Colombier 	if((cbox.con = conAlloc(cbox.confd[1], "console", 0)) == nil){
4505e96a66cSDavid du Colombier 		close(cbox.confd[0]);
4515e96a66cSDavid du Colombier 		close(cbox.confd[1]);
4525e96a66cSDavid du Colombier 		cbox.confd[0] = cbox.confd[1] = -1;
4535e96a66cSDavid du Colombier 		return 0;
4545e96a66cSDavid du Colombier 
4555e96a66cSDavid du Colombier 	}
4565e96a66cSDavid du Colombier 	cbox.con->isconsole = 1;
4575e96a66cSDavid du Colombier 
4585e96a66cSDavid du Colombier 	return 1;
4595e96a66cSDavid du Colombier }
460