common.c revision 40975
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: common.c,v 1.1 1998/11/05 19:48:16 des Exp $ 29 */ 30 31#include <sys/types.h> 32#include <sys/socket.h> 33#include <netinet/in.h> 34 35#include <com_err.h> 36#include <errno.h> 37#include <netdb.h> 38#include <string.h> 39#include <unistd.h> 40 41#include "fetch.h" 42#include "common.h" 43 44 45/*** Local data **************************************************************/ 46 47/* 48 * Error messages for resolver errors 49 */ 50static struct fetcherr _netdb_errlist[] = { 51 { HOST_NOT_FOUND, FETCH_RESOLV, "Host not found" }, 52 { TRY_AGAIN, FETCH_RESOLV, "Transient resolver failure" }, 53 { NO_RECOVERY, FETCH_RESOLV, "Non-recoverable resolver failure" }, 54 { NO_DATA, FETCH_RESOLV, "No address record" }, 55 { -1, FETCH_UNKNOWN, "Unknown resolver error" } 56}; 57 58static int com_err_initialized; 59 60/*** Error-reporting functions ***********************************************/ 61 62/* 63 * Initialize the common error library 64 */ 65static void 66_fetch_init_com_err(void) 67{ 68 initialize_ftch_error_table(); 69 com_err_initialized = 1; 70} 71 72/* 73 * Map error code to string 74 */ 75static int 76_fetch_finderr(struct fetcherr *p, int e) 77{ 78 int i; 79 for (i = 0; p[i].num != -1; i++) 80 if (p[i].num == e) 81 break; 82 return i; 83} 84 85/* 86 * Set error code 87 */ 88void 89_fetch_seterr(struct fetcherr *p, int e) 90{ 91 int n; 92 93 if (!com_err_initialized) 94 _fetch_init_com_err(); 95 96 n = _fetch_finderr(p, e); 97 com_err("libfetch", p[n].cat, "(%d %s)", e, p[n].string); 98} 99 100/* 101 * Set error code according to errno 102 */ 103void 104_fetch_syserr(void) 105{ 106 int cat; 107 108 if (!com_err_initialized) 109 _fetch_init_com_err(); 110 111 switch (errno) { 112 case 0: 113 cat = FETCH_OK; 114 break; 115 case EPERM: 116 case EACCES: 117 case EROFS: 118 case EAUTH: 119 case ENEEDAUTH: 120 cat = FETCH_AUTH; 121 break; 122 case ENOENT: 123 case EISDIR: /* XXX */ 124 cat = FETCH_UNAVAIL; 125 break; 126 case ENOMEM: 127 cat = FETCH_MEMORY; 128 break; 129 case EBUSY: 130 case EAGAIN: 131 cat = FETCH_TEMP; 132 break; 133 case EEXIST: 134 cat = FETCH_EXISTS; 135 break; 136 case ENOSPC: 137 cat = FETCH_FULL; 138 break; 139 case EADDRINUSE: 140 case EADDRNOTAVAIL: 141 case ENETDOWN: 142 case ENETUNREACH: 143 case ENETRESET: 144 case EHOSTUNREACH: 145 cat = FETCH_NETWORK; 146 break; 147 case ECONNABORTED: 148 case ECONNRESET: 149 cat = FETCH_ABORT; 150 break; 151 case ETIMEDOUT: 152 cat = FETCH_TIMEOUT; 153 break; 154 case ECONNREFUSED: 155 case EHOSTDOWN: 156 cat = FETCH_DOWN; 157 break; 158 default: 159 cat = FETCH_UNKNOWN; 160 } 161 com_err("libfetch", cat, "(%02d %s)", errno, strerror(errno)); 162} 163 164 165/*** Network-related utility functions ***************************************/ 166 167/* 168 * Establish a TCP connection to the specified port on the specified host. 169 */ 170int 171fetchConnect(char *host, int port) 172{ 173 struct sockaddr_in sin; 174 struct hostent *he; 175 int sd; 176 177#ifndef NDEBUG 178 fprintf(stderr, "\033[1m---> %s:%d\033[m\n", host, port); 179#endif 180 181 /* look up host name */ 182 if ((he = gethostbyname(host)) == NULL) { 183 _netdb_seterr(h_errno); 184 return -1; 185 } 186 187 /* set up socket address structure */ 188 bzero(&sin, sizeof(sin)); 189 bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length); 190 sin.sin_family = he->h_addrtype; 191 sin.sin_port = htons(port); 192 193 /* try to connect */ 194 if ((sd = socket(sin.sin_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { 195 _fetch_syserr(); 196 return -1; 197 } 198 if (connect(sd, (struct sockaddr *)&sin, sizeof sin) == -1) { 199 _fetch_syserr(); 200 close(sd); 201 return -1; 202 } 203 204 return sd; 205} 206