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

📄 tcpip.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 2 页
字号:
        *addrlen = 0;    if (check_ip && (*check_ip)(cd, (const char *) &addr,        sizeof(addr), AF_INET))    {	h->cerrno = CSDENY;#ifdef WIN32        closesocket(h->newfd);#else        close(h->newfd);#endif	h->newfd = -1;	return -1;    }    h->state = CS_ST_INCON;    tcpip_setsockopt (h->newfd);    return 0;}COMSTACK tcpip_accept(COMSTACK h){    COMSTACK cnew;    tcpip_state *state, *st = (tcpip_state *)h->cprivate;#ifdef WIN32    unsigned long tru = 1;#endif    TRC(fprintf(stderr, "tcpip_accept\n"));    if (h->state == CS_ST_INCON)    {	if (!(cnew = (COMSTACK)xmalloc(sizeof(*cnew))))	{	    h->cerrno = CSYSERR;#ifdef WIN32	    closesocket(h->newfd);#else	    close(h->newfd);#endif	    h->newfd = -1;	    return 0;	}	memcpy(cnew, h, sizeof(*h));	cnew->iofile = h->newfd;	cnew->io_pending = 0;	if (!(state = (tcpip_state *)	      (cnew->cprivate = xmalloc(sizeof(tcpip_state)))))	{	    h->cerrno = CSYSERR;	    if (h->newfd != -1)	    {#ifdef WIN32		closesocket(h->newfd);#else		close(h->newfd);#endif		h->newfd = -1;	    }	    return 0;	}	if (!cnew->blocking && #ifdef WIN32	    (ioctlsocket(cnew->iofile, FIONBIO, &tru) < 0)#else	    (!cnew->blocking && fcntl(cnew->iofile, F_SETFL, O_NONBLOCK) < 0)#endif	    )	{	    h->cerrno = CSYSERR;	    if (h->newfd != -1)	    {#ifdef WIN32		closesocket(h->newfd);#else		close(h->newfd);#endif		h->newfd = -1;	    }	    xfree (cnew);	    xfree (state);	    return 0;	}	h->newfd = -1;	state->altbuf = 0;	state->altsize = state->altlen = 0;	state->towrite = state->written = -1;	state->complete = st->complete;	cnew->state = CS_ST_ACCEPT;	h->state = CS_ST_IDLE;	#if HAVE_OPENSSL_SSL_H	state->ctx = st->ctx;	state->ctx_alloc = 0;	state->ssl = st->ssl;	if (state->ctx)	{	    state->ssl = SSL_new (state->ctx);	    SSL_set_fd (state->ssl, cnew->iofile);	}#endif	h = cnew;    }    if (h->state == CS_ST_ACCEPT)    {#if HAVE_OPENSSL_SSL_H	tcpip_state *state = (tcpip_state *)h->cprivate;	if (state->ctx)	{	    int res = SSL_accept (state->ssl);	    TRC(fprintf(stderr, "SSL_accept\n"));	    if (res <= 0)	    {		int err = SSL_get_error(state->ssl, res);		if (err == SSL_ERROR_WANT_READ)		{		    h->io_pending = CS_WANT_READ;		    return h;		}		if (err == SSL_ERROR_WANT_WRITE)		{		    h->io_pending = CS_WANT_WRITE;		    return h;		}		cs_close (h);		return 0;	    }	}#endif    }    else    {        h->cerrno = CSOUTSTATE;        return 0;    }    h->io_pending = 0;    h->state = CS_ST_DATAXFER;    h->event = CS_DATA;    return h;}#define CS_TCPIP_BUFCHUNK 4096/* * Return: -1 error, >1 good, len of buffer, ==1 incomplete buffer, * 0=connection closed. */int tcpip_get(COMSTACK h, char **buf, int *bufsize){    tcpip_state *sp = (tcpip_state *)h->cprivate;    char *tmpc;    int tmpi, berlen, rest, req, tomove;    int hasread = 0, res;    TRC(fprintf(stderr, "tcpip_get: bufsize=%d\n", *bufsize));    if (sp->altlen) /* switch buffers */    {        TRC(fprintf(stderr, "  %d bytes in altbuf (0x%x)\n", sp->altlen,            (unsigned) sp->altbuf));        tmpc = *buf;        tmpi = *bufsize;        *buf = sp->altbuf;        *bufsize = sp->altsize;        hasread = sp->altlen;        sp->altlen = 0;        sp->altbuf = tmpc;        sp->altsize = tmpi;    }    h->io_pending = 0;    while (!(berlen = (*sp->complete)((unsigned char *)*buf, hasread)))    {        if (!*bufsize)        {            if (!(*buf = (char *)xmalloc(*bufsize = CS_TCPIP_BUFCHUNK)))                return -1;        }        else if (*bufsize - hasread < CS_TCPIP_BUFCHUNK)            if (!(*buf =(char *)xrealloc(*buf, *bufsize *= 2)))                return -1;#ifdef __sun__	yaz_set_errno( 0 );	/* unfortunatly, sun sometimes forgets to set errno in recv	   when EWOULDBLOCK etc. would be required (res = -1) */#endif	res = recv(h->iofile, *buf + hasread, CS_TCPIP_BUFCHUNK, 0);	TRC(fprintf(stderr, "  recv res=%d, hasread=%d\n", res, hasread));	if (res < 0)	{	  TRC(fprintf(stderr, "  recv errno=%d, (%s)\n", yaz_errno(), 		      strerror(yaz_errno())));#ifdef WIN32	    if (WSAGetLastError() == WSAEWOULDBLOCK)	    {		h->io_pending = CS_WANT_READ;		break;	    }	    else		return -1;#else	    if (yaz_errno() == EWOULDBLOCK #ifdef EAGAIN   #if EAGAIN != EWOULDBLOCK                || yaz_errno() == EAGAIN#endif#endif		|| yaz_errno() == EINPROGRESS#ifdef __sun__		|| yaz_errno() == ENOENT /* Sun's sometimes set errno to this */#endif		)	    {		h->io_pending = CS_WANT_READ;		break;	    }	    else if (yaz_errno() == 0)		continue;	    else	        return -1;#endif	}	else if (!res)	    return 0;        hasread += res;    }    TRC (fprintf (stderr, "  Out of read loop with hasread=%d, berlen=%d\n",		  hasread, berlen));    /* move surplus buffer (or everything if we didn't get a BER rec.) */    if (hasread > berlen)    {        tomove = req = hasread - berlen;        rest = tomove % CS_TCPIP_BUFCHUNK;        if (rest)            req += CS_TCPIP_BUFCHUNK - rest;        if (!sp->altbuf)        {            if (!(sp->altbuf = (char *)xmalloc(sp->altsize = req)))                return -1;        } else if (sp->altsize < req)            if (!(sp->altbuf =(char *)xrealloc(sp->altbuf, sp->altsize = req)))                return -1;        TRC(fprintf(stderr, "  Moving %d bytes to altbuf(0x%x)\n", tomove,            (unsigned) sp->altbuf));        memcpy(sp->altbuf, *buf + berlen, sp->altlen = tomove);    }    if (berlen < CS_TCPIP_BUFCHUNK - 1)        *(*buf + berlen) = '\0';    return berlen ? berlen : 1;}#if HAVE_OPENSSL_SSL_H/* * Return: -1 error, >1 good, len of buffer, ==1 incomplete buffer, * 0=connection closed. */int ssl_get(COMSTACK h, char **buf, int *bufsize){    tcpip_state *sp = (tcpip_state *)h->cprivate;    char *tmpc;    int tmpi, berlen, rest, req, tomove;    int hasread = 0, res;    TRC(fprintf(stderr, "ssl_get: bufsize=%d\n", *bufsize));    if (sp->altlen) /* switch buffers */    {        TRC(fprintf(stderr, "  %d bytes in altbuf (0x%x)\n", sp->altlen,            (unsigned) sp->altbuf));        tmpc = *buf;        tmpi = *bufsize;        *buf = sp->altbuf;        *bufsize = sp->altsize;        hasread = sp->altlen;        sp->altlen = 0;        sp->altbuf = tmpc;        sp->altsize = tmpi;    }    h->io_pending = 0;    while (!(berlen = (*sp->complete)((unsigned char *)*buf, hasread)))    {        if (!*bufsize)        {            if (!(*buf = (char *)xmalloc(*bufsize = CS_TCPIP_BUFCHUNK)))                return -1;        }        else if (*bufsize - hasread < CS_TCPIP_BUFCHUNK)            if (!(*buf =(char *)xrealloc(*buf, *bufsize *= 2)))                return -1;	res = SSL_read (sp->ssl, *buf + hasread, CS_TCPIP_BUFCHUNK);	TRC(fprintf(stderr, "  SSL_read res=%d, hasread=%d\n", res, hasread));	if (res <= 0)	{	    int ssl_err = SSL_get_error(sp->ssl, res);	    if (ssl_err == SSL_ERROR_WANT_READ)	    {		h->io_pending = CS_WANT_READ;		break;	    }	    if (ssl_err == SSL_ERROR_WANT_WRITE)	    {		h->io_pending = CS_WANT_WRITE;		break;	    }	    if (res == 0)		return 0;	    h->cerrno = CSERRORSSL;	    return -1;	}	hasread += res;    }    TRC (fprintf (stderr, "  Out of read loop with hasread=%d, berlen=%d\n",        hasread, berlen));    /* move surplus buffer (or everything if we didn't get a BER rec.) */    if (hasread > berlen)    {        tomove = req = hasread - berlen;        rest = tomove % CS_TCPIP_BUFCHUNK;        if (rest)            req += CS_TCPIP_BUFCHUNK - rest;        if (!sp->altbuf)        {            if (!(sp->altbuf = (char *)xmalloc(sp->altsize = req)))                return -1;        } else if (sp->altsize < req)            if (!(sp->altbuf =(char *)xrealloc(sp->altbuf, sp->altsize = req)))                return -1;        TRC(fprintf(stderr, "  Moving %d bytes to altbuf(0x%x)\n", tomove,            (unsigned) sp->altbuf));        memcpy(sp->altbuf, *buf + berlen, sp->altlen = tomove);    }    if (berlen < CS_TCPIP_BUFCHUNK - 1)        *(*buf + berlen) = '\0';    return berlen ? berlen : 1;}#endif/* * Returns 1, 0 or -1 * In nonblocking mode, you must call again with same buffer while * return value is 1. */int tcpip_put(COMSTACK h, char *buf, int size){    int res;    struct tcpip_state *state = (struct tcpip_state *)h->cprivate;    TRC(fprintf(stderr, "tcpip_put: size=%d\n", size));    h->io_pending = 0;    h->event = CS_DATA;    if (state->towrite < 0)    {        state->towrite = size;        state->written = 0;    }    else if (state->towrite != size)    {        h->cerrno = CSWRONGBUF;        return -1;    }    while (state->towrite > state->written)    {	if ((res =	     send(h->iofile, buf + state->written, size -		  state->written, #ifdef MSG_NOSIGNAL		  MSG_NOSIGNAL#else		  0#endif		 )) < 0)	{	    if (#ifdef WIN32		WSAGetLastError() == WSAEWOULDBLOCK#else	        yaz_errno() == EWOULDBLOCK #ifdef EAGAIN#if EAGAIN != EWOULDBLOCK             || yaz_errno() == EAGAIN#endif#endif#ifdef __sun__                || yaz_errno() == ENOENT /* Sun's sometimes set errno to this value! */#endif		|| yaz_errno() == EINPROGRESS#endif		)	    {		TRC(fprintf(stderr, "  Flow control stop\n"));		h->io_pending = CS_WANT_WRITE;		return 1;	    }	    h->cerrno = CSYSERR;	    return -1;	}	state->written += res;	TRC(fprintf(stderr, "  Wrote %d, written=%d, nbytes=%d\n",		    res, state->written, size));    }    state->towrite = state->written = -1;    TRC(fprintf(stderr, "  Ok\n"));    return 0;}#if HAVE_OPENSSL_SSL_H/* * Returns 1, 0 or -1 * In nonblocking mode, you must call again with same buffer while * return value is 1. */int ssl_put(COMSTACK h, char *buf, int size){    int res;    struct tcpip_state *state = (struct tcpip_state *)h->cprivate;    TRC(fprintf(stderr, "ssl_put: size=%d\n", size));    h->io_pending = 0;    h->event = CS_DATA;    if (state->towrite < 0)    {        state->towrite = size;        state->written = 0;    }    else if (state->towrite != size)    {        h->cerrno = CSWRONGBUF;        return -1;    }    while (state->towrite > state->written)    {	res = SSL_write (state->ssl, buf + state->written,			 size - state->written);	if (res <= 0)	{	    int ssl_err = SSL_get_error(state->ssl, res);	    if (ssl_err == SSL_ERROR_WANT_READ)	    {		h->io_pending = CS_WANT_READ;		return 1;	    }	    if (ssl_err == SSL_ERROR_WANT_WRITE)	    {		h->io_pending = CS_WANT_WRITE;		return 1;	    }	    h->cerrno = CSERRORSSL;	    return -1;	}	state->written += res;	TRC(fprintf(stderr, "  Wrote %d, written=%d, nbytes=%d\n",		    res, state->written, size));    }    state->towrite = state->written = -1;    TRC(fprintf(stderr, "  Ok\n"));    return 0;}#endifint tcpip_close(COMSTACK h){    tcpip_state *sp = (struct tcpip_state *)h->cprivate;    TRC(fprintf(stderr, "tcpip_close\n"));    if (h->iofile != -1)    {#if HAVE_OPENSSL_SSL_H	if (sp->ssl)	{	    SSL_shutdown (sp->ssl);	}#endif#ifdef WIN32        closesocket(h->iofile);#else        close(h->iofile);#endif    }    if (sp->altbuf)        xfree(sp->altbuf);#if HAVE_OPENSSL_SSL_H    if (sp->ssl)    {	TRC (fprintf(stderr, "SSL_free\n"));	SSL_free (sp->ssl);    }    sp->ssl = 0;    if (sp->ctx_alloc)	SSL_CTX_free (sp->ctx_alloc);#endif    xfree(sp);    xfree(h);    return 0;}char *tcpip_addrstr(COMSTACK h){    struct sockaddr_in addr;    tcpip_state *sp = (struct tcpip_state *)h->cprivate;    char *r, *buf = sp->buf;    YAZ_SOCKLEN_T len;    struct hostent *host;        len = sizeof(addr);    if (getpeername(h->iofile, (struct sockaddr*) &addr, &len) < 0)    {	h->cerrno = CSYSERR;	return 0;    }    if ((host = gethostbyaddr((char*)&addr.sin_addr, sizeof(addr.sin_addr),			      AF_INET)))	r = (char*) host->h_name;    else	r = inet_ntoa(addr.sin_addr);    if (h->protocol == PROTO_HTTP)        sprintf(buf, "http:%s", r);    else        sprintf(buf, "tcp:%s", r);#if HAVE_OPENSSL_SSL_H    if (sp->ctx)    {        if (h->protocol == PROTO_HTTP)            sprintf(buf, "https:%s", r);        else            sprintf(buf, "ssl:%s", r);    }#endif    return buf;}int static tcpip_set_blocking(COMSTACK p, int blocking){    unsigned long flag;        if (p->blocking == blocking)	return 1;#ifdef WIN32    flag = 1;    if (ioctlsocket(p->iofile, FIONBIO, &flag) < 0)	return 0;#else    flag = fcntl(p->iofile, F_GETFL, 0);    if(!blocking)	flag = flag & ~O_NONBLOCK;    else        flag = flag | O_NONBLOCK;    if (fcntl(p->iofile, F_SETFL, flag) < 0)	return 0;#endif    p->blocking = blocking;    return 1;}

⌨️ 快捷键说明

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