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