fcallfmt.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       fcallfmt.c (5746B)
       ---
            1 #include "u.h"
            2 #include "lib.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 }