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