support.c revision 133211
11573Srgrimes/*
21573Srgrimes * Copyright (C) 2004
31573Srgrimes * 	Hartmut Brandt.
41573Srgrimes * 	All rights reserved.
51573Srgrimes *
61573Srgrimes * Author: Harti Brandt <harti@freebsd.org>
71573Srgrimes *
81573Srgrimes * Redistribution and use in source and binary forms, with or without
91573Srgrimes * modification, are permitted provided that the following conditions
101573Srgrimes * are met:
111573Srgrimes * 1. Redistributions of source code must retain the above copyright
121573Srgrimes *    notice, this list of conditions and the following disclaimer.
131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
141573Srgrimes *    notice, this list of conditions and the following disclaimer in the
151573Srgrimes *    documentation and/or other materials provided with the distribution.
161573Srgrimes *
171573Srgrimes * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
181573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
211573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271573Srgrimes * SUCH DAMAGE.
281573Srgrimes *
291573Srgrimes * $Begemot: bsnmp/lib/support.c,v 1.1 2004/08/06 08:47:58 brandt Exp $
301573Srgrimes *
311573Srgrimes * Functions that are missing on certain systems.
321573Srgrimes */
3350476Speter#include <stdio.h>
341573Srgrimes#include <stdlib.h>
35109043Stjr#include <stdarg.h>
361573Srgrimes#include <errno.h>
371573Srgrimes#include <string.h>
381573Srgrimes#include "support.h"
391573Srgrimes
401573Srgrimes#ifndef HAVE_ERR_H
41111285Sru
421573Srgrimesvoid
43111285Sruwarnx(const char *fmt, ...)
441573Srgrimes{
451573Srgrimes	va_list ap;
4659460Sphantom
4759460Sphantom	va_start(ap, fmt);
481573Srgrimes	fprintf(stderr, "warning: ");
4984306Sru	vfprintf(stderr, fmt, ap);
501573Srgrimes	fprintf(stderr, "\n");
511573Srgrimes	va_end(ap);
521573Srgrimes}
531573Srgrimes
541573Srgrimesvoid
55109043Stjrwarn(const char *fmt, ...)
56109043Stjr{
571573Srgrimes	va_list ap;
581573Srgrimes	int e = errno;
59109043Stjr
60109043Stjr	va_start(ap, fmt);
611573Srgrimes	fprintf(stderr, "warning: ");
621573Srgrimes	vfprintf(stderr, fmt, ap);
631573Srgrimes	fprintf(stderr, ": %s\n", strerror(e));
641573Srgrimes	va_end(ap);
651573Srgrimes}
661573Srgrimes
671573Srgrimesvoid
681573Srgrimeserrx(int code, const char *fmt, ...)
691573Srgrimes{
701573Srgrimes	va_list ap;
711573Srgrimes
7244286Shoek	va_start(ap, fmt);
7344286Shoek	fprintf(stderr, "error: ");
74127120Stjr	vfprintf(stderr, fmt, ap);
75127120Stjr	fprintf(stderr, "\n");
76127120Stjr	va_end(ap);
77127120Stjr	exit(code);
78127120Stjr}
79127120Stjr
80127120Stjrvoid
81127120Stjrerr(int code, const char *fmt, ...)
821573Srgrimes{
8344286Shoek	va_list ap;
8444286Shoek	int e = errno;
85109057Stjr
861573Srgrimes	va_start(ap, fmt);
871573Srgrimes	fprintf(stderr, "error: ");
881573Srgrimes	vfprintf(stderr, fmt, ap);
89107619Sru	fprintf(stderr, ": %s\n", strerror(e));
901573Srgrimes	va_end(ap);
911573Srgrimes	exit(code);
921573Srgrimes}
931573Srgrimes
941573Srgrimes#endif
95108040Sru
961573Srgrimes#ifndef HAVE_STRLCPY
971573Srgrimes
98109043Stjrsize_t
99109043Stjrstrlcpy(char *dst, const char *src, size_t len)
100109043Stjr{
101109043Stjr	size_t ret = strlen(dst);
102109043Stjr
103109043Stjr	while (len > 1) {
104109043Stjr		*dst++ = *src++;
105109043Stjr		len--;
106109043Stjr	}
107109043Stjr	if (len > 0)
108109043Stjr		*dst = '\0';
109109043Stjr	return (ret);
110111285Sru}
111109043Stjr
112109043Stjr#endif
113109043Stjr
114109043Stjr#ifndef HAVE_GETADDRINFO
1151573Srgrimes
1161573Srgrimes#include <sys/types.h>
1171573Srgrimes#include <sys/socket.h>
118109043Stjr#include <netinet/in.h>
119109043Stjr#include <netdb.h>
120109043Stjr
1211573Srgrimesextern int h_nerr;
122109043Stjrextern int h_errno;
1231573Srgrimesextern const char *h_errlist[];
1241573Srgrimes
1251573Srgrimes/*
1261573Srgrimes * VERY poor man's implementation
1271573Srgrimes */
1281573Srgrimesint
1291573Srgrimesgetaddrinfo(const char *host, const char *port, const struct addrinfo *hints,
1301573Srgrimes    struct addrinfo **res)
1311573Srgrimes{
1321573Srgrimes	struct hostent *hent;
1331573Srgrimes	struct sockaddr_in *s;
1341573Srgrimes	struct servent *sent;
1351573Srgrimes
1361573Srgrimes	if ((hent = gethostbyname(host)) == NULL)
137109043Stjr		return (h_errno);
1381573Srgrimes	if (hent->h_addrtype != hints->ai_family)
1391573Srgrimes		return (HOST_NOT_FOUND);
140104750Stjr	if (hent->h_addrtype != AF_INET)
1411573Srgrimes		return (HOST_NOT_FOUND);
1421573Srgrimes
1431573Srgrimes	if ((*res = malloc(sizeof(**res))) == NULL)
1441573Srgrimes		return (HOST_NOT_FOUND);
1451573Srgrimes
1461573Srgrimes	(*res)->ai_flags = hints->ai_flags;
1471573Srgrimes	(*res)->ai_family = hints->ai_family;
1481573Srgrimes	(*res)->ai_socktype = hints->ai_socktype;
14973088Sru	(*res)->ai_protocol = hints->ai_protocol;
150109043Stjr	(*res)->ai_next = NULL;
151109043Stjr
152109043Stjr	if (((*res)->ai_addr = malloc(sizeof(struct sockaddr_in))) == NULL) {
153109043Stjr		freeaddrinfo(*res);
154109043Stjr		return (HOST_NOT_FOUND);
155109043Stjr	}
1561573Srgrimes	(*res)->ai_addrlen = sizeof(struct sockaddr_in);
1571573Srgrimes	s = (struct sockaddr_in *)(*res)->ai_addr;
1581573Srgrimes	s->sin_family = hints->ai_family;
1591573Srgrimes	s->sin_len = sizeof(*s);
1601573Srgrimes	memcpy(&s->sin_addr, hent->h_addr, 4);
1611573Srgrimes
162108040Sru	if ((sent = getservbyname(port, NULL)) == NULL) {
1631573Srgrimes		freeaddrinfo(*res);
1641573Srgrimes		return (HOST_NOT_FOUND);
1651573Srgrimes	}
166	s->sin_port = sent->s_port;
167
168	return (0);
169}
170
171const char *
172gai_strerror(int e)
173{
174
175	if (e < 0 || e >= h_nerr)
176		return ("unknown error");
177	return (h_errlist[e]);
178}
179
180void
181freeaddrinfo(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