1 /*
2 * Copyright (C) 2004
3 * Hartmut Brandt.
4 * All rights reserved.
5 *
6 * Author: Harti Brandt <harti@freebsd.org>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $Begemot: bsnmp/lib/support.c,v 1.1 2004/08/06 08:47:58 brandt Exp $
30 *
31 * Functions that are missing on certain systems.
32 */
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <stdarg.h>
36 #include <errno.h>
37 #include <string.h>
38 #include "support.h"
39
40 #ifndef HAVE_ERR_H
41
42 void
warnx(const char * fmt,...)43 warnx(const char *fmt, ...)
44 {
45 va_list ap;
46
47 va_start(ap, fmt);
48 fprintf(stderr, "warning: ");
49 vfprintf(stderr, fmt, ap);
50 fprintf(stderr, "\n");
51 va_end(ap);
52 }
53
54 void
warn(const char * fmt,...)55 warn(const char *fmt, ...)
56 {
57 va_list ap;
58 int e = errno;
59
60 va_start(ap, fmt);
61 fprintf(stderr, "warning: ");
62 vfprintf(stderr, fmt, ap);
63 fprintf(stderr, ": %s\n", strerror(e));
64 va_end(ap);
65 }
66
67 void
errx(int code,const char * fmt,...)68 errx(int code, const char *fmt, ...)
69 {
70 va_list ap;
71
72 va_start(ap, fmt);
73 fprintf(stderr, "error: ");
74 vfprintf(stderr, fmt, ap);
75 fprintf(stderr, "\n");
76 va_end(ap);
77 exit(code);
78 }
79
80 void
err(int code,const char * fmt,...)81 err(int code, const char *fmt, ...)
82 {
83 va_list ap;
84 int e = errno;
85
86 va_start(ap, fmt);
87 fprintf(stderr, "error: ");
88 vfprintf(stderr, fmt, ap);
89 fprintf(stderr, ": %s\n", strerror(e));
90 va_end(ap);
91 exit(code);
92 }
93
94 #endif
95
96 #ifndef HAVE_STRLCPY
97
98 size_t
strlcpy(char * dst,const char * src,size_t len)99 strlcpy(char *dst, const char *src, size_t len)
100 {
101 size_t ret = strlen(dst);
102
103 while (len > 1) {
104 *dst++ = *src++;
105 len--;
106 }
107 if (len > 0)
108 *dst = '\0';
109 return (ret);
110 }
111
112 #endif
113
114 #ifndef HAVE_GETADDRINFO
115
116 #include <sys/types.h>
117 #include <sys/socket.h>
118 #include <netinet/in.h>
119 #include <netdb.h>
120
121 extern int h_nerr;
122 extern int h_errno;
123 extern const char *h_errlist[];
124
125 /*
126 * VERY poor man's implementation
127 */
128 int
getaddrinfo(const char * host,const char * port,const struct addrinfo * hints,struct addrinfo ** res)129 getaddrinfo(const char *host, const char *port, const struct addrinfo *hints,
130 struct addrinfo **res)
131 {
132 struct hostent *hent;
133 struct sockaddr_in *s;
134 struct servent *sent;
135
136 if ((hent = gethostbyname(host)) == NULL)
137 return (h_errno);
138 if (hent->h_addrtype != hints->ai_family)
139 return (HOST_NOT_FOUND);
140 if (hent->h_addrtype != AF_INET)
141 return (HOST_NOT_FOUND);
142
143 if ((*res = malloc(sizeof(**res))) == NULL)
144 return (HOST_NOT_FOUND);
145
146 (*res)->ai_flags = hints->ai_flags;
147 (*res)->ai_family = hints->ai_family;
148 (*res)->ai_socktype = hints->ai_socktype;
149 (*res)->ai_protocol = hints->ai_protocol;
150 (*res)->ai_next = NULL;
151
152 if (((*res)->ai_addr = malloc(sizeof(struct sockaddr_in))) == NULL) {
153 freeaddrinfo(*res);
154 return (HOST_NOT_FOUND);
155 }
156 (*res)->ai_addrlen = sizeof(struct sockaddr_in);
157 s = (struct sockaddr_in *)(*res)->ai_addr;
158 s->sin_family = hints->ai_family;
159 s->sin_len = sizeof(*s);
160 memcpy(&s->sin_addr, hent->h_addr, 4);
161
162 if ((sent = getservbyname(port, NULL)) == NULL) {
163 freeaddrinfo(*res);
164 return (HOST_NOT_FOUND);
165 }
166 s->sin_port = sent->s_port;
167
168 return (0);
169 }
170
171 const char *
gai_strerror(int e)172 gai_strerror(int e)
173 {
174
175 if (e < 0 || e >= h_nerr)
176 return ("unknown error");
177 return (h_errlist[e]);
178 }
179
180 void
freeaddrinfo(struct addrinfo * p)181 freeaddrinfo(struct addrinfo *p)
182 {
183 struct addrinfo *next;
184
185 while (p != NULL) {
186 next = p->ai_next;
187 if (p->ai_addr != NULL)
188 free(p->ai_addr);
189 free(p);
190 p = next;
191 }
192 }
193
194 #endif
195