📄 tcp_wsk.c
字号:
tmo.tv_usec = 0; while (stream->ictr < 1) { /* if nothing in the buffer */ time_t tl = time (0); if (tcpdebug) mm_log ("Reading TCP data",TCPDEBUG); FD_SET (stream->tcpsi,&fds);/* set bit in selection vector */ /* block and read */ switch ((stream->tcpsi == stream->tcpso) ? select (stream->tcpsi+1,&fds,0,0, ttmo_read ? &tmo : (struct timeval *) 0) : 1) { case SOCKET_ERROR: /* error */ if (WSAGetLastError () != WSAEINTR) return tcp_abort (stream); break; case 0: /* timeout */ tc = time (0); if (tmoh && ((*tmoh) (tc - t,tc - tl))) break; return tcp_abort (stream); default: if (stream->tcpsi == stream->tcpso) while (((i = recv (stream->tcpsi,stream->ibuf,BUFLEN,0)) == SOCKET_ERROR) && (WSAGetLastError () == WSAEINTR)); else while (((i = read (stream->tcpsi,stream->ibuf,BUFLEN)) < 0) && (errno == EINTR)); switch (i) { case SOCKET_ERROR: /* error */ case 0: /* no data read */ return tcp_abort (stream); default: stream->ictr = i; /* set new byte count */ /* point at TCP buffer */ stream->iptr = stream->ibuf; if (tcpdebug) mm_log ("Successfully read TCP data",TCPDEBUG); } } } (*bn) (BLOCK_NONE,NIL); return T;}/* TCP/IP send string as record * Accepts: TCP/IP stream * string pointer * Returns: T if success else NIL */long tcp_soutr (TCPSTREAM *stream,char *string){ return tcp_sout (stream,string,(unsigned long) strlen (string));}/* TCP/IP send string * Accepts: TCP/IP stream * string pointer * byte count * Returns: T if success else NIL */long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size){ int i; struct timeval tmo; fd_set fds; time_t tc,t = time (0); blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL); tmo.tv_sec = ttmo_write; tmo.tv_usec = 0; FD_ZERO (&fds); /* initialize selection vector */ if (stream->tcpso == INVALID_SOCKET) return NIL; (*bn) (BLOCK_TCPWRITE,NIL); while (size > 0) { /* until request satisfied */ time_t tl = time (0); if (tcpdebug) mm_log ("Writing to TCP",TCPDEBUG); FD_SET (stream->tcpso,&fds);/* set bit in selection vector */ /* block and write */ switch ((stream->tcpsi == stream->tcpso) ? select (stream->tcpso+1,NULL,&fds,NULL, tmo.tv_sec ? &tmo : (struct timeval *) 0) : 1) { case SOCKET_ERROR: /* error */ if (WSAGetLastError () != WSAEINTR) return tcp_abort (stream); break; case 0: /* timeout */ tc = time (0); if (tmoh && ((*tmoh) (tc - t,tc - tl))) break; return tcp_abort (stream); default: if (stream->tcpsi == stream->tcpso) while (((i = send (stream->tcpso,string, (int) min (size,TCPMAXSEND),0)) == SOCKET_ERROR) && (WSAGetLastError () == WSAEINTR)); else while (((i = write (stream->tcpso,string, min (size,TCPMAXSEND))) < 0) && (errno == EINTR)); if (i == SOCKET_ERROR) return tcp_abort (stream); size -= i; /* count this size */ if (tcpdebug) mm_log ("successfully wrote to TCP",TCPDEBUG); string += i; } } (*bn) (BLOCK_NONE,NIL); return T; /* all done */}/* TCP/IP close * Accepts: TCP/IP stream */void tcp_close (TCPSTREAM *stream){ tcp_abort (stream); /* nuke the sockets */ /* flush host names */ if (stream->host) fs_give ((void **) &stream->host); if (stream->remotehost) fs_give ((void **) &stream->remotehost); if (stream->localhost) fs_give ((void **) &stream->localhost); fs_give ((void **) &stream); /* flush the stream */}/* TCP/IP abort sockets * Accepts: TCP/IP stream * Returns: NIL, always */long tcp_abort (TCPSTREAM *stream){ if (stream->tcpsi != stream->tcpso) tcp_close_socket (&stream->tcpso); else stream->tcpso = INVALID_SOCKET; return tcp_close_socket (&stream->tcpsi);}/* TCP/IP abort stream * Accepts: WinSock socket * Returns: NIL, always */long tcp_close_socket (SOCKET *sock){ blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL); /* something to close? */ if (sock && (*sock != INVALID_SOCKET)) { (*bn) (BLOCK_TCPCLOSE,NIL); closesocket (*sock); /* WinSock socket close */ *sock = INVALID_SOCKET; (*bn) (BLOCK_NONE,NIL); wsa_sock_open--; /* drop this socket */ } /* no more open streams? */ if (wsa_initted && !wsa_sock_open) { mm_log ("Winsock cleanup",NIL); wsa_initted = 0; /* no more sockets, so... */ WSACleanup (); /* free up resources until needed */ } return NIL;}/* TCP/IP get host name * Accepts: TCP/IP stream * Returns: host name for this stream */char *tcp_host (TCPSTREAM *stream){ return stream->host; /* use tcp_remotehost() if want guarantees */}/* TCP/IP get remote host name * Accepts: TCP/IP stream * Returns: host name for this stream */char *tcp_remotehost (TCPSTREAM *stream){ if (!stream->remotehost) { struct sockaddr_in sin; int sinlen = sizeof (struct sockaddr_in); stream->remotehost = /* get socket's peer name */ ((getpeername (stream->tcpsi,(struct sockaddr *) &sin,&sinlen) == SOCKET_ERROR) || (sinlen <= 0)) ? cpystr (stream->host) : tcp_name (&sin,NIL); } return stream->remotehost;}/* TCP/IP return port for this stream * Accepts: TCP/IP stream * Returns: port number for this stream */unsigned long tcp_port (TCPSTREAM *stream){ return stream->port; /* return port number */}/* TCP/IP get local host name * Accepts: TCP/IP stream * Returns: local host name */char *tcp_localhost (TCPSTREAM *stream){ if (!stream->localhost) { struct sockaddr_in sin; int sinlen = sizeof (struct sockaddr_in); stream->localhost = /* get socket's name */ ((stream->port & 0xffff000) || ((getsockname (stream->tcpsi,(struct sockaddr *) &sin,&sinlen) == SOCKET_ERROR) || (sinlen <= 0))) ? cpystr (mylocalhost ()) : tcp_name (&sin,NIL); } return stream->localhost; /* return local host name */}/* TCP/IP get client host address (server calls only) * Returns: client host address */char *tcp_clientaddr (){ if (!myClientAddr) { struct sockaddr_in sin; int sinlen = sizeof (struct sockaddr_in); myClientAddr = /* get stdin's peer name */ ((getpeername (0,(struct sockaddr *) &sin,&sinlen) == SOCKET_ERROR) || (sinlen <= 0)) ? cpystr ("UNKNOWN") : cpystr (inet_ntoa (sin.sin_addr)); } return myClientAddr;}/* TCP/IP get client host name (server calls only) * Returns: client host name */char *tcp_clienthost (){ if (!myClientHost) { struct sockaddr_in sin; int sinlen = sizeof (struct sockaddr_in); myClientHost = /* get stdin's peer name */ ((getpeername (0,(struct sockaddr *) &sin,&sinlen) == SOCKET_ERROR) || (sinlen <= 0)) ? cpystr ("UNKNOWN") : tcp_name (&sin,T); } return myClientHost;}/* TCP/IP get server host address (server calls only) * Returns: server host address */char *tcp_serveraddr (){ if (!myServerAddr) { struct sockaddr_in sin; int sinlen = sizeof (struct sockaddr_in); myServerAddr = /* get stdin's peer name */ ((getsockname (0,(struct sockaddr *) &sin,&sinlen) == SOCKET_ERROR) || (sinlen <= 0)) ? cpystr ("UNKNOWN") : cpystr (inet_ntoa (sin.sin_addr)); } return myServerAddr;}/* TCP/IP get server host name (server calls only) * Returns: server host name */static long myServerPort = -1;char *tcp_serverhost (){ if (!myServerHost) { struct sockaddr_in sin; int sinlen = sizeof (struct sockaddr_in); if (!wsa_initted++) { /* init Windows Sockets */ WSADATA wsock; if (WSAStartup (WSA_VERSION,&wsock)) { wsa_initted = 0; return "random-pc"; /* try again later? */ } } /* get stdin's name */ if ((getsockname (0,(struct sockaddr *) &sin,&sinlen) == SOCKET_ERROR) || (sinlen <= 0)) myServerHost = cpystr (mylocalhost ()); else { myServerHost = tcp_name (&sin,NIL); myServerPort = ntohs (sin.sin_port); } } return myServerHost;}/* TCP/IP get server port number (server calls only) * Returns: server port number */long tcp_serverport (){ if (!myServerHost) tcp_serverhost (); return myServerPort;}/* TCP/IP return canonical form of host name * Accepts: host name * Returns: canonical form of host name */char *tcp_canonical (char *name){ char *ret,host[MAILTMPLEN]; struct hostent *he; blocknotify_t bn = (blocknotify_t) mail_parameters (NIL,GET_BLOCKNOTIFY,NIL); /* look like domain literal? */ if (name[0] == '[' && name[strlen (name) - 1] == ']') return name; (*bn) (BLOCK_DNSLOOKUP,NIL); if (tcpdebug) { sprintf (host,"DNS canonicalization %.80s",name); mm_log (host,TCPDEBUG); } /* note that NT requires lowercase! */ ret = (he = gethostbyname (lcase (strcpy (host,name)))) ? he->h_name : name; (*bn) (BLOCK_NONE,NIL); if (tcpdebug) mm_log ("DNS canonicalization done",TCPDEBUG); return ret;}/* TCP/IP return name from socket * Accepts: socket * verbose flag * Returns: cpystr name */char *tcp_name (struct sockaddr_in *sin,long flag){ char *ret,*t,adr[MAILTMPLEN],tmp[MAILTMPLEN]; sprintf (ret = adr,"[%.80s]",inet_ntoa (sin->sin_addr)); if (allowreversedns) { struct hostent *he; blocknotify_t bn = (blocknotify_t)mail_parameters(NIL,GET_BLOCKNOTIFY,NIL); void *data; if (tcpdebug) { sprintf (tmp,"Reverse DNS resolution %s",adr); mm_log (tmp,TCPDEBUG); } (*bn) (BLOCK_DNSLOOKUP,NIL);/* quell alarms */ data = (*bn) (BLOCK_SENSITIVE,NIL); /* translate address to name */ if (t = tcp_name_valid ((he = gethostbyaddr ((char *) &sin->sin_addr, sizeof (struct in_addr), sin->sin_family)) ? (char *) he->h_name : NIL)) { /* produce verbose form if needed */ if (flag) sprintf (ret = tmp,"%s %s",t,adr); else ret = t; } (*bn) (BLOCK_NONSENSITIVE,data); (*bn) (BLOCK_NONE,NIL); /* alarms OK now */ if (tcpdebug) mm_log ("Reverse DNS resolution done",TCPDEBUG); } return cpystr (ret);}/* Return my local host name * Returns: my local host name */char *mylocalhost (void){ if (!myLocalHost) { char tmp[MAILTMPLEN]; if (!wsa_initted++) { /* init Windows Sockets */ WSADATA wsock; if (WSAStartup (WSA_VERSION,&wsock)) { wsa_initted = 0; return "random-pc"; /* try again later? */ } } myLocalHost = cpystr ((gethostname (tmp,MAILTMPLEN-1) == SOCKET_ERROR) ? "random-pc" : tcp_canonical (tmp)); } return myLocalHost;}/* Validate name * Accepts: domain name * Returns: T if valid, NIL otherwise */char *tcp_name_valid (char *s){ int c; char *ret,*tail; /* must be non-empty and not too long */ if ((ret = (s && *s) ? s : NIL) && (tail = ret + NETMAXHOST)) { /* must be alnum, dot, or hyphen */ while ((c = *s++) && (s <= tail) && (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')) || (c == '-') || (c == '.'))); if (c) ret = NIL; } return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -