Bug Summary

File:src/lib/libossaudio/../libsndio/aucat.c
Warning:line 282, column 2
Null pointer passed as 2nd argument to memory copy function

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name aucat.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/lib/libossaudio/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/lib/libossaudio -D PIC -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libossaudio/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/lib/libossaudio/../libsndio/aucat.c
1/* $OpenBSD: aucat.c,v 1.79 2021/11/07 20:51:47 ratchov Exp $ */
2/*
3 * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
4 *
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.
8 *
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.
16 */
17
18#include <sys/types.h>
19#include <sys/socket.h>
20#include <sys/stat.h>
21#include <sys/un.h>
22
23#include <netinet/in.h>
24#include <netinet/tcp.h>
25#include <netdb.h>
26
27#include <errno(*__errno()).h>
28#include <fcntl.h>
29#include <limits.h>
30#include <poll.h>
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <unistd.h>
35
36#include "aucat.h"
37#include "debug.h"
38
39
40/*
41 * read a message, return 0 if not completed
42 */
43int
44_aucat_rmsg(struct aucat *hdl, int *eof)
45{
46 ssize_t n;
47 unsigned char *data;
48
49 if (hdl->rstate != RSTATE_MSG0) {
50 DPRINTF("_aucat_rmsg: bad state\n")do {} while(0);
51 abort();
52 }
53 while (hdl->rtodo > 0) {
54 data = (unsigned char *)&hdl->rmsg;
55 data += sizeof(struct amsg) - hdl->rtodo;
56 while ((n = read(hdl->fd, data, hdl->rtodo)) == -1) {
57 if (errno(*__errno()) == EINTR4)
58 continue;
59 if (errno(*__errno()) != EAGAIN35) {
60 *eof = 1;
61 DPERROR("_aucat_rmsg: read")do {} while(0);
62 }
63 return 0;
64 }
65 if (n == 0) {
66 DPRINTF("_aucat_rmsg: eof\n")do {} while(0);
67 *eof = 1;
68 return 0;
69 }
70 hdl->rtodo -= n;
71 }
72 if (ntohl(hdl->rmsg.cmd)(__uint32_t)(__builtin_constant_p(hdl->rmsg.cmd) ? (__uint32_t
)(((__uint32_t)(hdl->rmsg.cmd) & 0xff) << 24 | (
(__uint32_t)(hdl->rmsg.cmd) & 0xff00) << 8 | ((__uint32_t
)(hdl->rmsg.cmd) & 0xff0000) >> 8 | ((__uint32_t
)(hdl->rmsg.cmd) & 0xff000000) >> 24) : __swap32md
(hdl->rmsg.cmd))
== AMSG_DATA5) {
73 hdl->rtodo = ntohl(hdl->rmsg.u.data.size)(__uint32_t)(__builtin_constant_p(hdl->rmsg.u.data.size) ?
(__uint32_t)(((__uint32_t)(hdl->rmsg.u.data.size) & 0xff
) << 24 | ((__uint32_t)(hdl->rmsg.u.data.size) &
0xff00) << 8 | ((__uint32_t)(hdl->rmsg.u.data.size)
& 0xff0000) >> 8 | ((__uint32_t)(hdl->rmsg.u.data
.size) & 0xff000000) >> 24) : __swap32md(hdl->rmsg
.u.data.size))
;
74 hdl->rstate = RSTATE_DATA1;
75 } else {
76 hdl->rtodo = sizeof(struct amsg);
77 hdl->rstate = RSTATE_MSG0;
78 }
79 return 1;
80}
81
82/*
83 * write a message, return 0 if not completed
84 */
85int
86_aucat_wmsg(struct aucat *hdl, int *eof)
87{
88 ssize_t n;
89 unsigned char *data;
90
91 if (hdl->wstate == WSTATE_IDLE2) {
92 hdl->wstate = WSTATE_MSG3;
93 hdl->wtodo = sizeof(struct amsg);
94 }
95 if (hdl->wstate != WSTATE_MSG3) {
96 DPRINTF("_aucat_wmsg: bad state\n")do {} while(0);
97 abort();
98 }
99 while (hdl->wtodo > 0) {
100 data = (unsigned char *)&hdl->wmsg;
101 data += sizeof(struct amsg) - hdl->wtodo;
102 while ((n = write(hdl->fd, data, hdl->wtodo)) == -1) {
103 if (errno(*__errno()) == EINTR4)
104 continue;
105 if (errno(*__errno()) != EAGAIN35) {
106 *eof = 1;
107 DPERROR("_aucat_wmsg: write")do {} while(0);
108 }
109 return 0;
110 }
111 hdl->wtodo -= n;
112 }
113 if (ntohl(hdl->wmsg.cmd)(__uint32_t)(__builtin_constant_p(hdl->wmsg.cmd) ? (__uint32_t
)(((__uint32_t)(hdl->wmsg.cmd) & 0xff) << 24 | (
(__uint32_t)(hdl->wmsg.cmd) & 0xff00) << 8 | ((__uint32_t
)(hdl->wmsg.cmd) & 0xff0000) >> 8 | ((__uint32_t
)(hdl->wmsg.cmd) & 0xff000000) >> 24) : __swap32md
(hdl->wmsg.cmd))
== AMSG_DATA5) {
114 hdl->wtodo = ntohl(hdl->wmsg.u.data.size)(__uint32_t)(__builtin_constant_p(hdl->wmsg.u.data.size) ?
(__uint32_t)(((__uint32_t)(hdl->wmsg.u.data.size) & 0xff
) << 24 | ((__uint32_t)(hdl->wmsg.u.data.size) &
0xff00) << 8 | ((__uint32_t)(hdl->wmsg.u.data.size)
& 0xff0000) >> 8 | ((__uint32_t)(hdl->wmsg.u.data
.size) & 0xff000000) >> 24) : __swap32md(hdl->wmsg
.u.data.size))
;
115 hdl->wstate = WSTATE_DATA4;
116 } else {
117 hdl->wtodo = 0xdeadbeef;
118 hdl->wstate = WSTATE_IDLE2;
119 }
120 return 1;
121}
122
123size_t
124_aucat_rdata(struct aucat *hdl, void *buf, size_t len, int *eof)
125{
126 ssize_t n;
127
128 if (hdl->rstate != RSTATE_DATA1) {
129 DPRINTF("_aucat_rdata: bad state\n")do {} while(0);
130 abort();
131 }
132 if (len > hdl->rtodo)
133 len = hdl->rtodo;
134 while ((n = read(hdl->fd, buf, len)) == -1) {
135 if (errno(*__errno()) == EINTR4)
136 continue;
137 if (errno(*__errno()) != EAGAIN35) {
138 *eof = 1;
139 DPERROR("_aucat_rdata: read")do {} while(0);
140 }
141 return 0;
142 }
143 if (n == 0) {
144 DPRINTF("_aucat_rdata: eof\n")do {} while(0);
145 *eof = 1;
146 return 0;
147 }
148 hdl->rtodo -= n;
149 if (hdl->rtodo == 0) {
150 hdl->rstate = RSTATE_MSG0;
151 hdl->rtodo = sizeof(struct amsg);
152 }
153 DPRINTFN(2, "_aucat_rdata: read: n = %zd\n", n)do {} while(0);
154 return n;
155}
156
157size_t
158_aucat_wdata(struct aucat *hdl, const void *buf, size_t len,
159 unsigned int wbpf, int *eof)
160{
161 ssize_t n;
162 size_t datasize;
163
164 switch (hdl->wstate) {
165 case WSTATE_IDLE2:
166 datasize = len;
167 if (datasize > AMSG_DATAMAX0x1000)
168 datasize = AMSG_DATAMAX0x1000;
169 datasize -= datasize % wbpf;
170 if (datasize == 0)
171 datasize = wbpf;
172 hdl->wmsg.cmd = htonl(AMSG_DATA)(__uint32_t)(__builtin_constant_p(5) ? (__uint32_t)(((__uint32_t
)(5) & 0xff) << 24 | ((__uint32_t)(5) & 0xff00)
<< 8 | ((__uint32_t)(5) & 0xff0000) >> 8 | (
(__uint32_t)(5) & 0xff000000) >> 24) : __swap32md(5
))
;
173 hdl->wmsg.u.data.size = htonl(datasize)(__uint32_t)(__builtin_constant_p(datasize) ? (__uint32_t)(((
__uint32_t)(datasize) & 0xff) << 24 | ((__uint32_t)
(datasize) & 0xff00) << 8 | ((__uint32_t)(datasize)
& 0xff0000) >> 8 | ((__uint32_t)(datasize) & 0xff000000
) >> 24) : __swap32md(datasize))
;
174 hdl->wtodo = sizeof(struct amsg);
175 hdl->wstate = WSTATE_MSG3;
176 /* FALLTHROUGH */
177 case WSTATE_MSG3:
178 if (!_aucat_wmsg(hdl, eof))
179 return 0;
180 }
181 if (len > hdl->wtodo)
182 len = hdl->wtodo;
183 if (len == 0) {
184 DPRINTF("_aucat_wdata: len == 0\n")do {} while(0);
185 abort();
186 }
187 while ((n = write(hdl->fd, buf, len)) == -1) {
188 if (errno(*__errno()) == EINTR4)
189 continue;
190 if (errno(*__errno()) != EAGAIN35) {
191 *eof = 1;
192 DPERROR("_aucat_wdata: write")do {} while(0);
193 }
194 return 0;
195 }
196 DPRINTFN(2, "_aucat_wdata: write: n = %zd\n", n)do {} while(0);
197 hdl->wtodo -= n;
198 if (hdl->wtodo == 0) {
199 hdl->wstate = WSTATE_IDLE2;
200 hdl->wtodo = 0xdeadbeef;
201 }
202 return n;
203}
204
205static int
206aucat_mkcookie(unsigned char *cookie)
207{
208#define COOKIE_DIR"/.sndio" "/.sndio"
209#define COOKIE_SUFFIX"/.sndio/cookie" "/.sndio/cookie"
210#define TEMPL_SUFFIX".XXXXXXXX" ".XXXXXXXX"
211 struct stat sb;
212 char *home, *path = NULL((void *)0), *tmp = NULL((void *)0);
213 size_t home_len, path_len;
214 int fd, len;
215
216 /* please gcc */
217 path_len = 0xdeadbeef;
218
219 /*
220 * try to load the cookie
221 */
222 home = issetugid() ? NULL((void *)0) : getenv("HOME");
22
Assuming the condition is false
23
'?' condition is false
223 if (home == NULL((void *)0))
24
Assuming 'home' is not equal to NULL
25
Taking false branch
224 goto bad_gen;
225 home_len = strlen(home);
226 path = malloc(home_len + sizeof(COOKIE_SUFFIX"/.sndio/cookie"));
26
Value assigned to 'path'
227 if (path == NULL((void *)0))
27
Assuming 'path' is equal to NULL
28
Taking true branch
228 goto bad_gen;
29
Control jumps to line 263
229 memcpy(path, home, home_len);
230 memcpy(path + home_len, COOKIE_SUFFIX"/.sndio/cookie", sizeof(COOKIE_SUFFIX"/.sndio/cookie"));
231 path_len = home_len + sizeof(COOKIE_SUFFIX"/.sndio/cookie") - 1;
232 fd = open(path, O_RDONLY0x0000);
233 if (fd == -1) {
234 if (errno(*__errno()) != ENOENT2)
235 DPERROR(path)do {} while(0);
236 goto bad_gen;
237 }
238 if (fstat(fd, &sb) == -1) {
239 DPERROR(path)do {} while(0);
240 goto bad_close;
241 }
242 if (sb.st_mode & 0077) {
243 DPRINTF("%s has wrong permissions\n", path)do {} while(0);
244 goto bad_close;
245 }
246 len = read(fd, cookie, AMSG_COOKIELEN16);
247 if (len == -1) {
248 DPERROR(path)do {} while(0);
249 goto bad_close;
250 }
251 if (len != AMSG_COOKIELEN16) {
252 DPRINTF("%s: short read\n", path)do {} while(0);
253 goto bad_close;
254 }
255 close(fd);
256 goto done;
257bad_close:
258 close(fd);
259bad_gen:
260 /*
261 * generate a new cookie
262 */
263 arc4random_buf(cookie, AMSG_COOKIELEN16);
264
265 /*
266 * try to save the cookie
267 */
268
269 if (home
29.1
'home' is not equal to NULL
== NULL((void *)0))
30
Taking false branch
270 goto done;
271 tmp = malloc(path_len + sizeof(TEMPL_SUFFIX".XXXXXXXX"));
272 if (tmp == NULL((void *)0))
31
Assuming 'tmp' is not equal to NULL
32
Taking false branch
273 goto done;
274
275 /* create ~/.sndio directory */
276 memcpy(tmp, home, home_len);
277 memcpy(tmp + home_len, COOKIE_DIR"/.sndio", sizeof(COOKIE_DIR"/.sndio"));
278 if (mkdir(tmp, 0755) == -1 && errno(*__errno()) != EEXIST17)
33
Assuming the condition is false
279 goto done;
280
281 /* create cookie file in it */
282 memcpy(tmp, path, path_len);
34
Null pointer passed as 2nd argument to memory copy function
283 memcpy(tmp + path_len, TEMPL_SUFFIX".XXXXXXXX", sizeof(TEMPL_SUFFIX".XXXXXXXX"));
284 fd = mkstemp(tmp);
285 if (fd == -1) {
286 DPERROR(tmp)do {} while(0);
287 goto done;
288 }
289 if (write(fd, cookie, AMSG_COOKIELEN16) == -1) {
290 DPERROR(tmp)do {} while(0);
291 unlink(tmp);
292 close(fd);
293 goto done;
294 }
295 close(fd);
296 if (rename(tmp, path) == -1) {
297 DPERROR(tmp)do {} while(0);
298 unlink(tmp);
299 }
300done:
301 free(tmp);
302 free(path);
303 return 1;
304}
305
306static int
307aucat_connect_tcp(struct aucat *hdl, char *host, unsigned int unit)
308{
309 int s, error, opt;
310 struct addrinfo *ailist, *ai, aihints;
311 char serv[NI_MAXSERV32];
312
313 snprintf(serv, sizeof(serv), "%u", unit + AUCAT_PORT11025);
314 memset(&aihints, 0, sizeof(struct addrinfo));
315 aihints.ai_socktype = SOCK_STREAM1;
316 aihints.ai_protocol = IPPROTO_TCP6;
317 error = getaddrinfo(host, serv, &aihints, &ailist);
318 if (error) {
319 DPRINTF("%s: %s\n", host, gai_strerror(error))do {} while(0);
320 return 0;
321 }
322 s = -1;
323 for (ai = ailist; ai != NULL((void *)0); ai = ai->ai_next) {
324 s = socket(ai->ai_family, ai->ai_socktype | SOCK_CLOEXEC0x8000,
325 ai->ai_protocol);
326 if (s == -1) {
327 DPERROR("socket")do {} while(0);
328 continue;
329 }
330 restart:
331 if (connect(s, ai->ai_addr, ai->ai_addrlen) == -1) {
332 if (errno(*__errno()) == EINTR4)
333 goto restart;
334 DPERROR("connect")do {} while(0);
335 close(s);
336 s = -1;
337 continue;
338 }
339 break;
340 }
341 freeaddrinfo(ailist);
342 if (s == -1)
343 return 0;
344 opt = 1;
345 if (setsockopt(s, IPPROTO_TCP6, TCP_NODELAY0x01, &opt, sizeof(int)) == -1) {
346 DPERROR("setsockopt")do {} while(0);
347 close(s);
348 return 0;
349 }
350 hdl->fd = s;
351 return 1;
352}
353
354static int
355aucat_connect_un(struct aucat *hdl, unsigned int unit)
356{
357 struct sockaddr_un ca;
358 socklen_t len = sizeof(struct sockaddr_un);
359 uid_t uid;
360 int s;
361
362 uid = geteuid();
363 snprintf(ca.sun_path, sizeof(ca.sun_path),
364 SOCKPATH_DIR"/tmp/sndio" "-%u/" SOCKPATH_FILE"sock" "%u", uid, unit);
365 ca.sun_family = AF_UNIX1;
366 s = socket(AF_UNIX1, SOCK_STREAM1 | SOCK_CLOEXEC0x8000, 0);
367 if (s == -1)
368 return 0;
369 while (connect(s, (struct sockaddr *)&ca, len) == -1) {
370 if (errno(*__errno()) == EINTR4)
371 continue;
372 DPERROR(ca.sun_path)do {} while(0);
373 /* try shared server */
374 snprintf(ca.sun_path, sizeof(ca.sun_path),
375 SOCKPATH_DIR"/tmp/sndio" "/" SOCKPATH_FILE"sock" "%u", unit);
376 while (connect(s, (struct sockaddr *)&ca, len) == -1) {
377 if (errno(*__errno()) == EINTR4)
378 continue;
379 DPERROR(ca.sun_path)do {} while(0);
380 close(s);
381 return 0;
382 }
383 break;
384 }
385 hdl->fd = s;
386 DPRINTFN(2, "%s: connected\n", ca.sun_path)do {} while(0);
387 return 1;
388}
389
390static const char *
391parsestr(const char *str, char *rstr, unsigned int max)
392{
393 const char *p = str;
394
395 while (*p != '\0' && *p != ',' && *p != '/') {
396 if (--max == 0) {
397 DPRINTF("%s: string too long\n", str)do {} while(0);
398 return NULL((void *)0);
399 }
400 *rstr++ = *p++;
401 }
402 if (str == p) {
403 DPRINTF("%s: string expected\n", str)do {} while(0);
404 return NULL((void *)0);
405 }
406 *rstr = '\0';
407 return p;
408}
409
410int
411_aucat_open(struct aucat *hdl, const char *str, unsigned int mode)
412{
413 extern char *__progname;
414 int eof;
415 char host[NI_MAXHOST256], opt[AMSG_OPTMAX12];
416 const char *p;
417 unsigned int unit, devnum, type;
418
419 if ((p = _sndio_parsetype(str, "snd")) != NULL((void *)0))
1
Assuming the condition is true
2
Taking true branch
420 type = 0;
421 else if ((p = _sndio_parsetype(str, "midithru")) != NULL((void *)0))
422 type = 1;
423 else if ((p = _sndio_parsetype(str, "midi")) != NULL((void *)0))
424 type = 2;
425 else {
426 DPRINTF("%s: unsupported device type\n", str)do {} while(0);
427 return -1;
428 }
429 if (*p == '@') {
3
Assuming the condition is false
4
Taking false branch
430 p = parsestr(++p, host, NI_MAXHOST256);
431 if (p == NULL((void *)0))
432 return 0;
433 } else
434 *host = '\0';
435 if (*p == ',') {
5
Assuming the condition is false
6
Taking false branch
436 p = _sndio_parsenum(++p, &unit, 15);
437 if (p == NULL((void *)0))
438 return 0;
439 } else
440 unit = 0;
441 if (*p != '/') {
7
Assuming the condition is false
8
Taking false branch
442 DPRINTF("%s: '/' expected\n", str)do {} while(0);
443 return 0;
444 }
445 p++;
446 if (type
8.1
'type' is equal to 0
== 0) {
9
Taking true branch
447 if (*p < '0' || *p > '9') {
10
Assuming the condition is true
448 devnum = AMSG_NODEV255;
449 p = parsestr(p, opt, AMSG_OPTMAX12);
450 if (p == NULL((void *)0))
11
Assuming 'p' is not equal to NULL
12
Taking false branch
451 return 0;
452 } else {
453 p = _sndio_parsenum(p, &devnum, 15);
454 if (p == NULL((void *)0))
455 return 0;
456 if (*p == '.') {
457 p = parsestr(++p, opt, AMSG_OPTMAX12);
458 if (p == NULL((void *)0))
459 return 0;
460 } else
461 strlcpy(opt, "default", AMSG_OPTMAX12);
462 }
463 } else {
464 p = _sndio_parsenum(p, &devnum, 15);
465 if (p == NULL((void *)0))
466 return 0;
467 memset(opt, 0, sizeof(opt));
468 }
469 if (*p != '\0') {
13
Assuming the condition is false
14
Taking false branch
470 DPRINTF("%s: junk at end of dev name\n", p)do {} while(0);
471 return 0;
472 }
473 devnum += type * 16; /* XXX */
474 DPRINTFN(2, "_aucat_open: host=%s unit=%u devnum=%u opt=%s\n",do {} while(0)
15
Loop condition is false. Exiting loop
475 host, unit, devnum, opt)do {} while(0);
476 if (host[0] != '\0') {
16
Taking false branch
477 if (!aucat_connect_tcp(hdl, host, unit))
478 return 0;
479 } else {
480 if (!aucat_connect_un(hdl, unit))
17
Assuming the condition is false
18
Taking false branch
481 return 0;
482 }
483 hdl->rstate = RSTATE_MSG0;
484 hdl->rtodo = sizeof(struct amsg);
485 hdl->wstate = WSTATE_IDLE2;
486 hdl->wtodo = 0xdeadbeef;
487 hdl->maxwrite = 0;
488
489 /*
490 * say hello to server
491 */
492 AMSG_INIT(&hdl->wmsg)do { memset((&hdl->wmsg), 0xff, sizeof(struct amsg)); }
while (0)
;
19
Loop condition is false. Exiting loop
493 hdl->wmsg.cmd = htonl(AMSG_AUTH)(__uint32_t)(__builtin_constant_p(12) ? (__uint32_t)(((__uint32_t
)(12) & 0xff) << 24 | ((__uint32_t)(12) & 0xff00
) << 8 | ((__uint32_t)(12) & 0xff0000) >> 8 |
((__uint32_t)(12) & 0xff000000) >> 24) : __swap32md
(12))
;
20
'?' condition is true
494 if (!aucat_mkcookie(hdl->wmsg.u.auth.cookie))
21
Calling 'aucat_mkcookie'
495 goto bad_connect;
496 hdl->wtodo = sizeof(struct amsg);
497 if (!_aucat_wmsg(hdl, &eof))
498 goto bad_connect;
499 AMSG_INIT(&hdl->wmsg)do { memset((&hdl->wmsg), 0xff, sizeof(struct amsg)); }
while (0)
;
500 hdl->wmsg.cmd = htonl(AMSG_HELLO)(__uint32_t)(__builtin_constant_p(10) ? (__uint32_t)(((__uint32_t
)(10) & 0xff) << 24 | ((__uint32_t)(10) & 0xff00
) << 8 | ((__uint32_t)(10) & 0xff0000) >> 8 |
((__uint32_t)(10) & 0xff000000) >> 24) : __swap32md
(10))
;
501 hdl->wmsg.u.hello.version = AMSG_VERSION7;
502 hdl->wmsg.u.hello.mode = htons(mode)(__uint16_t)(__builtin_constant_p(mode) ? (__uint16_t)(((__uint16_t
)(mode) & 0xffU) << 8 | ((__uint16_t)(mode) & 0xff00U
) >> 8) : __swap16md(mode))
;
503 hdl->wmsg.u.hello.devnum = devnum;
504 hdl->wmsg.u.hello.id = htonl(getpid())(__uint32_t)(__builtin_constant_p(getpid()) ? (__uint32_t)(((
__uint32_t)(getpid()) & 0xff) << 24 | ((__uint32_t)
(getpid()) & 0xff00) << 8 | ((__uint32_t)(getpid())
& 0xff0000) >> 8 | ((__uint32_t)(getpid()) & 0xff000000
) >> 24) : __swap32md(getpid()))
;
505 strlcpy(hdl->wmsg.u.hello.who, __progname,
506 sizeof(hdl->wmsg.u.hello.who));
507 strlcpy(hdl->wmsg.u.hello.opt, opt,
508 sizeof(hdl->wmsg.u.hello.opt));
509 hdl->wtodo = sizeof(struct amsg);
510 if (!_aucat_wmsg(hdl, &eof))
511 goto bad_connect;
512 hdl->rtodo = sizeof(struct amsg);
513 if (!_aucat_rmsg(hdl, &eof)) {
514 DPRINTF("aucat_init: mode refused\n")do {} while(0);
515 goto bad_connect;
516 }
517 if (ntohl(hdl->rmsg.cmd)(__uint32_t)(__builtin_constant_p(hdl->rmsg.cmd) ? (__uint32_t
)(((__uint32_t)(hdl->rmsg.cmd) & 0xff) << 24 | (
(__uint32_t)(hdl->rmsg.cmd) & 0xff00) << 8 | ((__uint32_t
)(hdl->rmsg.cmd) & 0xff0000) >> 8 | ((__uint32_t
)(hdl->rmsg.cmd) & 0xff000000) >> 24) : __swap32md
(hdl->rmsg.cmd))
!= AMSG_ACK0) {
518 DPRINTF("aucat_init: protocol err\n")do {} while(0);
519 goto bad_connect;
520 }
521 return 1;
522 bad_connect:
523 while (close(hdl->fd) == -1 && errno(*__errno()) == EINTR4)
524 ; /* retry */
525 return 0;
526}
527
528void
529_aucat_close(struct aucat *hdl, int eof)
530{
531 char dummy[sizeof(struct amsg)];
532 ssize_t n;
533
534 if (!eof) {
535 AMSG_INIT(&hdl->wmsg)do { memset((&hdl->wmsg), 0xff, sizeof(struct amsg)); }
while (0)
;
536 hdl->wmsg.cmd = htonl(AMSG_BYE)(__uint32_t)(__builtin_constant_p(11) ? (__uint32_t)(((__uint32_t
)(11) & 0xff) << 24 | ((__uint32_t)(11) & 0xff00
) << 8 | ((__uint32_t)(11) & 0xff0000) >> 8 |
((__uint32_t)(11) & 0xff000000) >> 24) : __swap32md
(11))
;
537 hdl->wtodo = sizeof(struct amsg);
538 if (!_aucat_wmsg(hdl, &eof))
539 goto bad_close;
540
541 /*
542 * block until the peer disconnects
543 */
544 while (1) {
545 n = read(hdl->fd, dummy, sizeof(dummy));
546 if (n == -1) {
547 if (errno(*__errno()) == EINTR4)
548 continue;
549 break;
550 }
551 if (n == 0)
552 break;
553 }
554 }
555 bad_close:
556 while (close(hdl->fd) == -1 && errno(*__errno()) == EINTR4)
557 ; /* nothing */
558}
559
560int
561_aucat_setfl(struct aucat *hdl, int nbio, int *eof)
562{
563 if (fcntl(hdl->fd, F_SETFL4, nbio ? O_NONBLOCK0x0004 : 0) == -1) {
564 DPERROR("_aucat_setfl: fcntl")do {} while(0);
565 *eof = 1;
566 return 0;
567 }
568 return 1;
569}
570
571int
572_aucat_pollfd(struct aucat *hdl, struct pollfd *pfd, int events)
573{
574 if (hdl->rstate == RSTATE_MSG0)
575 events |= POLLIN0x0001;
576 pfd->fd = hdl->fd;
577 pfd->events = events;
578 return 1;
579}
580
581int
582_aucat_revents(struct aucat *hdl, struct pollfd *pfd)
583{
584 int revents = pfd->revents;
585
586 DPRINTFN(2, "_aucat_revents: revents: %x\n", revents)do {} while(0);
587 return revents;
588}