1/*
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Affero General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
6
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * GNU Affero General Public License for more details.
11
12 * You should have received a copy of the GNU Affero General Public License
13 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
14 */
15
16#include <stdio.h>
17#include <string.h>
18#include <unistd.h>
19#include <resolv.h>
20#include <alloca.h>
21#include <errno.h>
22#include <fcntl.h>
23#include <sys/socket.h>
24
25#if defined(__UCLIBC__) \
26 && (__UCLIBC_MAJOR__ == 0 \
27 && (__UCLIBC_MINOR__ < 9 || (__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ < 33)))
28
29#define NS_MAXCDNAME 255 /* max compressed domain name length */
30#define NS_MAXLABEL   63 /* max label length */
31
32int __attribute__ ((weak))
33dn_comp(const char *src, uint8_t *dst, int length,
34	uint8_t __attribute__((unused)) **dnptrs,
35	uint8_t __attribute__((unused)) **lastdnptr)
36{
37	uint8_t *buf, *ptr;
38	int len;
39
40	if (src == NULL || dst == NULL)
41		return -1;
42
43	buf = ptr = alloca(strlen(src) + 2);
44	while (src && *src) {
45		uint8_t *lenptr = ptr++;
46		for (len = 0; *src && *src != '.'; len++)
47			*ptr++ = *src++;
48		if (len == 0 || len > NS_MAXLABEL)
49			return -1;
50		*lenptr = len;
51		if (*src)
52			src++;
53	}
54	*ptr++ = 0;
55
56	len = ptr - buf;
57	if (len > NS_MAXCDNAME || len > length)
58		return -1;
59
60	memcpy(dst, buf, len);
61	return len;
62}
63
64#endif
65
66#if !defined(SOCK_CLOEXEC)
67
68int fflags(int sock, int flags)
69{
70	int err;
71
72	if (sock < 0)
73		return sock;
74
75	if (flags & O_CLOEXEC) {
76		if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0)
77			goto error;
78	}
79	return sock;
80
81error:
82	err = errno;
83	close(sock);
84	errno = err;
85	return -1;
86}
87
88#endif
89