63bd5be0 |
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 | |