2 f024663d 2021-09-05 stsp * Copyright (c) 2019 Ori Bernstein <ori@openbsd.org>
3 f024663d 2021-09-05 stsp * Copyright (c) 2021 Stefan Sperling <stsp@openbsd.org>
5 f024663d 2021-09-05 stsp * Permission to use, copy, modify, and distribute this software for any
6 f024663d 2021-09-05 stsp * purpose with or without fee is hereby granted, provided that the above
7 f024663d 2021-09-05 stsp * copyright notice and this permission notice appear in all copies.
9 f024663d 2021-09-05 stsp * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 f024663d 2021-09-05 stsp * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 f024663d 2021-09-05 stsp * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 f024663d 2021-09-05 stsp * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 f024663d 2021-09-05 stsp * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 f024663d 2021-09-05 stsp * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 f024663d 2021-09-05 stsp * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 f024663d 2021-09-05 stsp #include <ctype.h>
19 f024663d 2021-09-05 stsp #include <errno.h>
20 f024663d 2021-09-05 stsp #include <limits.h>
21 f024663d 2021-09-05 stsp #include <stdio.h>
22 f024663d 2021-09-05 stsp #include <stdlib.h>
23 f024663d 2021-09-05 stsp #include <unistd.h>
25 f024663d 2021-09-05 stsp #include "got_error.h"
26 ef20f542 2022-06-26 thomas #include "got_lib_pkt.h"
28 f024663d 2021-09-05 stsp const struct got_error *
29 f024663d 2021-09-05 stsp got_pkt_readn(ssize_t *off, int fd, void *buf, size_t n)
34 f024663d 2021-09-05 stsp while (*off != n) {
35 f024663d 2021-09-05 stsp r = read(fd, buf + *off, n - *off);
36 f024663d 2021-09-05 stsp if (r == -1)
37 f024663d 2021-09-05 stsp return got_error_from_errno("read");
39 23ac5000 2023-01-23 thomas return got_error(GOT_ERR_EOF);
42 f024663d 2021-09-05 stsp return NULL;
45 f024663d 2021-09-05 stsp const struct got_error *
46 f024663d 2021-09-05 stsp got_pkt_flushpkt(int fd, int chattygot)
50 f024663d 2021-09-05 stsp if (chattygot > 1)
51 f024663d 2021-09-05 stsp fprintf(stderr, "%s: writepkt: 0000\n", getprogname());
53 f024663d 2021-09-05 stsp w = write(fd, "0000", 4);
54 f024663d 2021-09-05 stsp if (w == -1)
55 f024663d 2021-09-05 stsp return got_error_from_errno("write");
57 f024663d 2021-09-05 stsp return got_error(GOT_ERR_IO);
58 f024663d 2021-09-05 stsp return NULL;
61 564cf664 2024-04-25 thomas.ad const struct got_error *
62 564cf664 2024-04-25 thomas.ad got_pkt_readlen(int *len, const char *str, int chattygot)
66 564cf664 2024-04-25 thomas.ad *len = 0;
67 564cf664 2024-04-25 thomas.ad for (i = 0; i < 4; i++) {
68 564cf664 2024-04-25 thomas.ad if ('0' <= str[i] && str[i] <= '9') {
69 564cf664 2024-04-25 thomas.ad *len *= 16;
70 564cf664 2024-04-25 thomas.ad *len += str[i] - '0';
71 564cf664 2024-04-25 thomas.ad } else if ('a' <= str[i] && str[i] <= 'f') {
72 564cf664 2024-04-25 thomas.ad *len *= 16;
73 564cf664 2024-04-25 thomas.ad *len += str[i] - 'a' + 10;
74 564cf664 2024-04-25 thomas.ad } else {
75 564cf664 2024-04-25 thomas.ad if (chattygot)
76 564cf664 2024-04-25 thomas.ad fprintf(stderr, "%s: bad length: '.4%s'\n",
77 564cf664 2024-04-25 thomas.ad getprogname(), str);
78 564cf664 2024-04-25 thomas.ad return got_error_msg(GOT_ERR_BAD_PACKET,
79 564cf664 2024-04-25 thomas.ad "packet length has invalid format");
82 564cf664 2024-04-25 thomas.ad return NULL;
86 f024663d 2021-09-05 stsp * Packet header contains a 4-byte hexstring which specifies the length
87 f024663d 2021-09-05 stsp * of data which follows.
89 f024663d 2021-09-05 stsp const struct got_error *
90 f024663d 2021-09-05 stsp got_pkt_readhdr(int *datalen, int fd, int chattygot)
92 564cf664 2024-04-25 thomas.ad static const struct got_error *err;
93 564cf664 2024-04-25 thomas.ad char lenstr[4];
97 f024663d 2021-09-05 stsp *datalen = 0;
99 f024663d 2021-09-05 stsp err = got_pkt_readn(&r, fd, lenstr, 4);
101 f024663d 2021-09-05 stsp return err;
102 f024663d 2021-09-05 stsp if (r == 0) {
103 f024663d 2021-09-05 stsp /* implicit "0000" */
104 f024663d 2021-09-05 stsp if (chattygot > 1)
105 f024663d 2021-09-05 stsp fprintf(stderr, "%s: readpkt: 0000\n", getprogname());
106 f024663d 2021-09-05 stsp return NULL;
108 f024663d 2021-09-05 stsp if (r != 4)
109 f024663d 2021-09-05 stsp return got_error_msg(GOT_ERR_BAD_PACKET,
110 f024663d 2021-09-05 stsp "wrong packet header length");
112 564cf664 2024-04-25 thomas.ad err = got_pkt_readlen(&n, lenstr, chattygot);
113 f024663d 2021-09-05 stsp if (n == 0)
114 564cf664 2024-04-25 thomas.ad return err;
115 f024663d 2021-09-05 stsp if (n <= 4)
116 f024663d 2021-09-05 stsp return got_error_msg(GOT_ERR_BAD_PACKET, "packet too short");
117 564cf664 2024-04-25 thomas.ad n -= 4;
119 f024663d 2021-09-05 stsp *datalen = n;
120 f024663d 2021-09-05 stsp return NULL;
123 f024663d 2021-09-05 stsp const struct got_error *
124 f024663d 2021-09-05 stsp got_pkt_readpkt(int *outlen, int fd, char *buf, int buflen, int chattygot)
126 f024663d 2021-09-05 stsp const struct got_error *err = NULL;
127 f024663d 2021-09-05 stsp int datalen, i;
130 f024663d 2021-09-05 stsp err = got_pkt_readhdr(&datalen, fd, chattygot);
132 f024663d 2021-09-05 stsp return err;
134 f024663d 2021-09-05 stsp if (datalen > buflen)
135 f024663d 2021-09-05 stsp return got_error(GOT_ERR_NO_SPACE);
137 f024663d 2021-09-05 stsp err = got_pkt_readn(&n, fd, buf, datalen);
139 f024663d 2021-09-05 stsp return err;
140 f024663d 2021-09-05 stsp if (n != datalen)
141 f024663d 2021-09-05 stsp return got_error_msg(GOT_ERR_BAD_PACKET, "short packet");
143 f024663d 2021-09-05 stsp if (chattygot > 1) {
144 f024663d 2021-09-05 stsp fprintf(stderr, "%s: readpkt: %zd:\t", getprogname(), n);
145 f024663d 2021-09-05 stsp for (i = 0; i < n; i++) {
146 6771d425 2022-11-17 thomas if (isprint((unsigned char)buf[i]))
147 f024663d 2021-09-05 stsp fputc(buf[i], stderr);
149 f024663d 2021-09-05 stsp fprintf(stderr, "[0x%.2x]", buf[i]);
151 f024663d 2021-09-05 stsp fputc('\n', stderr);
154 f024663d 2021-09-05 stsp *outlen = n;
155 f024663d 2021-09-05 stsp return NULL;
158 f024663d 2021-09-05 stsp const struct got_error *
159 f024663d 2021-09-05 stsp got_pkt_writepkt(int fd, char *buf, int nbuf, int chattygot)
161 f024663d 2021-09-05 stsp char len[5];
162 717a78d4 2022-08-16 thomas int i, ret;
165 717a78d4 2022-08-16 thomas ret = snprintf(len, sizeof(len), "%04x", nbuf + 4);
166 717a78d4 2022-08-16 thomas if (ret < 0 || (size_t)ret >= sizeof(len))
167 f024663d 2021-09-05 stsp return got_error(GOT_ERR_NO_SPACE);
168 f024663d 2021-09-05 stsp w = write(fd, len, 4);
169 f024663d 2021-09-05 stsp if (w == -1)
170 f024663d 2021-09-05 stsp return got_error_from_errno("write");
171 f024663d 2021-09-05 stsp if (w != 4)
172 f024663d 2021-09-05 stsp return got_error(GOT_ERR_IO);
173 f024663d 2021-09-05 stsp w = write(fd, buf, nbuf);
174 f024663d 2021-09-05 stsp if (w == -1)
175 f024663d 2021-09-05 stsp return got_error_from_errno("write");
176 f024663d 2021-09-05 stsp if (w != nbuf)
177 f024663d 2021-09-05 stsp return got_error(GOT_ERR_IO);
178 f024663d 2021-09-05 stsp if (chattygot > 1) {
179 f024663d 2021-09-05 stsp fprintf(stderr, "%s: writepkt: %s:\t", getprogname(), len);
180 f024663d 2021-09-05 stsp for (i = 0; i < nbuf; i++) {
181 6771d425 2022-11-17 thomas if (isprint((unsigned char)buf[i]))
182 f024663d 2021-09-05 stsp fputc(buf[i], stderr);
184 f024663d 2021-09-05 stsp fprintf(stderr, "[0x%.2x]", buf[i]);
186 f024663d 2021-09-05 stsp fputc('\n', stderr);
188 f024663d 2021-09-05 stsp return NULL;