Esempio n. 1
0
FILE *
fetchPutFile(struct url *u, const char *flags)
{
	FILE *f;

	if (CHECK_FLAG('a'))
		f = fopen(u->doc, "a");
	else
		f = fopen(u->doc, "w+");

	if (f == NULL)
		_fetch_syserr();

	if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) {
		fclose(f);
		_fetch_syserr();
	}

	return (f);
}
Esempio n. 2
0
FILE *
fetchXGetFile(struct url *u, struct url_stat *us, const char *flags)
{
	FILE *f;

	if (us && fetchStatFile(u, us, flags) == -1)
		return (NULL);

	f = fopen(u->doc, "r");

	if (f == NULL)
		_fetch_syserr();

	if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) {
		fclose(f);
		_fetch_syserr();
	}

	return (f);
}
Esempio n. 3
0
static int
_fetch_stat_file(const char *fn, struct url_stat *us)
{
	struct stat sb;

	us->size = -1;
	us->atime = us->mtime = 0;
	if (stat(fn, &sb) == -1) {
		_fetch_syserr();
		return (-1);
	}
	us->size = sb.st_size;
	us->atime = sb.st_atime;
	us->mtime = sb.st_mtime;
	return (0);
}
Esempio n. 4
0
/*
 * Write a vector to a connection w/ timeout
 * Note: can modify the iovec.
 */
ssize_t
_fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt)
{
	struct timeval now, timeout, wait;
	fd_set writefds;
	ssize_t wlen, total;
	int r;

	if (fetchTimeout) {
		FD_ZERO(&writefds);
		gettimeofday(&timeout, NULL);
		timeout.tv_sec += fetchTimeout;
	}

	total = 0;
	while (iovcnt > 0) {
		while (fetchTimeout && !FD_ISSET(conn->sd, &writefds)) {
			FD_SET(conn->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 = WSA(ETIMEDOUT);
				_fetch_syserr();
				return (-1);
			}
			errno = 0;
			r = select(conn->sd + 1, NULL, &writefds, NULL, &wait);
			if (r == -1) {
				if (errno == WSA(EINTR) && fetchRestartCalls)
					continue;
				return (-1);
			}
		}
		errno = 0;
#ifdef WITH_SSL
		if (conn->ssl != NULL)
			wlen = SSL_write(conn->ssl,
			    iov->iov_base, iov->iov_len);
		else
#endif
#ifdef flagWIN32
			wlen = send(conn->sd, iov->iov_base, iov->iov_len, 0);
#else
			wlen = writev(conn->sd, iov, iovcnt);
#endif
		if (wlen == 0) {
			/* we consider a short write a failure */
			errno = EPIPE;
			_fetch_syserr();
			return (-1);
		}
		if (wlen < 0) {
			if (errno == EINTR && fetchRestartCalls)
				continue;
			return (-1);
		}
		total += wlen;
		while (iovcnt > 0 && wlen >= (ssize_t)iov->iov_len) {
			wlen -= iov->iov_len;
			iov++;
			iovcnt--;
		}
		if (iovcnt > 0) {
			iov->iov_len -= wlen;
			iov->iov_base = __DECONST(char *, iov->iov_base) + wlen;
		}
	}
Esempio n. 5
0
/*
 * Read a character from a connection w/ timeout
 */
ssize_t
_fetch_read(conn_t *conn, char *buf, size_t len)
{
	struct timeval now, timeout, wait;
	fd_set readfds;
	ssize_t rlen, total;
	int r;

	if (fetchTimeout) {
		FD_ZERO(&readfds);
		gettimeofday(&timeout, NULL);
		timeout.tv_sec += fetchTimeout;
	}

	total = 0;
	while (len > 0) {
		while (fetchTimeout && !FD_ISSET(conn->sd, &readfds)) {
			FD_SET(conn->sd, &readfds);
			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 = WSA(ETIMEDOUT);
				_fetch_syserr();
				return (-1);
			}
			errno = 0;
			r = select(conn->sd + 1, &readfds, NULL, NULL, &wait);
			if (r == -1) {
				if (errno == EINTR && fetchRestartCalls)
					continue;
				_fetch_syserr();
				return (-1);
			}
		}
#ifdef WITH_SSL
		if (conn->ssl != NULL)
			rlen = SSL_read(conn->ssl, buf, len);
		else
#endif
#ifdef flagWIN32
			rlen = recv(conn->sd, buf, len, 0);
#else
			rlen = read(conn->sd, buf, len);
#endif
		if (rlen == 0)
			break;
		if (rlen < 0) {
			if (errno == EINTR && fetchRestartCalls)
				continue;
			return (-1);
		}
		len -= rlen;
		buf += rlen;
		total += rlen;
	}
	return (total);
}
Esempio n. 6
0
/*
 * Establish a TCP connection to the specified port on the specified host.
 */
conn_t *
_fetch_connect(const char *host, int port, int af, int verbose)
{
	conn_t *conn;
	char pbuf[10];
	const char *bindaddr;
	struct addrinfo hints, *res, *res0;
	int sd, err;

	DEBUG(fprintf(stderr, "---> %s:%d\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), "%d", port);
	memset(&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);
#ifdef flagWIN32
			closesocket(sd);
#else
			close(sd);
#endif
			continue;
		}
		if (connect(sd, res->ai_addr, res->ai_addrlen) == 0)
			break;
#ifdef flagWIN32
		closesocket(sd);
#else
		close(sd);
#endif
	}
	freeaddrinfo(res0);
	if (sd == -1) {
		_fetch_syserr();
		return (NULL);
	}

	if ((conn = _fetch_reopen(sd)) == NULL) {
		_fetch_syserr();
#ifdef flagWIN32
		closesocket(sd);
#else
		close(sd);
#endif
	}
	return (conn);
}