xref: /plan9/sys/src/libc/9sys/fcallfmt.c (revision 22a127bbfe4dd304949cc596400de973c0138e31)
19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <fcall.h>
49a747e4fSDavid du Colombier 
59a747e4fSDavid du Colombier static uint dumpsome(char*, char*, char*, long);
69a747e4fSDavid du Colombier static void fdirconv(char*, char*, Dir*);
79a747e4fSDavid du Colombier static char *qidtype(char*, uchar);
89a747e4fSDavid du Colombier 
99a747e4fSDavid du Colombier #define	QIDFMT	"(%.16llux %lud %s)"
109a747e4fSDavid du Colombier 
119a747e4fSDavid du Colombier int
fcallfmt(Fmt * fmt)129a747e4fSDavid du Colombier fcallfmt(Fmt *fmt)
139a747e4fSDavid du Colombier {
149a747e4fSDavid du Colombier 	Fcall *f;
159a747e4fSDavid du Colombier 	int fid, type, tag, i;
169a747e4fSDavid du Colombier 	char buf[512], tmp[200];
179a747e4fSDavid du Colombier 	char *p, *e;
189a747e4fSDavid du Colombier 	Dir *d;
199a747e4fSDavid du Colombier 	Qid *q;
209a747e4fSDavid du Colombier 
219a747e4fSDavid du Colombier 	e = buf+sizeof(buf);
229a747e4fSDavid du Colombier 	f = va_arg(fmt->args, Fcall*);
239a747e4fSDavid du Colombier 	type = f->type;
249a747e4fSDavid du Colombier 	fid = f->fid;
259a747e4fSDavid du Colombier 	tag = f->tag;
269a747e4fSDavid du Colombier 	switch(type){
279a747e4fSDavid du Colombier 	case Tversion:	/* 100 */
289a747e4fSDavid du Colombier 		seprint(buf, e, "Tversion tag %ud msize %ud version '%s'", tag, f->msize, f->version);
299a747e4fSDavid du Colombier 		break;
309a747e4fSDavid du Colombier 	case Rversion:
319a747e4fSDavid du Colombier 		seprint(buf, e, "Rversion tag %ud msize %ud version '%s'", tag, f->msize, f->version);
329a747e4fSDavid du Colombier 		break;
339a747e4fSDavid du Colombier 	case Tauth:	/* 102 */
349a747e4fSDavid du Colombier 		seprint(buf, e, "Tauth tag %ud afid %d uname %s aname %s", tag,
359a747e4fSDavid du Colombier 			f->afid, f->uname, f->aname);
369a747e4fSDavid du Colombier 		break;
379a747e4fSDavid du Colombier 	case Rauth:
389a747e4fSDavid du Colombier 		seprint(buf, e, "Rauth tag %ud qid " QIDFMT, tag,
399a747e4fSDavid du Colombier 			f->aqid.path, f->aqid.vers, qidtype(tmp, f->aqid.type));
409a747e4fSDavid du Colombier 		break;
419a747e4fSDavid du Colombier 	case Tattach:	/* 104 */
429a747e4fSDavid du Colombier 		seprint(buf, e, "Tattach tag %ud fid %d afid %d uname %s aname %s", tag,
439a747e4fSDavid du Colombier 			fid, f->afid, f->uname, f->aname);
449a747e4fSDavid du Colombier 		break;
459a747e4fSDavid du Colombier 	case Rattach:
469a747e4fSDavid du Colombier 		seprint(buf, e, "Rattach tag %ud qid " QIDFMT, tag,
479a747e4fSDavid du Colombier 			f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type));
489a747e4fSDavid du Colombier 		break;
499a747e4fSDavid du Colombier 	case Rerror:	/* 107; 106 (Terror) illegal */
509a747e4fSDavid du Colombier 		seprint(buf, e, "Rerror tag %ud ename %s", tag, f->ename);
519a747e4fSDavid du Colombier 		break;
529a747e4fSDavid du Colombier 	case Tflush:	/* 108 */
539a747e4fSDavid du Colombier 		seprint(buf, e, "Tflush tag %ud oldtag %ud", tag, f->oldtag);
549a747e4fSDavid du Colombier 		break;
559a747e4fSDavid du Colombier 	case Rflush:
569a747e4fSDavid du Colombier 		seprint(buf, e, "Rflush tag %ud", tag);
579a747e4fSDavid du Colombier 		break;
589a747e4fSDavid du Colombier 	case Twalk:	/* 110 */
599a747e4fSDavid du Colombier 		p = seprint(buf, e, "Twalk tag %ud fid %d newfid %d nwname %d ", tag, fid, f->newfid, f->nwname);
60d9306527SDavid du Colombier 		if(f->nwname <= MAXWELEM)
619a747e4fSDavid du Colombier 			for(i=0; i<f->nwname; i++)
629a747e4fSDavid du Colombier 				p = seprint(p, e, "%d:%s ", i, f->wname[i]);
639a747e4fSDavid du Colombier 		break;
649a747e4fSDavid du Colombier 	case Rwalk:
659a747e4fSDavid du Colombier 		p = seprint(buf, e, "Rwalk tag %ud nwqid %ud ", tag, f->nwqid);
66d9306527SDavid du Colombier 		if(f->nwqid <= MAXWELEM)
679a747e4fSDavid du Colombier 			for(i=0; i<f->nwqid; i++){
689a747e4fSDavid du Colombier 				q = &f->wqid[i];
699a747e4fSDavid du Colombier 				p = seprint(p, e, "%d:" QIDFMT " ", i,
709a747e4fSDavid du Colombier 					q->path, q->vers, qidtype(tmp, q->type));
719a747e4fSDavid du Colombier 			}
729a747e4fSDavid du Colombier 		break;
739a747e4fSDavid du Colombier 	case Topen:	/* 112 */
749a747e4fSDavid du Colombier 		seprint(buf, e, "Topen tag %ud fid %ud mode %d", tag, fid, f->mode);
759a747e4fSDavid du Colombier 		break;
769a747e4fSDavid du Colombier 	case Ropen:
779a747e4fSDavid du Colombier 		seprint(buf, e, "Ropen tag %ud qid " QIDFMT " iounit %ud ", tag,
789a747e4fSDavid du Colombier 			f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
799a747e4fSDavid du Colombier 		break;
809a747e4fSDavid du Colombier 	case Tcreate:	/* 114 */
819a747e4fSDavid du Colombier 		seprint(buf, e, "Tcreate tag %ud fid %ud name %s perm %M mode %d", tag, fid, f->name, (ulong)f->perm, f->mode);
829a747e4fSDavid du Colombier 		break;
839a747e4fSDavid du Colombier 	case Rcreate:
849a747e4fSDavid du Colombier 		seprint(buf, e, "Rcreate tag %ud qid " QIDFMT " iounit %ud ", tag,
859a747e4fSDavid du Colombier 			f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type), f->iounit);
869a747e4fSDavid du Colombier 		break;
879a747e4fSDavid du Colombier 	case Tread:	/* 116 */
889a747e4fSDavid du Colombier 		seprint(buf, e, "Tread tag %ud fid %d offset %lld count %ud",
899a747e4fSDavid du Colombier 			tag, fid, f->offset, f->count);
909a747e4fSDavid du Colombier 		break;
919a747e4fSDavid du Colombier 	case Rread:
929a747e4fSDavid du Colombier 		p = seprint(buf, e, "Rread tag %ud count %ud ", tag, f->count);
939a747e4fSDavid du Colombier 			dumpsome(p, e, f->data, f->count);
949a747e4fSDavid du Colombier 		break;
959a747e4fSDavid du Colombier 	case Twrite:	/* 118 */
969a747e4fSDavid du Colombier 		p = seprint(buf, e, "Twrite tag %ud fid %d offset %lld count %ud ",
979a747e4fSDavid du Colombier 			tag, fid, f->offset, f->count);
989a747e4fSDavid du Colombier 		dumpsome(p, e, f->data, f->count);
999a747e4fSDavid du Colombier 		break;
1009a747e4fSDavid du Colombier 	case Rwrite:
1019a747e4fSDavid du Colombier 		seprint(buf, e, "Rwrite tag %ud count %ud", tag, f->count);
1029a747e4fSDavid du Colombier 		break;
1039a747e4fSDavid du Colombier 	case Tclunk:	/* 120 */
1049a747e4fSDavid du Colombier 		seprint(buf, e, "Tclunk tag %ud fid %ud", tag, fid);
1059a747e4fSDavid du Colombier 		break;
1069a747e4fSDavid du Colombier 	case Rclunk:
1079a747e4fSDavid du Colombier 		seprint(buf, e, "Rclunk tag %ud", tag);
1089a747e4fSDavid du Colombier 		break;
1099a747e4fSDavid du Colombier 	case Tremove:	/* 122 */
1109a747e4fSDavid du Colombier 		seprint(buf, e, "Tremove tag %ud fid %ud", tag, fid);
1119a747e4fSDavid du Colombier 		break;
1129a747e4fSDavid du Colombier 	case Rremove:
1139a747e4fSDavid du Colombier 		seprint(buf, e, "Rremove tag %ud", tag);
1149a747e4fSDavid du Colombier 		break;
1159a747e4fSDavid du Colombier 	case Tstat:	/* 124 */
1169a747e4fSDavid du Colombier 		seprint(buf, e, "Tstat tag %ud fid %ud", tag, fid);
1179a747e4fSDavid du Colombier 		break;
1189a747e4fSDavid du Colombier 	case Rstat:
1199a747e4fSDavid du Colombier 		p = seprint(buf, e, "Rstat tag %ud ", tag);
1209a747e4fSDavid du Colombier 		if(f->nstat > sizeof tmp)
1219a747e4fSDavid du Colombier 			seprint(p, e, " stat(%d bytes)", f->nstat);
1229a747e4fSDavid du Colombier 		else{
1239a747e4fSDavid du Colombier 			d = (Dir*)tmp;
1249a747e4fSDavid du Colombier 			convM2D(f->stat, f->nstat, d, (char*)(d+1));
1259a747e4fSDavid du Colombier 			seprint(p, e, " stat ");
1269a747e4fSDavid du Colombier 			fdirconv(p+6, e, d);
1279a747e4fSDavid du Colombier 		}
1289a747e4fSDavid du Colombier 		break;
1299a747e4fSDavid du Colombier 	case Twstat:	/* 126 */
1309a747e4fSDavid du Colombier 		p = seprint(buf, e, "Twstat tag %ud fid %ud", tag, fid);
1319a747e4fSDavid du Colombier 		if(f->nstat > sizeof tmp)
1329a747e4fSDavid du Colombier 			seprint(p, e, " stat(%d bytes)", f->nstat);
1339a747e4fSDavid du Colombier 		else{
1349a747e4fSDavid du Colombier 			d = (Dir*)tmp;
1359a747e4fSDavid du Colombier 			convM2D(f->stat, f->nstat, d, (char*)(d+1));
1369a747e4fSDavid du Colombier 			seprint(p, e, " stat ");
1379a747e4fSDavid du Colombier 			fdirconv(p+6, e, d);
1389a747e4fSDavid du Colombier 		}
1399a747e4fSDavid du Colombier 		break;
1409a747e4fSDavid du Colombier 	case Rwstat:
1419a747e4fSDavid du Colombier 		seprint(buf, e, "Rwstat tag %ud", tag);
1429a747e4fSDavid du Colombier 		break;
1439a747e4fSDavid du Colombier 	default:
1449a747e4fSDavid du Colombier 		seprint(buf, e,  "unknown type %d", type);
1459a747e4fSDavid du Colombier 	}
1469a747e4fSDavid du Colombier 	return fmtstrcpy(fmt, buf);
1479a747e4fSDavid du Colombier }
1489a747e4fSDavid du Colombier 
1499a747e4fSDavid du Colombier static char*
qidtype(char * s,uchar t)1509a747e4fSDavid du Colombier qidtype(char *s, uchar t)
1519a747e4fSDavid du Colombier {
1529a747e4fSDavid du Colombier 	char *p;
1539a747e4fSDavid du Colombier 
1549a747e4fSDavid du Colombier 	p = s;
1559a747e4fSDavid du Colombier 	if(t & QTDIR)
1569a747e4fSDavid du Colombier 		*p++ = 'd';
1579a747e4fSDavid du Colombier 	if(t & QTAPPEND)
1589a747e4fSDavid du Colombier 		*p++ = 'a';
1599a747e4fSDavid du Colombier 	if(t & QTEXCL)
1609a747e4fSDavid du Colombier 		*p++ = 'l';
1619a747e4fSDavid du Colombier 	if(t & QTAUTH)
1629a747e4fSDavid du Colombier 		*p++ = 'A';
1639a747e4fSDavid du Colombier 	*p = '\0';
1649a747e4fSDavid du Colombier 	return s;
1659a747e4fSDavid du Colombier }
1669a747e4fSDavid du Colombier 
1679a747e4fSDavid du Colombier int
dirfmt(Fmt * fmt)1689a747e4fSDavid du Colombier dirfmt(Fmt *fmt)
1699a747e4fSDavid du Colombier {
1709a747e4fSDavid du Colombier 	char buf[160];
1719a747e4fSDavid du Colombier 
1729a747e4fSDavid du Colombier 	fdirconv(buf, buf+sizeof buf, va_arg(fmt->args, Dir*));
1739a747e4fSDavid du Colombier 	return fmtstrcpy(fmt, buf);
1749a747e4fSDavid du Colombier }
1759a747e4fSDavid du Colombier 
1769a747e4fSDavid du Colombier static void
fdirconv(char * buf,char * e,Dir * d)1779a747e4fSDavid du Colombier fdirconv(char *buf, char *e, Dir *d)
1789a747e4fSDavid du Colombier {
1799a747e4fSDavid du Colombier 	char tmp[16];
1809a747e4fSDavid du Colombier 
1819a747e4fSDavid du Colombier 	seprint(buf, e, "'%s' '%s' '%s' '%s' "
1829a747e4fSDavid du Colombier 		"q " QIDFMT " m %#luo "
1839a747e4fSDavid du Colombier 		"at %ld mt %ld l %lld "
1849a747e4fSDavid du Colombier 		"t %d d %d",
1859a747e4fSDavid du Colombier 			d->name, d->uid, d->gid, d->muid,
1869a747e4fSDavid du Colombier 			d->qid.path, d->qid.vers, qidtype(tmp, d->qid.type), d->mode,
1879a747e4fSDavid du Colombier 			d->atime, d->mtime, d->length,
1889a747e4fSDavid du Colombier 			d->type, d->dev);
1899a747e4fSDavid du Colombier }
1909a747e4fSDavid du Colombier 
1919a747e4fSDavid du Colombier /*
1929a747e4fSDavid du Colombier  * dump out count (or DUMPL, if count is bigger) bytes from
1939a747e4fSDavid du Colombier  * buf to ans, as a string if they are all printable,
1949a747e4fSDavid du Colombier  * else as a series of hex bytes
1959a747e4fSDavid du Colombier  */
1969a747e4fSDavid du Colombier #define DUMPL 64
1979a747e4fSDavid du Colombier 
1989a747e4fSDavid du Colombier static uint
dumpsome(char * ans,char * e,char * buf,long count)1999a747e4fSDavid du Colombier dumpsome(char *ans, char *e, char *buf, long count)
2009a747e4fSDavid du Colombier {
2019a747e4fSDavid du Colombier 	int i, printable;
2029a747e4fSDavid du Colombier 	char *p;
2039a747e4fSDavid du Colombier 
2049a747e4fSDavid du Colombier 	if(buf == nil){
2059a747e4fSDavid du Colombier 		seprint(ans, e, "<no data>");
2069a747e4fSDavid du Colombier 		return strlen(ans);
2079a747e4fSDavid du Colombier 	}
2089a747e4fSDavid du Colombier 	printable = 1;
2099a747e4fSDavid du Colombier 	if(count > DUMPL)
2109a747e4fSDavid du Colombier 		count = DUMPL;
2119a747e4fSDavid du Colombier 	for(i=0; i<count && printable; i++)
212*22a127bbSDavid du Colombier 		if((buf[i]<32 && buf[i] !='\n' && buf[i] !='\t') || (uchar)buf[i]>127)
2139a747e4fSDavid du Colombier 			printable = 0;
2149a747e4fSDavid du Colombier 	p = ans;
2159a747e4fSDavid du Colombier 	*p++ = '\'';
2169a747e4fSDavid du Colombier 	if(printable){
2179a747e4fSDavid du Colombier 		if(count > e-p-2)
2189a747e4fSDavid du Colombier 			count = e-p-2;
2199a747e4fSDavid du Colombier 		memmove(p, buf, count);
2209a747e4fSDavid du Colombier 		p += count;
2219a747e4fSDavid du Colombier 	}else{
2229a747e4fSDavid du Colombier 		if(2*count > e-p-2)
2239a747e4fSDavid du Colombier 			count = (e-p-2)/2;
2249a747e4fSDavid du Colombier 		for(i=0; i<count; i++){
2259a747e4fSDavid du Colombier 			if(i>0 && i%4==0)
2269a747e4fSDavid du Colombier 				*p++ = ' ';
227feebb65bSDavid du Colombier 			sprint(p, "%2.2ux", (uchar)buf[i]);
2289a747e4fSDavid du Colombier 			p += 2;
2299a747e4fSDavid du Colombier 		}
2309a747e4fSDavid du Colombier 	}
2319a747e4fSDavid du Colombier 	*p++ = '\'';
2329a747e4fSDavid du Colombier 	*p = 0;
2339a747e4fSDavid du Colombier 	return p - ans;
2349a747e4fSDavid du Colombier }
235