akaros/user/ndblib/fcallfmt.c
<<
>>
Prefs
   1/* 
   2 * This file is part of the UCB release of Plan 9. It is subject to the license
   3 * terms in the LICENSE file found in the top-level directory of this
   4 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
   5 * part of the UCB release of Plan 9, including this file, may be copied,
   6 * modified, propagated, or distributed except according to the terms contained
   7 * in the LICENSE file.
   8 */
   9#include <parlib/printf-ext.h>
  10
  11#include <stdlib.h>
  12#include <stdio.h>
  13#include <parlib/parlib.h>
  14#include <unistd.h>
  15#include <sys/types.h>
  16#include <sys/stat.h>
  17#include <signal.h>
  18#include <fcntl.h>
  19#include <ctype.h>
  20#include <error.h>
  21#include <iplib/iplib.h>
  22#include <fcall.h>
  23#include <ndblib/ndb.h>
  24#include <ndblib/fcallfmt.h>
  25
  26static int dumpsome(FILE *, char *, long);
  27static int fdirconv(FILE *, struct dir *);
  28static char *qidtype(char *, uint8_t);
  29
  30#define QIDFMT  "(%.16llux %lud %s)"
  31
  32int printf_fcall(FILE * stream, const struct printf_info *info,
  33                                 const void *const *args)
  34{
  35        struct fcall *f = *(void **)args[0];
  36        int fid, type, tag, i, retval = 0;
  37        char buf[512], tmp[200];
  38        char *p, *e;
  39        struct dir *d;
  40        struct qid *q;
  41
  42        e = buf + sizeof(buf);
  43        type = f->type;
  44        fid = f->fid;
  45        tag = f->tag;
  46        switch (type) {
  47                case Tversion:  /* 100 */
  48                        retval +=
  49                                fprintf(stream, "Tversion tag %u msize %u version '%s' ", tag,
  50                                                f->msize, f->version);
  51                        break;
  52                case Rversion:
  53                        retval +=
  54                                fprintf(stream, "Rversion tag %u msize %u version '%s' ", tag,
  55                                                f->msize, f->version);
  56                        break;
  57                case Tauth:     /* 102 */
  58                        retval +=
  59                                fprintf(stream, "Tauth tag %u afid %d uname %s aname %s ", tag,
  60                                                f->afid, f->uname, f->aname);
  61                        break;
  62                case Rauth:
  63                        retval += fprintf(stream, "Rauth tag %u qid " QIDFMT, tag,
  64                                                          f->aqid.path, f->aqid.vers, qidtype(tmp,
  65                                                                                                                                  f->aqid.
  66                                                                                                                                  type));
  67                        break;
  68                case Tattach:   /* 104 */
  69                        retval +=
  70                                fprintf(stream,
  71                                                "Tattach tag %u fid %d afid %d uname %s aname %s ", tag,
  72                                                fid, f->afid, f->uname, f->aname);
  73                        break;
  74                case Rattach:
  75                        retval += fprintf(stream, "Rattach tag %u qid " QIDFMT, tag,
  76                                                          f->qid.path, f->qid.vers, qidtype(tmp,
  77                                                                                                                                f->qid.type));
  78                        break;
  79                case Rerror:    /* 107; 106 (Terror) illegal */
  80                        retval += fprintf(stream, "Rerror tag %u ename %s ", tag, f->ename);
  81                        break;
  82                case Tflush:    /* 108 */
  83                        retval +=
  84                                fprintf(stream, "Tflush tag %u oldtag %u ", tag, f->oldtag);
  85                        break;
  86                case Rflush:
  87                        retval += fprintf(stream, "Rflush tag %u ", tag);
  88                        break;
  89                case Twalk:     /* 110 */
  90                        retval +=
  91                                fprintf(stream, "Twalk tag %u fid %d newfid %d nwname %d  ",
  92                                                tag, fid, f->newfid, f->nwname);
  93                        if (f->nwname <= MAXWELEM)
  94                                for (i = 0; i < f->nwname; i++)
  95                                        retval += fprintf(stream, "%d:%s  ", i, f->wname[i]);
  96                        break;
  97                case Rwalk:
  98                        retval +=
  99                                fprintf(stream, "Rwalk tag %u nwqid %u  ", tag, f->nwqid);
 100                        if (f->nwqid <= MAXWELEM)
 101                                for (i = 0; i < f->nwqid; i++) {
 102                                        q = &f->wqid[i];
 103                                        retval += fprintf(stream, "%d:" QIDFMT "  ", i,
 104                                                                          q->path, q->vers, qidtype(tmp, q->type));
 105                                }
 106                        break;
 107                case Topen:     /* 112 */
 108                        retval +=
 109                                fprintf(stream, "Topen tag %u fid %u mode %d ", tag, fid,
 110                                                f->mode);
 111                        break;
 112                case Ropen:
 113                        retval +=
 114                                fprintf(stream, "Ropen tag %u qid " QIDFMT " iounit %u  ", tag,
 115                                                f->qid.path, f->qid.vers, qidtype(tmp, f->qid.type),
 116                                                f->iounit);
 117                        break;
 118                case Tcreate:   /* 114 */
 119                        retval +=
 120                                fprintf(stream,
 121                                                "Tcreate tag %u fid %u name %s perm %d mode %d ", tag,
 122                                                fid, f->name, (uint32_t) f->perm, f->mode);
 123                        break;
 124                case Rcreate:
 125                        retval +=
 126                                fprintf(stream, "Rcreate tag %u qid " QIDFMT " iounit %u  ",
 127                                                tag, f->qid.path, f->qid.vers, qidtype(tmp,
 128                                                                                                                           f->qid.type),
 129                                                f->iounit);
 130                        break;
 131                case Tread:     /* 116 */
 132                        retval +=
 133                                fprintf(stream, "Tread tag %u fid %d offset %lld count %u ",
 134                                                tag, fid, f->offset, f->count);
 135                        break;
 136                case Rread:
 137                        retval +=
 138                                fprintf(stream, "Rread tag %u count %u  ", tag, f->count);
 139                        retval += dumpsome(stream, f->data, f->count);
 140                        break;
 141                case Twrite:    /* 118 */
 142                        retval +=
 143                                fprintf(stream, "Twrite tag %u fid %d offset %lld count %u  ",
 144                                                tag, fid, f->offset, f->count);
 145                        retval += dumpsome(stream, f->data, f->count);
 146                        break;
 147                case Rwrite:
 148                        retval +=
 149                                fprintf(stream, "Rwrite tag %u count %u ", tag, f->count);
 150                        break;
 151                case Tclunk:    /* 120 */
 152                        retval += fprintf(stream, "Tclunk tag %u fid %u ", tag, fid);
 153                        break;
 154                case Rclunk:
 155                        retval += fprintf(stream, "Rclunk tag %u ", tag);
 156                        break;
 157                case Tremove:   /* 122 */
 158                        retval += fprintf(stream, "Tremove tag %u fid %u ", tag, fid);
 159                        break;
 160                case Rremove:
 161                        retval += fprintf(stream, "Rremove tag %u ", tag);
 162                        break;
 163                case Tstat:     /* 124 */
 164                        retval += fprintf(stream, "Tstat tag %u fid %u ", tag, fid);
 165                        break;
 166                case Rstat:
 167                        retval += fprintf(stream, "Rstat tag %u  ", tag);
 168                        if (f->nstat > sizeof tmp)
 169                                retval += fprintf(stream, " stat(%d bytes) ", f->nstat);
 170                        else {
 171                                d = (struct dir *)tmp;
 172                                convM2D(f->stat, f->nstat, d, (char *)(d + 1));
 173                                retval += fprintf(stream, " stat ");
 174                                retval += fdirconv(stream, d);
 175                        }
 176                        break;
 177                case Twstat:    /* 126 */
 178                        retval += fprintf(stream, "Twstat tag %u fid %u ", tag, fid);
 179                        if (f->nstat > sizeof tmp)
 180                                retval += fprintf(stream, " stat(%d bytes) ", f->nstat);
 181                        else {
 182                                d = (struct dir *)tmp;
 183                                convM2D(f->stat, f->nstat, d, (char *)(d + 1));
 184                                retval += fprintf(stream, " stat ");
 185                                retval += fdirconv(stream, d);
 186                        }
 187                        break;
 188                case Rwstat:
 189                        retval += fprintf(stream, "Rwstat tag %u ", tag);
 190                        break;
 191                default:
 192                        retval += fprintf(stream, "unknown type %d ", type);
 193        }
 194        return retval;
 195}
 196
 197static char *qidtype(char *s, uint8_t t)
 198{
 199        char *p;
 200#define QTDIR              0x80 /* type bit for directories */
 201        p = s;
 202        if (t & QTDIR)
 203                *p++ = 'd';
 204#if 0
 205        if (t & QTAPPEND)
 206                *p++ = 'a';
 207        if (t & QTEXCL)
 208                *p++ = 'l';
 209        if (t & QTAUTH)
 210                *p++ = 'A';
 211#endif
 212        *p = '\0';
 213        return s;
 214}
 215
 216int printf_dir(FILE * stream, const struct printf_info *info,
 217                           const void *const *args)
 218{
 219        struct dir *d = *(void **)args[0];
 220        return fdirconv(stream, d);
 221}
 222
 223static int fdirconv(FILE * stream, struct dir *d)
 224{
 225        char tmp[16];
 226
 227        return fprintf(stream, "'%s' '%s' '%s' '%s' "
 228                                   "q " QIDFMT " m %#luo "
 229                                   "at %ld mt %ld l %lld "
 230                                   "t %d d %d ",
 231                                   d->name, d->uid, d->gid, d->muid,
 232                                   d->qid.path, d->qid.vers, qidtype(tmp, d->qid.type), d->mode,
 233                                   d->atime, d->mtime, d->length, d->type, d->dev);
 234}
 235
 236/*
 237 * dump out count (or DUMPL, if count is bigger) bytes from
 238 * buf to stream, as a string if they are all printable,
 239 * else as a series of hex bytes
 240 */
 241#define DUMPL 64
 242
 243static int dumpsome(FILE * stream, char *buf, long count)
 244{
 245        int i, printable, retval = 0;
 246
 247        if (buf == NULL) {
 248                return fprintf(stream, "<no data>");
 249        }
 250        printable = 1;
 251        if (count > DUMPL)
 252                count = DUMPL;
 253        for (i = 0; i < count && printable; i++)
 254                if ((buf[i] < 32 && buf[i] != '\n' && buf[i] != '\t')
 255                        || (uint8_t) buf[i] > 127)
 256                        printable = 0;
 257        retval += fprintf(stream, "'");
 258        if (printable) {
 259                retval += fprintf(stream, "%s ", buf);
 260        } else {
 261                for (i = 0; i < count; i++) {
 262                        if (i > 0 && i % 4 == 0)
 263                                retval += fprintf(stream, " ");
 264                        retval += fprintf(stream, "%2.2ux ", buf[i]);
 265                }
 266        }
 267        retval += fprintf(stream, "'");
 268        return retval;
 269}
 270
 271int printf_fcall_info(const struct printf_info *info, size_t n, int *argtypes,
 272                                          int *size)
 273{
 274        if (n > 0) {
 275                argtypes[0] = PA_POINTER;
 276                size[0] = sizeof(uint8_t *);
 277        }
 278        return 1;
 279}
 280
 281int printf_dir_info(const struct printf_info *info, size_t n, int *argtypes,
 282                                        int *size)
 283{
 284        if (n > 0) {
 285                argtypes[0] = PA_POINTER;
 286                size[0] = sizeof(uint8_t *);
 287        }
 288        return 1;
 289}
 290