common.c revision 40939
1/*-
2 * Copyright (c) 1998 Dag-Erling Co�dan Sm�rgrav
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer
10 *    in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 *    derived from this software without specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 *	$Id$
29 */
30
31#include <sys/types.h>
32#include <sys/socket.h>
33#include <netinet/in.h>
34
35#include <errno.h>
36#include <netdb.h>
37#include <string.h>
38#include <unistd.h>
39
40#include "fetch.h"
41#include "common.h"
42
43/*** Local data **************************************************************/
44
45/*
46 * Error messages for resolver errors
47 */
48static struct fetcherr _netdb_errlist[] = {
49    { HOST_NOT_FOUND,	"Host not found" },
50    { TRY_AGAIN,	"Transient resolver failure" },
51    { NO_RECOVERY,	"Non-recoverable resolver failure" },
52    { NO_DATA,		"No address record" },
53    { -1,		"Unknown resolver error" }
54};
55#define _netdb_errstring(n)	_fetch_errstring(_netdb_errlist, n)
56#define _netdb_seterr(n)	_fetch_seterr(_netdb_errlist, n)
57
58
59/*** Error-reporting functions ***********************************************/
60
61/*
62 * Map error code to string
63 */
64const char *
65_fetch_errstring(struct fetcherr *p, int e)
66{
67    while ((p->num != -1) && (p->num != e))
68	p++;
69
70    return p->string;
71}
72
73/*
74 * Set error code
75 */
76void
77_fetch_seterr(struct fetcherr *p, int e)
78{
79    fetchLastErrCode = e;
80    fetchLastErrText = _fetch_errstring(p, e);
81}
82
83/*
84 * Set error code according to errno
85 */
86void
87_fetch_syserr(void)
88{
89    fetchLastErrCode = errno;
90    fetchLastErrText = strerror(errno);
91}
92
93
94/*** Network-related utility functions ***************************************/
95
96/*
97 * Establish a TCP connection to the specified port on the specified host.
98 */
99int
100fetchConnect(char *host, int port)
101{
102    struct sockaddr_in sin;
103    struct hostent *he;
104    int sd;
105
106#ifndef NDEBUG
107    fprintf(stderr, "\033[1m---> %s:%d\033[m\n", host, port);
108#endif
109
110    /* look up host name */
111    if ((he = gethostbyname(host)) == NULL) {
112	_netdb_seterr(h_errno);
113	return -1;
114    }
115
116    /* set up socket address structure */
117    bzero(&sin, sizeof(sin));
118    bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length);
119    sin.sin_family = he->h_addrtype;
120    sin.sin_port = htons(port);
121
122    /* try to connect */
123    if ((sd = socket(sin.sin_family, SOCK_STREAM, IPPROTO_TCP)) == -1) {
124	_fetch_syserr();
125	return -1;
126    }
127    if (connect(sd, (struct sockaddr *)&sin, sizeof sin) == -1) {
128	_fetch_syserr();
129	close(sd);
130	return -1;
131    }
132
133    return sd;
134}
135