d5d1cc4f9ee5b3a19f68ec6bfb4c968f0d85c9cc
[fceu.git] / drivers / cli / unix-netplay.c
1 /* FCE Ultra - NES/Famicom Emulator
2  *
3  * Copyright notice for this file:
4  *  Copyright (C) 2002 Ben Parnell
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <arpa/inet.h>
25 #include <stdio.h>
26 #include <unistd.h>
27 #include <netdb.h>
28 #include <errno.h>
29
30 #ifndef socklen_t
31 #define socklen_t int
32 #endif
33
34 static int Socket=-1;
35 #include "main.h"
36 #include "unix-netplay.h"
37
38 char *netplayhost=0;
39 int Port=0xFCE;
40 int netplay=0;
41
42 int FCEUD_NetworkConnect(void)
43 {
44  struct sockaddr_in sockn;
45  int TSocket;
46
47  memset(&sockn,0,sizeof(sockn));
48  sockn.sin_family=AF_INET;
49  sockn.sin_port=htons(Port);
50
51  if((TSocket=socket(AF_INET, SOCK_STREAM, 0))<0)
52  {
53   puts("Error creating socket.");
54   return(0);
55  }
56
57  if(netplay==1)         /* Be a server. */
58  {
59   sockn.sin_addr.s_addr=INADDR_ANY;
60   if(bind(TSocket, (struct sockaddr *)&sockn, sizeof(sockn))<0)
61   {
62    close(TSocket);
63    puts("Error binding to socket."); 
64    return(0);
65   }
66   if(listen(TSocket, 1)<0)
67   {
68    puts("Error listening on socket.");
69    close(TSocket);
70    return(0);
71   }
72   {
73    socklen_t len=sizeof(sockn);
74      
75    printf("Accepting connection on port %d...\n",Port);
76    if((Socket=accept(TSocket,(struct sockaddr *)&sockn,&len))<0 )
77    {
78     puts("Error accepting a connection.");
79     close(TSocket);
80     return(0);
81    }
82    close(TSocket);
83   }
84
85  }
86  else /* Connect as a client if not a server. */
87  {
88   struct hostent *Host;
89
90   if((sockn.sin_addr.s_addr=inet_addr(netplayhost))==INADDR_NONE)
91   {
92    if(!(Host=gethostbyname(netplayhost)))
93    {
94     puts("Error getting network host entry.");
95     return(0);
96    }
97    memcpy(&sockn.sin_addr,Host->h_addr,Host->h_length);
98   }  
99   printf("Attempting to connect to %s...\n",netplayhost);
100   if( connect(TSocket, (struct sockaddr *)&sockn, sizeof(sockn)) <0 )
101   {
102    puts("Error connecting to remote host.");
103    close(TSocket);
104    return(0);
105   }
106   Socket=TSocket;
107  }
108  return(1);  
109 }
110
111 /* 0 on failure, 1 on success, -1 if it would block and blocking is not
112    specified.
113 */
114
115 int FCEUD_NetworkRecvData(uint8 *data, uint32 len, int block)
116 {
117   if(block)
118   {
119    int t;
120    uint8 temp[32];
121    t=recv(Socket,temp,32,MSG_PEEK|MSG_DONTWAIT);
122    if(t==-1)
123    {
124     if(errno!=EAGAIN) return(0);
125    }
126    else if(t==32)
127     NoWaiting|=2;
128    else
129     NoWaiting&=~2;
130    return(recv(Socket,data,len,0)==len);
131   }
132   else
133   {
134    int t=recv(Socket,data,len,MSG_DONTWAIT);
135    if(t==-1)
136    {
137     if(errno==EAGAIN)   // Would block
138      return(-1);
139     return(0);
140    }
141    return(1);
142   }
143 }
144
145 /* 0 on failure, 1 on success.  This function should always block. */
146
147 int FCEUD_NetworkSendData(uint8 *Value, uint32 len)
148 {
149  return(send(Socket,Value,len,0)==len);
150 }
151
152 void FCEUD_NetworkClose(void)
153 {
154  if(Socket>0)
155   close(Socket);
156  Socket=-1;
157 }
158