OSDN Git Service

For clarity, reworded English prompt for selecting the cards to keep in poker.
[hengband/hengband.git] / src / io / inet.c
1 /*
2  * @brief ネットワーク機能処理
3  * @date 2002/01/12
4  * @author mogami
5  */
6
7 #include "io/inet.h"
8 #include "io/files-util.h"
9 #include "util/angband-files.h"
10
11 #ifdef WORLD_SCORE
12 #ifdef WINDOWS
13 #include <winsock.h>
14 #else
15 #include <netdb.h>
16 #include <netinet/in.h>
17 #include <sys/socket.h>
18 #include <sys/time.h>
19 #include <sys/types.h>
20
21 #include <setjmp.h>
22 #include <signal.h>
23 #endif
24
25 #include <stdlib.h>
26
27 static concptr errstr;
28 static char *proxy;
29 static int proxy_port;
30
31 /* プロキシサーバのアドレスををファイルから読んで設定する */
32 void set_proxy(char *default_url, int default_port)
33 {
34     char buf[1024];
35     size_t len;
36     FILE *fp;
37     char *s;
38
39     path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, "proxy.prf");
40
41     /* ファイルから設定を読む。 */
42     fp = angband_fopen(buf, "r");
43
44     if (!fp) {
45         /* ファイルが存在しない場合はデフォルトを設定 */
46         proxy = default_url;
47         proxy_port = default_port;
48         return;
49     }
50
51     while (angband_fgets(fp, buf, sizeof(buf)) == 0) {
52         if (buf[0] != '#' && buf[0] != '\0')
53             break;
54     }
55
56     angband_fclose(fp);
57
58     /* ポインタを用意。 */
59     s = buf;
60
61     /* "http://" から始まっている場合はその部分をカットする。 */
62 #if defined(WINDOWS)
63     if (!strnicmp(s, "http://", 7)) {
64         s += 7;
65     }
66 #else
67     if (!strncasecmp(s, "http://", 7)) {
68         s += 7;
69     }
70 #endif
71
72     /* 文字列の長さを調べ、必要なメモリを確保 */
73     len = strlen(s);
74     proxy = malloc(len + 1);
75
76     /* ポート番号があるかどうかを調べ、あればproxy_portに設定。 */
77     --len;
78     while (len > 0 && isdigit((unsigned char)s[len]))
79         --len;
80     if (len > 0 && s[len] == ':' && s[len + 1] != '\0') {
81         s[len] = '\0';
82         strcpy(proxy, s);
83         proxy_port = atoi(s + (len + 1));
84     } else {
85         strcpy(proxy, s);
86         proxy_port = default_port;
87     }
88
89     /* プロキシのアドレスをproxyにコピー */
90     strcpy(proxy, s);
91
92     if (proxy_port == 0)
93         proxy_port = 80;
94 }
95
96 /* ソケットにバッファの内容を書き込む */
97 int soc_write(int sd, char *buf, size_t sz)
98 {
99     int nleft, nwritten;
100
101     nleft = sz;
102
103     while (nleft > 0) {
104         nwritten = send(sd, buf, nleft, 0);
105         if (nwritten <= 0)
106             return (nwritten);
107         nleft -= nwritten;
108         buf += nwritten;
109     }
110
111     return sz;
112 }
113
114 int soc_read(int sd, char *buf, size_t sz)
115 {
116     int nleft, nread = 0;
117
118     nleft = sz;
119
120     while (nleft > 0) {
121         int n;
122         n = recv(sd, buf + nread, nleft, 0);
123         if (n <= 0)
124             return (nread);
125         nleft -= n;
126         nread += n;
127     }
128
129     return nread;
130 }
131
132 #if !defined(WINDOWS)
133 static sigjmp_buf env;
134 static void (*sig_int_saved)(int);
135 static void (*sig_alm_saved)(int);
136 #endif
137
138 static void restore_signal(void)
139 {
140 #if !defined(WINDOWS)
141     struct itimerval val0;
142
143     /* itimerリセット用 */
144     val0.it_interval.tv_sec = 0;
145     val0.it_interval.tv_usec = 0;
146     val0.it_value.tv_sec = 0;
147     val0.it_value.tv_usec = 0;
148
149     /* アラーム解除 */
150     setitimer(ITIMER_REAL, &val0, NULL);
151     signal(SIGALRM, sig_alm_saved);
152     signal(SIGINT, sig_int_saved);
153 #endif
154 }
155
156 #if !defined(WINDOWS)
157 static void interrupt_report(int sig)
158 {
159     restore_signal();
160     siglongjmp(env, sig);
161 }
162 #endif
163
164 /* サーバにコネクトする関数。 */
165 int connect_server(int timeout, concptr host, int port)
166 {
167     int sd;
168     struct sockaddr_in to;
169     struct hostent *hp;
170
171 #ifndef WINDOWS
172     struct itimerval val;
173     int ret;
174
175     /* itimer設定用 */
176     val.it_interval.tv_sec = 0;
177     val.it_interval.tv_usec = 0;
178     val.it_value.tv_sec = timeout;
179     val.it_value.tv_usec = 0;
180
181     /* タイムアウト、もしくは中断した時の処理。 */
182     if ((ret = sigsetjmp(env, 1)) != 0) {
183 #ifdef JP
184         if (ret == SIGALRM)
185             errstr = "エラー: タイムアウト";
186         else
187             errstr = "エラー: インタラプト";
188 #else
189         if (ret == SIGALRM)
190             errstr = "Error : time out";
191         else
192             errstr = "Error : interupted";
193 #endif
194         return -1;
195     }
196     sig_int_saved = signal(SIGINT, interrupt_report);
197     sig_alm_saved = signal(SIGALRM, interrupt_report);
198
199     /* タイムアウトの時間を設定 */
200     setitimer(ITIMER_REAL, &val, NULL);
201 #else
202     /* Unused in Windows */
203     (void)timeout;
204 #endif
205
206     /* プロキシが設定されていればプロキシに繋ぐ */
207     if (proxy && proxy[0]) {
208         if ((hp = gethostbyname(proxy)) == NULL) {
209 #ifdef JP
210             errstr = "エラー: プロキシのアドレスが不正です";
211 #else
212             errstr = "Error : wrong proxy addres";
213 #endif
214
215             restore_signal();
216
217             return -1;
218         }
219     } else if ((hp = gethostbyname(host)) == NULL) {
220 #ifdef JP
221         errstr = "エラー: サーバのアドレスが不正です";
222 #else
223         errstr = "Error : wrong server adress";
224 #endif
225
226         restore_signal();
227
228         return -1;
229     }
230
231     memset(&to, 0, sizeof(to));
232     memcpy(&to.sin_addr, hp->h_addr_list[0], hp->h_length);
233
234     to.sin_family = AF_INET;
235
236     if (proxy && proxy[0] && proxy_port)
237         to.sin_port = htons((unsigned short int)proxy_port);
238     else
239         to.sin_port = htons((unsigned short int)port);
240
241 #ifndef WINDOWS
242     if ((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
243 #else
244     if ((sd = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
245 #endif
246     {
247 #ifdef JP
248         errstr = "エラー: ソケットを生成できません";
249 #else
250         errstr = "Error : cannot create socket.";
251 #endif
252         restore_signal();
253         return -1;
254     }
255
256     if (connect(sd, (struct sockaddr *)&to, sizeof(to)) < 0) {
257 #ifdef JP
258         errstr = "エラー: サーバに接続できません";
259 #else
260         errstr = "Error : failed to connect server";
261 #endif
262         restore_signal();
263 #ifndef WINDOWS
264         close(sd);
265 #else
266         closesocket(sd);
267 #endif
268         return -1;
269     }
270
271     restore_signal();
272
273     return sd;
274 }
275
276 int disconnect_server(int sd)
277 {
278 #if defined(WINDOWS)
279     return closesocket(sd);
280 #else
281     return close(sd);
282 #endif
283 }
284
285 concptr soc_err() { return errstr; }
286
287 #endif /* WORLD_SCORE */