Blob


1 /*
2 * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #include "compat.h"
19 #include <sys/types.h>
20 #include <sys/uio.h>
22 #include <ctype.h>
23 #include <stdint.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
28 #include "kami.h"
29 #include "log.h"
30 #include "utils.h"
32 void *
33 xmalloc(size_t size)
34 {
35 void *r;
37 if ((r = malloc(size)) == NULL)
38 fatal("malloc");
39 return r;
40 }
42 void *
43 xcalloc(size_t nmemb, size_t size)
44 {
45 void *r;
47 if ((r = calloc(nmemb, size)) == NULL)
48 fatal("calloc");
49 return r;
50 }
52 char *
53 xstrdup(const char *s)
54 {
55 char *r;
57 if ((r = strdup(s)) == NULL)
58 fatal("strdup");
59 return r;
60 }
62 void *
63 xmemdup(const void *d, size_t len)
64 {
65 void *r;
67 if ((r = malloc(len)) == NULL)
68 fatal("malloc");
69 memcpy(r, d, len);
70 return r;
71 }
73 const char *
74 pp_msg_type(uint8_t type)
75 {
76 switch (type) {
77 case Tversion: return "Tversion";
78 case Rversion: return "Rversion";
79 case Tauth: return "Tauth";
80 case Rauth: return "Rauth";
81 case Tattach: return "Tattach";
82 case Rattach: return "Rattach";
83 case Terror: return "Terror"; /* illegal */
84 case Rerror: return "Rerror";
85 case Tflush: return "Tflush";
86 case Rflush: return "Rflush";
87 case Twalk: return "Twalk";
88 case Rwalk: return "Rwalk";
89 case Topen: return "Topen";
90 case Ropen: return "Ropen";
91 case Tcreate: return "Tcreate";
92 case Rcreate: return "Rcreate";
93 case Tread: return "Tread";
94 case Rread: return "Rread";
95 case Twrite: return "Twrite";
96 case Rwrite: return "Rwrite";
97 case Tclunk: return "Tclunk";
98 case Rclunk: return "Rclunk";
99 case Tremove: return "Tremove";
100 case Rremove: return "Rremove";
101 case Tstat: return "Tstat";
102 case Rstat: return "Rstat";
103 case Twstat: return "Twstat";
104 case Rwstat: return "Rwstat";
105 default: return "unknown";
109 const char *
110 pp_qid_type(uint8_t type)
112 switch (type) {
113 case QTDIR: return "dir";
114 case QTAPPEND: return "append-only";
115 case QTEXCL: return "exclusive";
116 case QTMOUNT: return "mounted-channel";
117 case QTAUTH: return "authentication";
118 case QTTMP: return "non-backed-up";
119 case QTSYMLINK: return "symlink";
120 case QTFILE: return "file";
123 return "unknown";
126 static void
127 hexdump_ppline(int x, uint8_t *data, size_t len)
129 for (; x < 50; x++)
130 printf(" ");
132 printf("|");
134 for (x = 0; x < (int)len; ++x) {
135 if (isgraph(data[x]))
136 printf("%c", data[x]);
137 else
138 printf(".");
141 printf("|\n");
144 void
145 hexdump(const char *label, uint8_t *data, size_t len)
147 size_t i;
148 int x, n;
150 /*
151 * Layout:
152 * === first block === == second block == |........|\n
153 * first and second block are 8 bytes long (for a total of 48
154 * columns), plus two separator plus two | plus 16 chars, for
155 * a total of 68 characters.
156 */
158 printf("\nhexdump \"%s\": (%zu bytes)\n", label, len);
159 for (x = 0, n = 0, i = 0; i < len; ++i) {
160 if (i != 0 && i % 8 == 0) {
161 printf(" ");
162 x++;
165 if (n == 16) {
166 hexdump_ppline(x, &data[i - 16], 16);
167 x = 0;
168 n = 0;
171 printf("%02x ", data[i]);
172 x += 3;
173 n++;
176 if (n != 0)
177 hexdump_ppline(x, &data[i - n], n);
179 printf("\n");
180 fflush(stdout);
183 void
184 imsg_event_add(struct imsgev *iev)
186 iev->events = EV_READ;
187 if (iev->ibuf.w.queued)
188 iev->events |= EV_WRITE;
190 event_del(&iev->ev);
191 event_set(&iev->ev, iev->ibuf.fd, iev->events, iev->handler, iev);
192 event_add(&iev->ev, NULL);
195 int
196 imsg_compose_event(struct imsgev *iev, uint16_t type, uint32_t peerid,
197 pid_t pid, int fd, const void *data, uint16_t datalen)
199 int ret;
201 if ((ret = imsg_compose(&iev->ibuf, type, peerid, pid, fd, data,
202 datalen) != -1))
203 imsg_event_add(iev);
205 return ret;