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
);
62 * Packet header contains a 4-byte hexstring which specifies the length
63 * of data which follows.
65 const struct got_error
*
66 got_pkt_readhdr(int *datalen
, int fd
, int chattygot
)
68 static const struct got_error
*err
= NULL
;
77 err
= got_pkt_readn(&r
, fd
, lenstr
, 4);
83 fprintf(stderr
, "%s: readpkt: 0000\n", getprogname());
87 return got_error_msg(GOT_ERR_BAD_PACKET
,
88 "wrong packet header length");
91 for (i
= 0; i
< 4; i
++) {
92 if (!isprint((unsigned char)lenstr
[i
]))
93 return got_error_msg(GOT_ERR_BAD_PACKET
,
94 "unprintable character in packet length field");
96 for (i
= 0; i
< 4; i
++) {
97 if (!isxdigit((unsigned char)lenstr
[i
])) {
99 fprintf(stderr
, "%s: bad length: '%s'\n",
100 getprogname(), lenstr
);
101 return got_error_msg(GOT_ERR_BAD_PACKET
,
102 "packet length not specified in hex");
106 len
= strtol(lenstr
, &e
, 16);
107 if (lenstr
[0] == '\0' || *e
!= '\0')
108 return got_error(GOT_ERR_BAD_PACKET
);
109 if (errno
== ERANGE
&& (len
== LONG_MAX
|| len
== LONG_MIN
))
110 return got_error_msg(GOT_ERR_BAD_PACKET
, "bad packet length");
111 if (len
> INT_MAX
|| len
< INT_MIN
)
112 return got_error_msg(GOT_ERR_BAD_PACKET
, "bad packet length");
117 return got_error_msg(GOT_ERR_BAD_PACKET
, "packet too short");
124 const struct got_error
*
125 got_pkt_readpkt(int *outlen
, int fd
, char *buf
, int buflen
, int chattygot
)
127 const struct got_error
*err
= NULL
;
131 err
= got_pkt_readhdr(&datalen
, fd
, chattygot
);
135 if (datalen
> buflen
)
136 return got_error(GOT_ERR_NO_SPACE
);
138 err
= got_pkt_readn(&n
, fd
, buf
, datalen
);
142 return got_error_msg(GOT_ERR_BAD_PACKET
, "short packet");
145 fprintf(stderr
, "%s: readpkt: %zd:\t", getprogname(), n
);
146 for (i
= 0; i
< n
; i
++) {
147 if (isprint((unsigned char)buf
[i
]))
148 fputc(buf
[i
], stderr
);
150 fprintf(stderr
, "[0x%.2x]", buf
[i
]);
159 const struct got_error
*
160 got_pkt_writepkt(int fd
, char *buf
, int nbuf
, int chattygot
)
166 ret
= snprintf(len
, sizeof(len
), "%04x", nbuf
+ 4);
167 if (ret
< 0 || (size_t)ret
>= sizeof(len
))
168 return got_error(GOT_ERR_NO_SPACE
);
169 w
= write(fd
, len
, 4);
171 return got_error_from_errno("write");
173 return got_error(GOT_ERR_IO
);
174 w
= write(fd
, buf
, nbuf
);
176 return got_error_from_errno("write");
178 return got_error(GOT_ERR_IO
);
180 fprintf(stderr
, "%s: writepkt: %s:\t", getprogname(), len
);
181 for (i
= 0; i
< nbuf
; i
++) {
182 if (isprint((unsigned char)buf
[i
]))
183 fputc(buf
[i
], stderr
);
185 fprintf(stderr
, "[0x%.2x]", buf
[i
]);