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

📄 winnet.c

📁 一个FTP下载的源代码。代码质量非常高
💻 C
📖 第 1 页 / 共 3 页
字号:
	    } else {
		fatalbox(winsock_error_string(err));
	    }
	} else {
	    if (s->sending_oob) {
		if (nsent < len) {
		    memmove(s->oobdata, s->oobdata+nsent, len-nsent);
		    s->sending_oob = len - nsent;
		} else {
		    s->sending_oob = 0;
		}
	    } else {
		bufchain_consume(&s->output_data, nsent);
	    }
	}
    }
}

static int sk_tcp_write(Socket sock, const char *buf, int len)
{
    Actual_Socket s = (Actual_Socket) sock;

    /*
     * Add the data to the buffer list on the socket.
     */
    bufchain_add(&s->output_data, buf, len);

    /*
     * Now try sending from the start of the buffer list.
     */
    if (s->writable)
	try_send(s);

    return bufchain_size(&s->output_data);
}

static int sk_tcp_write_oob(Socket sock, const char *buf, int len)
{
    Actual_Socket s = (Actual_Socket) sock;

    /*
     * Replace the buffer list on the socket with the data.
     */
    bufchain_clear(&s->output_data);
    assert(len <= sizeof(s->oobdata));
    memcpy(s->oobdata, buf, len);
    s->sending_oob = len;

    /*
     * Now try sending from the start of the buffer list.
     */
    if (s->writable)
	try_send(s);

    return s->sending_oob;
}

int select_result(WPARAM wParam, LPARAM lParam)
{
    int ret;//, open;
    DWORD err;
    char buf[20480];		       /* nice big buffer for plenty of speed */
    Actual_Socket s;
    u_long atmark;

  	/* wParam is the socket itself */
	if (wParam == 0)
		return 1;				/* boggle */
    s = find234(sktree, (void *) wParam, cmpforsearch);
    if (!s)
	{
		return 1;		       /* boggle */
	}
    if ((err = WSAGETSELECTERROR(lParam)) != 0) {
	/*
	 * An error has occurred on this socket. Pass it to the
	 * plug.
	 */
	return plug_closing(s->plug, winsock_error_string(err), err, 0);
    }

    noise_ultralight(lParam);

    switch (WSAGETSELECTEVENT(lParam)) {
      case FD_CONNECT:
	s->connected = s->writable = 1;
	break;
      case FD_READ:
	/* In the case the socket is still frozen, we don't even bother */
	if (s->frozen) {
	    s->frozen_readable = 1;
	    break;
	}

	/*
	 * We have received data on the socket. For an oobinline
	 * socket, this might be data _before_ an urgent pointer,
	 * in which case we send it to the back end with type==1
	 * (data prior to urgent).
	 */
	//if (s->oobinline) {
	 //   atmark = 1;
	   // ioctlsocket(s->s, SIOCATMARK, &atmark);
	    /*
	     * Avoid checking the return value from ioctlsocket(),
	     * on the grounds that some WinSock wrappers don't
	     * support it. If it does nothing, we get atmark==1,
	     * which is equivalent to `no OOB pending', so the
	     * effect will be to non-OOB-ify any OOB data.
	     */
	//} else
	//    atmark = 1;
	atmark = 0;
	while (TRUE)
	{
		*(int *)buf=sizeof(buf)-4;
		FzSFtpIpc_SendRequest(SFTP_DATAID_CTS_READ, 4, buf);
		while (TRUE)
		{
			DWORD nID, nDataLength;
			if (!FzSFtpIpc_ReceiveRequest(&nID, &nDataLength, buf))
				cleanup_exit(1);
			if (nID==SFTP_DATAID_STC_READ)
			{
				if (nDataLength<4)
				{
					FzSFtpIpc_Trace("SFTP_DATAID_STC_READ->nDataLength<4");
					cleanup_exit(1);
				}
				ret=*(int *)buf;
				err=*((int *)buf+1);
				if (ret<0 || ret>20476)
				{
					FzSFtpIpc_Trace("SFTP_DATAID_STC_READ->ret out of range");
					cleanup_exit(1);
				}
				if (ret!=0)
					err=0;
				else if (err)
					ret=-1;				
				break;
			}
		}
		if (ret>=0 || err!=WSAEWOULDBLOCK)
			break;

		while (TRUE)
		{
			DWORD nID, nDataLength;
			char pData[20480];
			if (!FzSFtpIpc_ReceiveRequest(&nID, &nDataLength,pData))
				cleanup_exit(1);
			if (nID==SFTP_DATAID_STC_FDREAD)
			{
				if (nDataLength)
				{
					FzSFtpIpc_Trace("SFTP_DATAID_STC_FDREAD->nDataLength!=0");
					cleanup_exit(1);
				}
				break;
			}
		}		
	}




	//ret = recv(s->s, buf, sizeof(buf), 0);
	noise_ultralight(ret);
	if (ret < 0) {
	    //err = WSAGetLastError();
	    if (err == WSAEWOULDBLOCK) {
		break;
	    }
	}
	if (ret < 0) {
	    return plug_closing(s->plug, winsock_error_string(err), err,
				0);
	} else if (0 == ret) {
	    return plug_closing(s->plug, NULL, 0, 0);
	} else {
	    return plug_receive(s->plug, atmark ? 0 : 1, buf+4, ret);
	}
	break;
      case FD_OOB:
	/*
	 * This will only happen on a non-oobinline socket. It
	 * indicates that we can immediately perform an OOB read
	 * and get back OOB data, which we will send to the back
	 * end with type==2 (urgent data).
	 */
/*	ret = recv(s->s, buf, sizeof(buf), MSG_OOB);
	noise_ultralight(ret);
	if (ret <= 0) {
	    fatalbox(ret == 0 ? "Internal networking trouble" :
		     winsock_error_string(WSAGetLastError()));
	} else {
	    return plug_receive(s->plug, 2, buf, ret);
	}*/
	break;
      case FD_WRITE:
	{
	    int bufsize_before, bufsize_after;
		MessageBox(0, "FD_WRITE", "FD_WRITE", MB_OK);
	    s->writable = 1;
	    bufsize_before = s->sending_oob + bufchain_size(&s->output_data);
	    try_send(s);
	    bufsize_after = s->sending_oob + bufchain_size(&s->output_data);
	    if (bufsize_after < bufsize_before)
		plug_sent(s->plug, bufsize_after);
	}
	break;
 //     case FD_CLOSE:
	/* Signal a close on the socket. First read any outstanding data. */
/*	open = 1;
	do {
	    ret = recv(s->s, buf, sizeof(buf), 0);
	    if (ret < 0) {
		err = WSAGetLastError();
		if (err == WSAEWOULDBLOCK)
		    break;
		return plug_closing(s->plug, winsock_error_string(err),
				    err, 0);
	    } else {
		if (ret)
		    open &= plug_receive(s->plug, 0, buf, ret);
		else
		    open &= plug_closing(s->plug, NULL, 0, 0);
	    }
	} while (ret > 0);
	return open;
       case FD_ACCEPT:
	{
	    struct sockaddr_in isa;
	    int addrlen = sizeof(struct sockaddr_in);
	    SOCKET t;  /* socket of connection */

/*	    memset(&isa, 0, sizeof(struct sockaddr_in));
	    err = 0;
	    t = accept(s->s,(struct sockaddr *)&isa,&addrlen);
	    if (t == INVALID_SOCKET)
	    {
		err = WSAGetLastError();
		if (err == WSATRY_AGAIN)
		    break;
	    }

	    if (s->localhost_only &&
		ntohl(isa.sin_addr.s_addr) != INADDR_LOOPBACK) {
		closesocket(t);	       /* dodgy WinSock let nonlocal through */
/*	    } else if (plug_accepting(s->plug, (void*)t)) {
		closesocket(t);	       /* denied or error */
	  //  }
	}
    //}

    return 1;
}

/*
 * Deal with socket errors detected in try_send().
 */
void net_pending_errors(void)
{
    int i;
    Actual_Socket s;

    /*
     * This might be a fiddly business, because it's just possible
     * that handling a pending error on one socket might cause
     * others to be closed. (I can't think of any reason this might
     * happen in current SSH implementation, but to maintain
     * generality of this network layer I'll assume the worst.)
     * 
     * So what we'll do is search the socket list for _one_ socket
     * with a pending error, and then handle it, and then search
     * the list again _from the beginning_. Repeat until we make a
     * pass with no socket errors present. That way we are
     * protected against the socket list changing under our feet.
     */

    do {
	for (i = 0; (s = index234(sktree, i)) != NULL; i++) {
	    if (s->pending_error) {
		/*
		 * An error has occurred on this socket. Pass it to the
		 * plug.
		 */
		plug_closing(s->plug,
			     winsock_error_string(s->pending_error),
			     s->pending_error, 0);
		break;
	    }
	}
    } while (s);
}

/*
 * Each socket abstraction contains a `void *' private field in
 * which the client can keep state.
 */
static void sk_tcp_set_private_ptr(Socket sock, void *ptr)
{
    Actual_Socket s = (Actual_Socket) sock;
    s->private_ptr = ptr;
}

static void *sk_tcp_get_private_ptr(Socket sock)
{
    Actual_Socket s = (Actual_Socket) sock;
    return s->private_ptr;
}

/*
 * Special error values are returned from sk_namelookup and sk_new
 * if there's a problem. These functions extract an error message,
 * or return NULL if there's no problem.
 */
const char *sk_addr_error(SockAddr addr)
{
    return addr->error;
}
static char *sk_tcp_socket_error(Socket sock)
{
    Actual_Socket s = (Actual_Socket) sock;
    return s->error;
}

static void sk_tcp_set_frozen(Socket sock, int is_frozen)
{
    Actual_Socket s = (Actual_Socket) sock;
    if (s->frozen == is_frozen)
	return;
    s->frozen = is_frozen;
    if (!is_frozen && s->frozen_readable) {
	//char c;
	//recv(s->s, &c, 1, MSG_PEEK);
    }
    s->frozen_readable = 0;
}

/*
 * For Plink: enumerate all sockets currently active.
 */
SOCKET first_socket(int *state)
{
    Actual_Socket s;
    *state = 0;
    s = index234(sktree, (*state)++);
    return s ? s->s : INVALID_SOCKET;
}

SOCKET next_socket(int *state)
{
    Actual_Socket s = index234(sktree, (*state)++);
    return s ? s->s : INVALID_SOCKET;
}

Socket new_connection(SockAddr addr, char *hostname,
		      int port, int privport,
		      int oobinline, int nodelay, Plug plug, const Config *cfg)
{
	/* no proxy, so just return the direct socket */
	return sk_new(addr, port, privport, oobinline, nodelay, plug);
}

/* Not used in FileZilla
int net_service_lookup(char *service)
{
    struct servent *se;
    se = getservbyname(service, NULL);
    if (se != NULL)
	return ntohs(se->s_port);
    else
	return 0;
}
*/

⌨️ 快捷键说明

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