]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/bsnmp/lib/support.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / bsnmp / lib / support.c
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
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
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
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
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
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
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 *
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
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