kconfig: use pkg-config for ncurses detection
[akaros.git] / user / ndblib / fcallfmt.c
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
26 static int dumpsome(FILE *, char *, long);
27 static int fdirconv(FILE *, struct dir *);
28 static char *qidtype(char *, uint8_t);
29
30 #define QIDFMT  "(%.16llux %lud %s)"
31
32 int 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
197 static 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
216 int 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
223 static 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
243 static 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
271 int 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
281 int 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 }