2 * Copyright (c) 2019 Ori Bernstein <ori@openbsd.org>
3 * Copyright (c) 2021 Stefan Sperling <stsp@openbsd.org>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
25 #include "got_error.h"
26 #include "got_lib_pkt.h"
28 const struct got_error *
29 got_pkt_readn(ssize_t *off, int fd, void *buf, size_t n)
35 r = read(fd, buf + *off, n - *off);
37 return got_error_from_errno("read");
39 return got_error(GOT_ERR_EOF);
45 const struct got_error *
46 got_pkt_flushpkt(int fd, int chattygot)
51 fprintf(stderr, "%s: writepkt: 0000\n", getprogname());
53 w = write(fd, "0000", 4);
55 return got_error_from_errno("write");
57 return got_error(GOT_ERR_IO);
61 const struct got_error *
62 got_pkt_readlen(int *len, const char *str, int chattygot)
67 for (i = 0; i < 4; i++) {
68 if ('0' <= str[i] && str[i] <= '9') {
71 } else if ('a' <= str[i] && str[i] <= 'f') {
73 *len += str[i] - 'a' + 10;
76 fprintf(stderr, "%s: bad length: '.4%s'\n",
78 return got_error_msg(GOT_ERR_BAD_PACKET,
79 "packet length has invalid format");
86 * Packet header contains a 4-byte hexstring which specifies the length
87 * of data which follows.
89 const struct got_error *
90 got_pkt_readhdr(int *datalen, int fd, int chattygot)
92 static const struct got_error *err;
99 err = got_pkt_readn(&r, fd, lenstr, 4);
103 /* implicit "0000" */
105 fprintf(stderr, "%s: readpkt: 0000\n", getprogname());
109 return got_error_msg(GOT_ERR_BAD_PACKET,
110 "wrong packet header length");
112 err = got_pkt_readlen(&n, lenstr, chattygot);
116 return got_error_msg(GOT_ERR_BAD_PACKET, "packet too short");
123 const struct got_error *
124 got_pkt_readpkt(int *outlen, int fd, char *buf, int buflen, int chattygot)
126 const struct got_error *err = NULL;
130 err = got_pkt_readhdr(&datalen, fd, chattygot);
134 if (datalen > buflen)
135 return got_error(GOT_ERR_NO_SPACE);
137 err = got_pkt_readn(&n, fd, buf, datalen);
141 return got_error_msg(GOT_ERR_BAD_PACKET, "short packet");
144 fprintf(stderr, "%s: readpkt: %zd:\t", getprogname(), n);
145 for (i = 0; i < n; i++) {
146 if (isprint((unsigned char)buf[i]))
147 fputc(buf[i], stderr);
149 fprintf(stderr, "[0x%.2x]", buf[i]);
158 const struct got_error *
159 got_pkt_writepkt(int fd, char *buf, int nbuf, int chattygot)
165 ret = snprintf(len, sizeof(len), "%04x", nbuf + 4);
166 if (ret < 0 || (size_t)ret >= sizeof(len))
167 return got_error(GOT_ERR_NO_SPACE);
168 w = write(fd, len, 4);
170 return got_error_from_errno("write");
172 return got_error(GOT_ERR_IO);
173 w = write(fd, buf, nbuf);
175 return got_error_from_errno("write");
177 return got_error(GOT_ERR_IO);
179 fprintf(stderr, "%s: writepkt: %s:\t", getprogname(), len);
180 for (i = 0; i < nbuf; i++) {
181 if (isprint((unsigned char)buf[i]))
182 fputc(buf[i], stderr);
184 fprintf(stderr, "[0x%.2x]", buf[i]);