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
 
5
static uint dumpsome(char*, char*, char*, long);
6
static void fdirconv(char*, char*, Dir*);
7
static char *qidtype(char*, uchar);
8
 
9
#define	QIDFMT	"(%.16llux %lud %s)"
10
 
11
int
12
fcallfmt(Fmt *fmt)
13
{
14
	Fcall *f;
15
	int fid, type, tag, i;
16
	char buf[512], tmp[200];
17
	char *p, *e;
18
	Dir *d;
19
	Qid *q;
20
 
21
	e = buf+sizeof(buf);
22
	f = va_arg(fmt->args, Fcall*);
23
	type = f->type;
24
	fid = f->fid;
25
	tag = f->tag;
26
	switch(type){
27
	case Tversion:	/* 100 */
28
		seprint(buf, e, "Tversion tag %ud msize %ud version '%s'", tag, f->msize, f->version);
29
		break;
30
	case Rversion:
31
		seprint(buf, e, "Rversion tag %ud msize %ud version '%s'", tag, f->msize, f->version);
32
		break;
33
	case Tauth:	/* 102 */
34
		seprint(buf, e, "Tauth tag %ud afid %d uname %s aname %s", tag,
35
			f->afid, f->uname, f->aname);
36
		break;
37
	case Rauth:
38
		seprint(buf, e, "Rauth tag %ud qid " QIDFMT, tag,
39
			f->aqid.path, f->aqid.vers, qidtype(tmp, f->aqid.type));
40
		break;
41
	case Tattach:	/* 104 */
42
		seprint(buf, e, "Tattach tag %ud fid %d afid %d uname %s aname %s", tag,
43
			fid, f->afid, f->uname, f->aname);
44
		break;
45
	case Rattach:
46
		seprint(buf, e, "Rattach tag %ud qid " QIDFMT, tag,
47
			f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type));
48
		break;
49
	case Rerror:	/* 107; 106 (Terror) illegal */
50
		seprint(buf, e, "Rerror tag %ud ename %s", tag, f->ename);
51
		break;
52
	case Tflush:	/* 108 */
53
		seprint(buf, e, "Tflush tag %ud oldtag %ud", tag, f->oldtag);
54
		break;
55
	case Rflush:
56
		seprint(buf, e, "Rflush tag %ud", tag);
57
		break;
58
	case Twalk:	/* 110 */
59
		p = seprint(buf, e, "Twalk tag %ud fid %d newfid %d nwname %d ", tag, fid, f->newfid, f->nwname);
60
		if(f->nwname <= MAXWELEM)
61
			for(i=0; i<f->nwname; i++)
62
				p = seprint(p, e, "%d:%s ", i, f->wname[i]);
63
		break;
64
	case Rwalk:
65
		p = seprint(buf, e, "Rwalk tag %ud nwqid %ud ", tag, f->nwqid);
66
		if(f->nwqid <= MAXWELEM)
67
			for(i=0; i<f->nwqid; i++){
68
				q = &f->wqid[i];
69
				p = seprint(p, e, "%d:" QIDFMT " ", i,
70
					q->path, q->vers, qidtype(tmp, q->type));
71
			}
72
		break;
73
	case Topen:	/* 112 */
74
		seprint(buf, e, "Topen tag %ud fid %ud mode %d", tag, fid, f->mode);
75
		break;
76
	case Ropen:
77
		seprint(buf, e, "Ropen tag %ud qid " QIDFMT " iounit %ud ", tag,
78
			f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
79
		break;
80
	case Tcreate:	/* 114 */
81
		seprint(buf, e, "Tcreate tag %ud fid %ud name %s perm %M mode %d", tag, fid, f->name, (ulong)f->perm, f->mode);
82
		break;
83
	case Rcreate:
84
		seprint(buf, e, "Rcreate tag %ud qid " QIDFMT " iounit %ud ", tag,
85
			f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
86
		break;
87
	case Tread:	/* 116 */
88
		seprint(buf, e, "Tread tag %ud fid %d offset %lld count %ud",
89
			tag, fid, f->offset, f->count);
90
		break;
91
	case Rread:
92
		p = seprint(buf, e, "Rread tag %ud count %ud ", tag, f->count);
93
			dumpsome(p, e, f->data, f->count);
94
		break;
95
	case Twrite:	/* 118 */
96
		p = seprint(buf, e, "Twrite tag %ud fid %d offset %lld count %ud ",
97
			tag, fid, f->offset, f->count);
98
		dumpsome(p, e, f->data, f->count);
99
		break;
100
	case Rwrite:
101
		seprint(buf, e, "Rwrite tag %ud count %ud", tag, f->count);
102
		break;
103
	case Tclunk:	/* 120 */
104
		seprint(buf, e, "Tclunk tag %ud fid %ud", tag, fid);
105
		break;
106
	case Rclunk:
107
		seprint(buf, e, "Rclunk tag %ud", tag);
108
		break;
109
	case Tremove:	/* 122 */
110
		seprint(buf, e, "Tremove tag %ud fid %ud", tag, fid);
111
		break;
112
	case Rremove:
113
		seprint(buf, e, "Rremove tag %ud", tag);
114
		break;
115
	case Tstat:	/* 124 */
116
		seprint(buf, e, "Tstat tag %ud fid %ud", tag, fid);
117
		break;
118
	case Rstat:
119
		p = seprint(buf, e, "Rstat tag %ud ", tag);
120
		if(f->nstat > sizeof tmp)
121
			seprint(p, e, " stat(%d bytes)", f->nstat);
122
		else{
123
			d = (Dir*)tmp;
124
			convM2D(f->stat, f->nstat, d, (char*)(d+1));
125
			seprint(p, e, " stat ");
126
			fdirconv(p+6, e, d);
127
		}
128
		break;
129
	case Twstat:	/* 126 */
130
		p = seprint(buf, e, "Twstat tag %ud fid %ud", tag, fid);
131
		if(f->nstat > sizeof tmp)
132
			seprint(p, e, " stat(%d bytes)", f->nstat);
133
		else{
134
			d = (Dir*)tmp;
135
			convM2D(f->stat, f->nstat, d, (char*)(d+1));
136
			seprint(p, e, " stat ");
137
			fdirconv(p+6, e, d);
138
		}
139
		break;
140
	case Rwstat:
141
		seprint(buf, e, "Rwstat tag %ud", tag);
142
		break;
143
	default:
144
		seprint(buf, e,  "unknown type %d", type);
145
	}
146
	return fmtstrcpy(fmt, buf);
147
}
148
 
149
static char*
150
qidtype(char *s, uchar t)
151
{
152
	char *p;
153
 
154
	p = s;
155
	if(t & QTDIR)
156
		*p++ = 'd';
157
	if(t & QTAPPEND)
158
		*p++ = 'a';
159
	if(t & QTEXCL)
160
		*p++ = 'l';
161
	if(t & QTAUTH)
162
		*p++ = 'A';
163
	*p = '\0';
164
	return s;
165
}
166
 
167
int
168
dirfmt(Fmt *fmt)
169
{
170
	char buf[160];
171
 
172
	fdirconv(buf, buf+sizeof buf, va_arg(fmt->args, Dir*));
173
	return fmtstrcpy(fmt, buf);
174
}
175
 
176
static void
177
fdirconv(char *buf, char *e, Dir *d)
178
{
179
	char tmp[16];
180
 
181
	seprint(buf, e, "'%s' '%s' '%s' '%s' "
182
		"q " QIDFMT " m %#luo "
183
		"at %ld mt %ld l %lld "
184
		"t %d d %d",
185
			d->name, d->uid, d->gid, d->muid,
186
			d->qid.path, d->qid.vers, qidtype(tmp, d->qid.type), d->mode,
187
			d->atime, d->mtime, d->length,
188
			d->type, d->dev);
189
}
190
 
191
/*
192
 * dump out count (or DUMPL, if count is bigger) bytes from
193
 * buf to ans, as a string if they are all printable,
194
 * else as a series of hex bytes
195
 */
196
#define DUMPL 64
197
 
198
static uint
199
dumpsome(char *ans, char *e, char *buf, long count)
200
{
201
	int i, printable;
202
	char *p;
203
 
204
	if(buf == nil){
205
		seprint(ans, e, "<no data>");
206
		return strlen(ans);
207
	}
208
	printable = 1;
209
	if(count > DUMPL)
210
		count = DUMPL;
211
	for(i=0; i<count && printable; i++)
212
		if((buf[i]<32 && buf[i] !='\n' && buf[i] !='\t') || (uchar)buf[i]>127)
213
			printable = 0;
214
	p = ans;
215
	*p++ = '\'';
216
	if(printable){
217
		if(count > e-p-2)
218
			count = e-p-2;
219
		memmove(p, buf, count);
220
		p += count;
221
	}else{
222
		if(2*count > e-p-2)
223
			count = (e-p-2)/2;
224
		for(i=0; i<count; i++){
225
			if(i>0 && i%4==0)
226
				*p++ = ' ';
227
			sprint(p, "%2.2ux", (uchar)buf[i]);
228
			p += 2;
229
		}
230
	}
231
	*p++ = '\'';
232
	*p = 0;
233
	return p - ans;
234
}