⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 common.c

📁 Sigma SMP8634 Mrua v. 2.8.2.0
💻 C
📖 第 1 页 / 共 2 页
字号:
/*- * Copyright (c) 1998-2004 Dag-Erling Co飀an Sm鴕grav * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer *    in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products *    derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#define ALLOW_OS_CODE 1#include <sys/cdefs.h>#include <sys/param.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/uio.h>#include <sys/fcntl.h>#include <netinet/in.h>#include <errno.h>#include <netdb.h>#include <pwd.h>#include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include "../include/rmlibhttp.h"#include "common.h"/*** Local data **************************************************************//* * Error messages for resolver errors */static struct fetcherr _netdb_errlist[] = {#ifdef EAI_NODATA	{ EAI_NODATA,	FETCH_RESOLV,	"Host not found" },#endif	{ EAI_AGAIN,	FETCH_TEMP,	"Transient resolver failure" },	{ EAI_FAIL,	FETCH_RESOLV,	"Non-recoverable resolver failure" },	{ EAI_NONAME,	FETCH_RESOLV,	"No address record" },	{ -1,		FETCH_UNKNOWN,	"Unknown resolver error" }};/* End-of-Line */static const RMascii ENDL[3] = "\r\n";/*** Error-reporting functions ***********************************************//* * Map error code to string */static struct fetcherr *_fetch_finderr(struct fetcherr *p, RMint32 e){	while (p->num != -1 && p->num != e)		p++;	return (p);}/* * Set error code */void_fetch_seterr(struct fetcherr *p, RMint32 e){	p = _fetch_finderr(p, e);	fetchLastErrCode = p->cat;	snprintf(fetchLastErrString, MAXERRSTRING, "%s", p->string);}/* * Set error code according to errno */void_fetch_syserr(void){	switch (errno) {	case 0:		fetchLastErrCode = FETCH_OK;		break;	case EPERM:	case EACCES:	case EROFS:		fetchLastErrCode = FETCH_AUTH;		break;	case ENOENT:	case EISDIR: /* XXX */		fetchLastErrCode = FETCH_UNAVAIL;		break;	case ENOMEM:		fetchLastErrCode = FETCH_MEMORY;		break;	case EBUSY:	case EAGAIN:		fetchLastErrCode = FETCH_TEMP;		break;	case EEXIST:		fetchLastErrCode = FETCH_EXISTS;		break;	case ENOSPC:		fetchLastErrCode = FETCH_FULL;		break;	case EADDRINUSE:	case EADDRNOTAVAIL:	case ENETDOWN:	case ENETUNREACH:	case ENETRESET:	case EHOSTUNREACH:		fetchLastErrCode = FETCH_NETWORK;		break;	case ECONNABORTED:	case ECONNRESET:		fetchLastErrCode = FETCH_ABORT;		break;	case ETIMEDOUT:		fetchLastErrCode = FETCH_TIMEOUT;		break;	case EPIPE:		fetchLastErrCode = FETCH_PIPE;		break;	case ECONNREFUSED:	case EHOSTDOWN:		fetchLastErrCode = FETCH_DOWN;		break;default:		fetchLastErrCode = FETCH_UNKNOWN;	}	snprintf(fetchLastErrString, MAXERRSTRING, "%s", strerror(errno));}/* * Emit status message */void_fetch_info(const RMascii *fmt, ...){	va_list ap;	va_start(ap, fmt);	vfprintf(stderr, fmt, ap);	va_end(ap);	fputc('\n', stderr);}/*** Network-related utility functions ***************************************//* * Return the default port for a scheme */RMint32_fetch_default_port(const RMascii *scheme){	return (HTTP_DEFAULT_PORT);}/* * Return the default proxy port for a scheme */RMint32_fetch_default_proxy_port(const RMascii *scheme){	return (HTTP_DEFAULT_PROXY_PORT);}/* * Create a connection for an existing descriptor. */conn_t *_fetch_reopen(RMint32 sd){	conn_t *conn;	/* allocate and fill connection structure */	if ((conn = RMCalloc(1, sizeof(*conn))) == NULL)		return (NULL);	conn->sd = sd;	++conn->ref;	return (conn);}/* * Bump a connection's reference count. */conn_t *_fetch_ref(conn_t *conn){	++conn->ref;	return (conn);}/* * Bind a socket to a specific local address */RMint32_fetch_bind(RMint32 sd, RMint32 af, const RMascii *addr){	struct addrinfo hints, *res, *res0;	RMint32 err;	RMMemset(&hints, 0, sizeof(hints));	hints.ai_family = af;	hints.ai_socktype = SOCK_STREAM;	hints.ai_protocol = 0;	if ((err = getaddrinfo(addr, NULL, &hints, &res0)) != 0)		return (-1);	for (res = res0; res; res = res->ai_next)		if (bind(sd, res->ai_addr, res->ai_addrlen) == 0)			return (0);	return (-1);}/* * Establish a TCP connection to the specified port on the specified host. */conn_t *_fetch_connect(const RMascii *host, RMint32 port, RMint32 af, RMint32 verbose){	conn_t *conn;	RMascii pbuf[10];	const RMascii *bindaddr;	struct addrinfo hints, *res, *res0;	RMint32 sd, err, r;	long fcntl_arg=0;	RMDBGLOG((HTTPDEBUG, "---> %s:%ld\n", host, port));	if (verbose)		_fetch_info("looking up %s", host);	/* look up host name and set up socket address structure */	snprintf(pbuf, sizeof(pbuf), "%ld", port);	RMMemset(&hints, 0, sizeof(hints));	hints.ai_family = af;	hints.ai_socktype = SOCK_STREAM;	hints.ai_protocol = 0;	if ((err = getaddrinfo(host, pbuf, &hints, &res0)) != 0) {		_netdb_seterr(err);		return (NULL);	}	bindaddr = getenv("FETCH_BIND_ADDRESS");	if (verbose)		_fetch_info("connecting to %s:%d", host, port);	/* try to connect */	for (sd = -1, res = res0; res; sd = -1, res = res->ai_next) {		if ((sd = socket(res->ai_family, res->ai_socktype,                        res->ai_protocol)) == -1)			continue;		if (bindaddr != NULL && *bindaddr != '\0' &&		    _fetch_bind(sd, res->ai_family, bindaddr) != 0) {			_fetch_info("failed to bind to '%s'", bindaddr);			close(sd);			continue;		}		/* make the socket non blocking */		if (fetchTimeout) {			fcntl_arg = fcntl(sd, F_GETFL);			fcntl(sd, F_SETFL, fcntl_arg|O_NONBLOCK);		}		if (connect(sd, res->ai_addr, res->ai_addrlen) == 0)			break;		else if (fetchTimeout && (errno == EINPROGRESS)) {			fd_set writefds;			struct timeval now, timeout, wait;						FD_ZERO(&writefds);			gettimeofday(&timeout, NULL);			/* give more timeout connect than for read/write */			timeout.tv_sec += 2*fetchTimeout;						while (!FD_ISSET(sd, &writefds)) {				gettimeofday(&now, NULL);				wait.tv_sec = timeout.tv_sec - now.tv_sec;				wait.tv_usec = timeout.tv_usec - now.tv_usec;				if (wait.tv_usec < 0) {					wait.tv_usec += 1000000;					wait.tv_sec--;				}				if (wait.tv_sec < 0) {					errno = ETIMEDOUT;					_fetch_syserr();					break;				}				errno = 0;				FD_SET(sd, &writefds);				r = select(sd + 1, NULL, &writefds, NULL, &wait);				if (r == -1) {					if (errno == EINTR && fetchRestartCalls)						continue;					_fetch_syserr();					break;				}			}						if (FD_ISSET(sd, &writefds)) {				break;			}		}		close(sd);	}	/* restore the blocking flag */	if (fetchTimeout) 		fcntl(sd, F_SETFL, fcntl_arg&~O_NONBLOCK);	freeaddrinfo(res0);	if (sd == -1) {		_fetch_syserr();		return (NULL);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -