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