fixed: broken fs0, sram saves
[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 <string.h>
27 #include <unistd.h>
28 #include <netdb.h>
29 #include <errno.h>
30
31 #ifndef socklen_t
32 #define socklen_t int
33 #endif
34
35 static int Socket=-1;
36 #include "main.h"
37 #include "unix-netplay.h"
38
39 char *netplayhost=0;
40 int Port=0xFCE;
41 int netplay=0;
42
43 int FCEUD_NetworkConnect(void)
44 {
45  struct sockaddr_in sockn;
46  int TSocket;
47
48  memset(&sockn,0,sizeof(sockn));
49  sockn.sin_family=AF_INET;
50  sockn.sin_port=htons(Port);
51
52  if((TSocket=socket(AF_INET, SOCK_STREAM, 0))<0)
53  {
54   puts("Error creating socket.");
55   return(0);
56  }
57
58  if(netplay==1)         /* Be a server. */
59  {
60   sockn.sin_addr.s_addr=INADDR_ANY;
61   if(bind(TSocket, (struct sockaddr *)&sockn, sizeof(sockn))<0)
62   {
63    close(TSocket);
64    puts("Error binding to socket.");
65    return(0);
66   }
67   if(listen(TSocket, 1)<0)
68   {
69    puts("Error listening on socket.");
70    close(TSocket);
71    return(0);
72   }
73   {
74    socklen_t len=sizeof(sockn);
75
76    printf("Accepting connection on port %d...\n",Port);
77    if((Socket=accept(TSocket,(struct sockaddr *)&sockn,&len))<0 )
78    {
79     puts("Error accepting a connection.");
80     close(TSocket);
81     return(0);
82    }
83    close(TSocket);
84   }
85
86  }
87  else /* Connect as a client if not a server. */
88  {
89   struct hostent *Host;
90
91   if((sockn.sin_addr.s_addr=inet_addr(netplayhost))==INADDR_NONE)
92   {
93    if(!(Host=gethostbyname(netplayhost)))
94    {
95     puts("Error getting network host entry.");
96     return(0);
97    }
98    memcpy(&sockn.sin_addr,Host->h_addr,Host->h_length);
99   }
100   printf("Attempting to connect to %s...\n",netplayhost);
101   if( connect(TSocket, (struct sockaddr *)&sockn, sizeof(sockn)) <0 )
102   {
103    puts("Error connecting to remote host.");
104    close(TSocket);
105    return(0);
106   }
107   Socket=TSocket;
108  }
109  return(1);
110 }
111
112 /* 0 on failure, 1 on success, -1 if it would block and blocking is not
113    specified.
114 */
115
116 int FCEUD_NetworkRecvData(uint8 *data, uint32 len, int block)
117 {
118   if(block)
119   {
120    int t;
121    uint8 temp[32];
122    t=recv(Socket,temp,32,MSG_PEEK|MSG_DONTWAIT);
123    if(t==-1)
124    {
125     if(errno!=EAGAIN) return(0);
126    }
127    else if(t==32)
128     NoWaiting|=2;
129    else
130     NoWaiting&=~2;
131    return(recv(Socket,data,len,0)==len);
132   }
133   else
134   {
135    int t=recv(Socket,data,len,MSG_DONTWAIT);
136    if(t==-1)
137    {
138     if(errno==EAGAIN)   // Would block
139      return(-1);
140     return(0);
141    }
142    return(1);
143   }
144 }
145
146 /* 0 on failure, 1 on success.  This function should always block. */
147
148 int FCEUD_NetworkSendData(uint8 *Value, uint32 len)
149 {
150  return(send(Socket,Value,len,0)==len);
151 }
152
153 void FCEUD_NetworkClose(void)
154 {
155  if(Socket>0)
156   close(Socket);
157  Socket=-1;
158 }
159