2 * Netris -- A free networked version of T*tris
3 * Copyright (C) 1994,1995,1996 Mark H. Weaver <mhw@netris.org>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 * $Id: inet.c,v 1.18 1996/02/09 08:22:13 mhw Exp $
23 #include <sys/types.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
32 #define HEADER_SIZE sizeof(netint2[2])
33 #define HEADER_SIZE3 sizeof(netint4[3])
35 static MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event);
38 static EventGenRec netGen = { NULL, 0, FT_read, -1, NetGenFunc, EM_net };
40 static char netBuf[64];
41 static int netBufSize, netBufGoal = HEADER_SIZE3;
42 static int isServer, lostConn, gotEndConn;
44 ExtFunc void InitNet(void)
49 ExtFunc int WaitForConnection(char *portStr)
51 struct sockaddr_in addr;
60 port = atoi(portStr); /* XXX Error checking */
63 memset(&addr, 0, sizeof(addr));
64 addr.sin_family = AF_INET;
65 addr.sin_addr.s_addr = htonl(INADDR_ANY);
66 addr.sin_port = htons(port);
67 sockListen = socket(AF_INET, SOCK_STREAM, 0);
71 setsockopt(sockListen, SOL_SOCKET, SO_REUSEADDR,
72 (void *)&val1, sizeof(val1));
73 if (bind(sockListen, (struct sockaddr *)&addr, sizeof(addr)) < 0)
75 if (listen(sockListen, 1) < 0)
79 addrLen = sizeof(addr);
80 if ((sock = accept(sockListen, (struct sockaddr *)&addr, &addrLen)) < 0)
82 fprintf(stderr, "Connection: %s\n", inet_ntoa(addr.sin_addr));
87 setsockopt(sock, SOL_SOCKET, SO_LINGER,
88 (void *)&val2, sizeof(val2));
90 strcpy(opponentHost, "???");
91 if (addr.sin_family == AF_INET) {
92 host = gethostbyaddr((void *)&addr.sin_addr,
93 sizeof(struct in_addr), AF_INET);
95 strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1);
96 opponentHost[sizeof(opponentHost)-1] = 0;
109 ExtFunc int InitiateConnection(char *hostStr, char *portStr)
111 struct sockaddr_in addr;
112 struct hostent *host;
117 port = atoi(portStr); /* XXX Error checking */
120 host = gethostbyname(hostStr);
122 die("gethostbyname");
123 assert(host->h_addrtype == AF_INET);
124 strncpy(opponentHost, host->h_name, sizeof(opponentHost)-1);
125 opponentHost[sizeof(opponentHost)-1] = 0;
127 memset(&addr, 0, sizeof(addr));
128 addr.sin_family = host->h_addrtype;
129 memcpy(&addr.sin_addr, host->h_addr, host->h_length);
130 addr.sin_port = htons(port);
131 mySock = socket(AF_INET, SOCK_STREAM, 0);
134 if (connect(mySock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
135 if (errno != ECONNREFUSED)
141 netGen.fd = sock = mySock;
142 AddEventGen(&netGen);
146 static MyEventType NetGenFunc(EventGenRec *gen, MyEvent *event)
149 short uid, type, size;
152 result = MyRead(sock, netBuf + netBufSize, netBufGoal - netBufSize);
157 netBufSize += result;
158 if (netBufSize < netBufGoal)
160 memcpy(data, netBuf, sizeof(data));
161 uid = ntoh4(data[0]);
162 type = ntoh4(data[1]);
163 size = ntoh4(data[2]);
165 if (netBufSize < netBufGoal)
168 netBufGoal = HEADER_SIZE3;
169 event->u.net.type = type;
170 event->u.net.size = size - HEADER_SIZE3;
171 event->u.net.data = netBuf + HEADER_SIZE3;
172 if (type == NP_endConn) {
176 else if (type == NP_byeBye) {
183 ExtFunc void CheckNetConn(void)
187 ExtFunc void SendPacket(short uid, NetPacketType type, int size, void *data)
191 header[0] = hton4(uid);
192 header[1] = hton4(type);
193 header[2] = hton4(size + HEADER_SIZE3);
194 if (MyWrite(sock, header, HEADER_SIZE3) != HEADER_SIZE3)
196 if (size > 0 && data && MyWrite(sock, data, size) != size)
200 ExtFunc void CloseNet(void)
206 SendPacket(0, NP_endConn, 0, NULL);
209 WaitMyEvent(&event, EM_net);
213 WaitMyEvent(&event, EM_net);
214 SendPacket(0, NP_byeBye, 0, NULL);
221 RemoveEventGen(&netGen);