00001 #include "tcp.h"
00002 
00003 #ifndef WINSOCK
00004 #       include <netdb.h>
00005 #       include <netinet/in.h>
00006 #       include <fcntl.h>
00007 #else
00008 static int initialized = 0;
00009 static WSADATA wsaData;
00010 
00011 
00012 
00013 
00014 static inline int initialize() {
00015         if(!initialized) {
00016                 if(WSAStartup(MAKEWORD(1, 1), &wsaData)) {
00017                         return TCP_ERROR;
00018                 }
00019         }
00020         return 0;
00021 }
00022 #endif 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 static int set_sockaddr(struct sockaddr_in *addr,
00035         const char *host, int port) {
00036         struct hostent *he;
00037 
00038         if(host) {
00039                 
00040                 he = gethostbyname(host);
00041                 if(!he) {
00042                         return TCP_ERROR;
00043                 }
00044 
00045                 
00046                 memcpy(&addr->sin_addr, he->h_addr, he->h_length);
00047         } else {
00048                 
00049                 addr->sin_addr.s_addr = INADDR_ANY;
00050         }
00051 
00052         
00053         addr->sin_family = AF_INET;
00054         addr->sin_port = htons((short) port);
00055         
00056         return 0;
00057 }
00058 
00059 
00060 
00061 
00062 static TCP_SOCKET make_socket() {
00063         TCP_SOCKET sock;
00064 
00065         
00066         sock = socket(AF_INET, SOCK_STREAM, 0);
00067 #       ifdef WINSOCK
00068         if(sock == INVALID_SOCKET) return TCP_ERROR;
00069 #       else
00070         if(sock < 0) return TCP_ERROR;
00071 #       endif
00072         
00073         return sock;
00074 }
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 TCP_CONNECTION tcp_connect(const char *host, int port) {
00083         struct sockaddr_in addr;
00084         int sock;
00085 
00086 #       ifdef WINSOCK
00087         
00088         if(initialize() == TCP_ERROR) return TCP_ERROR;
00089 #       endif
00090 
00091         
00092         if(set_sockaddr(&addr, host, port) == TCP_ERROR) return TCP_ERROR;
00093 
00094         
00095         sock = make_socket();
00096         if(sock == TCP_ERROR) return TCP_ERROR;
00097 
00098         
00099 #       ifdef WINSOCK
00100         if(connect(sock, (struct sockaddr*) &addr, sizeof(addr)) ==
00101                 SOCKET_ERROR) {
00102 #       else
00103         if(connect(sock, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
00104 #       endif 
00105                 tcp_close(sock);
00106                 return TCP_ERROR;
00107         }
00108 
00109         return sock;
00110 }
00111 
00112 
00113 
00114 
00115 
00116 int tcp_close(TCP_CONNECTION conn) {
00117 #       ifdef WINSOCK
00118         return closesocket(conn);
00119 #       else
00120         return close(conn);
00121 #endif
00122 }
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 
00132 
00133 
00134 
00135 
00136 
00137 int tcp_read(TCP_CONNECTION conn, void *buf, int len) {
00138         return tcp_recv(conn, buf, len, 0);
00139 }
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 
00149 
00150 
00151 
00152 
00153 int tcp_write(TCP_CONNECTION conn, const void *buf, int len) {
00154         return tcp_send(conn, buf, len, 0);
00155 }
00156 
00157 
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 
00166 
00167 
00168 
00169 
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 int tcp_setblocking(TCP_CONNECTION conn, int blocking) {
00178 #       ifdef WINSOCK
00179         u_long arg = !blocking;
00180 
00181         return ioctlsocket(conn, FIONBIO, &arg);
00182 #       else
00183         int flags;
00184 
00185         flags = fcntl(conn, F_GETFL, 0);
00186         if(flags < 0) return TCP_ERROR;
00187         return fcntl(conn, F_SETFL, blocking ?
00188                 flags | O_NONBLOCK :
00189                 flags & ~(O_NONBLOCK));
00190 #       endif   
00191 }
00192 
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 TCP_SOCKET tcp_listen(const char *host, int port) {
00201         struct hostent *he;
00202         struct sockaddr_in addr;
00203         int sock;
00204 
00205 #       ifdef WINSOCK
00206         
00207         if(initialize() == TCP_ERROR) return TCP_ERROR;
00208 #       endif
00209 
00210         
00211         if(set_sockaddr(&addr, host, port) == TCP_ERROR) return TCP_ERROR;
00212 
00213         
00214         sock = make_socket();
00215         if(sock == TCP_ERROR) return TCP_ERROR;
00216 
00217         
00218 #       ifdef WINSOCK
00219         if(bind(sock, (struct sockaddr*) &addr, sizeof(addr)) ==
00220                 SOCKET_ERROR || listen(sock, 3) == SOCKET_ERROR) {
00221 #       else
00222         if(bind(sock, (struct sockaddr*) &addr, sizeof(addr)) < 0 ||
00223                 listen(sock, 3) < 0) {
00224 #       endif 
00225                 tcp_close(sock);
00226                 return TCP_ERROR;
00227         }
00228 
00229         return sock;
00230 }
00231 
00232 
00233 
00234 
00235 
00236 TCP_CONNECTION tcp_accept(TCP_SOCKET sock) {
00237 #       ifdef WINSOCK
00238         return accept(sock, 0, 0);
00239 #       else
00240         int conn;
00241 
00242         conn = accept(sock, 0, 0);
00243         return conn < 0 ? TCP_ERROR : conn;
00244 #       endif 
00245 }