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 <u.h>
2
#include <libc.h>
3
#include <fcall.h>
4
#include <thread.h>
5
#include <9p.h>
6
 
7
/*
8
 * Generous estimate of number of fields, including terminal nil pointer
9
 */
10
static int
11
ncmdfield(char *p, int n)
12
{
13
	int white, nwhite;
14
	char *ep;
15
	int nf;
16
 
17
	if(p == nil)
18
		return 1;
19
 
20
	nf = 0;
21
	ep = p+n;
22
	white = 1;	/* first text will start field */
23
	while(p < ep){
24
		nwhite = (strchr(" \t\r\n", *p++ & 0xFF) != 0);	/* UTF is irrelevant */
25
		if(white && !nwhite)	/* beginning of field */
26
			nf++;
27
		white = nwhite;
28
	}
29
	return nf+1;	/* +1 for nil */
30
}
31
 
32
/*
33
 *  parse a command written to a device
34
 */
35
Cmdbuf*
36
parsecmd(char *p, int n)
37
{
38
	Cmdbuf *cb;
39
	int nf;
40
	char *sp;
41
 
42
	nf = ncmdfield(p, n);
43
 
44
	/* allocate Cmdbuf plus string pointers plus copy of string including \0 */
45
	sp = emalloc9p(sizeof(*cb) + nf * sizeof(char*) + n + 1);
46
	cb = (Cmdbuf*)sp;
47
	cb->f = (char**)(&cb[1]);
48
	cb->buf = (char*)(&cb->f[nf]);
49
 
50
	memmove(cb->buf, p, n);
51
 
52
	/* dump new line and null terminate */
53
	if(n > 0 && cb->buf[n-1] == '\n')
54
		n--;
55
	cb->buf[n] = '\0';
56
 
57
	cb->nf = tokenize(cb->buf, cb->f, nf-1);
58
	cb->f[cb->nf] = nil;
59
 
60
	return cb;
61
}
62
 
63
/*
64
 * Reconstruct original message, for error diagnostic
65
 */
66
void
67
respondcmderror(Req *r, Cmdbuf *cb, char *fmt, ...)
68
{
69
	int i;
70
	va_list arg;
71
	char *p, *e;
72
	char err[ERRMAX];
73
 
74
	e = err+ERRMAX-10;
75
	va_start(arg, fmt);
76
	p = vseprint(err, e, fmt, arg);
77
	va_end(arg);
78
	p = seprint(p, e, ": \"");
79
	quotefmtinstall();	/* just in case */
80
	for(i=0; i<cb->nf; i++){
81
		if(i > 0)
82
			p = seprint(p, e, " ");
83
		p = seprint(p, e, "%q", cb->f[i]);
84
	}
85
	strcpy(p, "\"");
86
	respond(r, err);
87
}
88
 
89
/*
90
 * Look up entry in table
91
 */
92
Cmdtab*
93
lookupcmd(Cmdbuf *cb, Cmdtab *ctab, int nctab)
94
{
95
	int i;
96
	Cmdtab *ct;
97
 
98
	if(cb->nf == 0){
99
		werrstr("empty control message");
100
		return nil;
101
	}
102
 
103
	for(ct = ctab, i=0; i<nctab; i++, ct++){
104
		if(strcmp(ct->cmd, "*") !=0)	/* wildcard always matches */
105
		if(strcmp(ct->cmd, cb->f[0]) != 0)
106
			continue;
107
		if(ct->narg != 0 && ct->narg != cb->nf){
108
			werrstr("bad # args to command");
109
			return nil;
110
		}
111
		return ct;
112
	}
113
 
114
	werrstr("unknown control message");
115
	return nil;
116
}