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"
27 #include "got_lib_poll.h"
29 const struct got_error
*
30 got_pkt_readn(ssize_t
*off
, int fd
, void *buf
, size_t n
,
33 const struct got_error
*err
;
36 err
= got_poll_read_full_timeout(fd
, &len
, buf
, n
, n
,
41 /* XXX size_t -> ssize_t */
43 return got_error(GOT_ERR_RANGE
);
48 const struct got_error
*
49 got_pkt_flushpkt(int fd
, int chattygot
)
54 fprintf(stderr
, "%s: writepkt: 0000\n", getprogname());
56 w
= write(fd
, "0000", 4);
58 return got_error_from_errno("write");
60 return got_error(GOT_ERR_IO
);
64 const struct got_error
*
65 got_pkt_readlen(int *len
, const char *str
, int chattygot
)
70 for (i
= 0; i
< 4; i
++) {
71 if ('0' <= str
[i
] && str
[i
] <= '9') {
74 } else if ('a' <= str
[i
] && str
[i
] <= 'f') {
76 *len
+= str
[i
] - 'a' + 10;
79 fprintf(stderr
, "%s: bad length: '.4%s'\n",
81 return got_error_msg(GOT_ERR_BAD_PACKET
,
82 "packet length has invalid format");
89 * Packet header contains a 4-byte hexstring which specifies the length
90 * of data which follows.
92 const struct got_error
*
93 got_pkt_readhdr(int *datalen
, int fd
, int chattygot
, int timeout
)
95 static const struct got_error
*err
;
102 err
= got_pkt_readn(&r
, fd
, lenstr
, 4, timeout
);
106 /* implicit "0000" */
108 fprintf(stderr
, "%s: readpkt: 0000\n", getprogname());
112 return got_error_msg(GOT_ERR_BAD_PACKET
,
113 "wrong packet header length");
115 err
= got_pkt_readlen(&n
, lenstr
, chattygot
);
119 return got_error_msg(GOT_ERR_BAD_PACKET
, "packet too short");
126 const struct got_error
*
127 got_pkt_readpkt(int *outlen
, int fd
, char *buf
, int buflen
, int chattygot
,
130 const struct got_error
*err
= NULL
;
134 err
= got_pkt_readhdr(&datalen
, fd
, chattygot
, timeout
);
138 if (datalen
> buflen
)
139 return got_error(GOT_ERR_NO_SPACE
);
141 err
= got_pkt_readn(&n
, fd
, buf
, datalen
, timeout
);
145 return got_error_msg(GOT_ERR_BAD_PACKET
, "short packet");
148 fprintf(stderr
, "%s: readpkt: %zd:\t", getprogname(), n
);
149 for (i
= 0; i
< n
; i
++) {
150 if (isprint((unsigned char)buf
[i
]))
151 fputc(buf
[i
], stderr
);
153 fprintf(stderr
, "[0x%.2x]", buf
[i
]);
162 const struct got_error
*
163 got_pkt_writepkt(int fd
, char *buf
, int nbuf
, int chattygot
)
169 ret
= snprintf(len
, sizeof(len
), "%04x", nbuf
+ 4);
170 if (ret
< 0 || (size_t)ret
>= sizeof(len
))
171 return got_error(GOT_ERR_NO_SPACE
);
172 w
= write(fd
, len
, 4);
174 return got_error_from_errno("write");
176 return got_error(GOT_ERR_IO
);
177 w
= write(fd
, buf
, nbuf
);
179 return got_error_from_errno("write");
181 return got_error(GOT_ERR_IO
);
183 fprintf(stderr
, "%s: writepkt: %s:\t", getprogname(), len
);
184 for (i
= 0; i
< nbuf
; i
++) {
185 if (isprint((unsigned char)buf
[i
]))
186 fputc(buf
[i
], stderr
);
188 fprintf(stderr
, "[0x%.2x]", buf
[i
]);