OSDN Git Service

[Refactor] #37353 record_turn の宣言を gameoption.h へ移動.
[hengband/hengband.git] / src / inet.c
1 /* File: inet.c */
2
3 #include "angband.h"
4 #include "util.h"
5 #include "files.h"
6 #include "inet.h"
7
8
9 #ifdef WORLD_SCORE
10
11 #include <stdio.h>
12 #include <stdarg.h>
13 #include <ctype.h>
14
15 #if defined(WINDOWS)
16 #include <winsock.h>
17 #elif defined(MACINTOSH)
18 #include <OpenTransport.h>
19 #include <OpenTptInternet.h>
20 #else
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <netinet/in.h>
24 #include <netdb.h>
25 #include <sys/time.h>
26
27 #include <setjmp.h>
28 #include <signal.h>
29 #endif
30
31 #include <stdlib.h>
32
33 static concptr errstr;
34 static char     *proxy;
35 static int      proxy_port;
36
37 #ifdef MACINTOSH
38 static InetSvcRef inet_services = nil;
39 static EndpointRef ep           = kOTInvalidEndpointRef;
40 #endif
41
42 #if 0 /* とりあえず現在は使わない。by Habu*/
43 static char     *homeurl;
44
45 void
46 set_homeurl(char *s)
47 {
48         if(homeurl)
49                 free(homeurl);
50
51         homeurl = malloc(strlen(s) + 1);
52         strcpy(homeurl, s);
53 }
54
55 char *
56 get_homeurl()
57 {
58         if(homeurl)
59                 return homeurl;
60         else
61                 return "";
62 }
63
64
65 char *
66 get_proxy()
67 {
68         static char buf[BUFSIZ];
69
70         if(proxy && proxy[0]){
71 #ifndef WINDOWS
72                 snprintf(buf, sizeof(buf), "%s:%d", proxy, proxy_port);
73 #else
74                 _snprintf(buf, sizeof(buf), "%s:%d", proxy, proxy_port);
75 #endif
76                 buf[sizeof(buf)-1] = '\0';
77                 return buf;
78         }
79         else
80                 return "";
81 }
82
83 char *
84 get_proxy_host()
85 {
86         return proxy;
87 }
88
89 int
90 get_proxy_port()
91 {
92         return proxy_port;
93 }
94
95 int soc_read(int sd, char *buf, size_t sz)
96 {
97 #ifndef WINDOWS
98         return read(sd, buf, sz);
99 #else
100         return recv(sd, buf, sz, 0);
101 #endif
102 }
103
104 #endif /* if 0 */
105
106 /* プロキシサーバのアドレスををファイルから読んで設定する */
107 void set_proxy(char *default_url, int default_port)
108 {
109         char buf[1024];
110         size_t len;
111         FILE *fp;
112         char *s;
113
114 #ifdef MACINTOSH
115         int i;
116         char tmp[8];
117 #endif
118
119         path_build(buf, sizeof(buf), ANGBAND_DIR_PREF, "proxy.prf");
120
121         /* ファイルから設定を読む。 */
122         fp = my_fopen(buf, "r");
123
124         if (!fp)
125         {
126                 /* ファイルが存在しない場合はデフォルトを設定 */
127                 proxy = default_url;
128                 proxy_port = default_port;
129                 return;
130         }
131
132         while (my_fgets(fp, buf, sizeof(buf))==0)
133         {
134                 if (buf[0] != '#' && buf[0] != '\0') break;
135         }
136
137         my_fclose(fp);
138
139         /* ポインタを用意。 */
140         s = buf;
141
142         /* "http://" から始まっている場合はその部分をカットする。 */
143 #if defined(WINDOWS)
144         if (!strnicmp(s, "http://", 7))
145         {
146                 s += 7;
147         }
148 #elif defined(MACINTOSH)
149         strncpy( tmp , s , 7 );
150         for ( i = 0 ; i < 7 ; i++ )
151         {
152                 if ( isalpha(tmp[i]) )
153                         tmp[i]= tolower(tmp[i]);
154         }
155         if (!strncmp(s, "http://", 7))
156         {
157                 s += 7;
158         }
159 #else
160         if (!strncasecmp(s, "http://", 7))
161         {
162                 s += 7;
163         }
164 #endif
165
166         /* 文字列の長さを調べ、必要なメモリを確保 */
167         len = strlen(s);
168         proxy = malloc(len + 1);
169
170         /* ポート番号があるかどうかを調べ、あればproxy_portに設定。 */
171         --len;
172         while (len > 0 && isdigit((unsigned char)s[len]))
173                 --len;
174         if (len > 0 && s[len] == ':' && s[len + 1] != '\0')
175         {
176                 s[len] = '\0';
177                 strcpy(proxy, s);
178                 proxy_port = atoi(s + (len + 1));
179         }
180         else
181         {
182                 strcpy(proxy, s);
183                 proxy_port = default_port;
184         }
185
186         /* プロキシのアドレスをproxyにコピー */
187         strcpy(proxy, s);
188
189         if (proxy_port == 0)
190                 proxy_port = 80;
191 }
192
193 /* ソケットにバッファの内容を書き込む */
194 int soc_write(int sd, char *buf, size_t sz)
195 {
196 #ifndef MACINTOSH
197         int nleft, nwritten;
198
199         nleft = sz;
200
201         while (nleft > 0) {
202                 nwritten = send(sd, buf, nleft, 0);
203                 if (nwritten <= 0)
204                         return (nwritten);
205                 nleft -= nwritten;
206                 buf += nwritten;
207         }
208 #else /* !MACINTOSH */
209
210         OTResult bytesSent;
211         
212         OTSnd(ep, (void *) buf, sz, 0);
213
214 #endif
215         return sz;
216 }
217
218 int soc_read(int sd, char *buf, size_t sz)
219 {
220 #ifndef MACINTOSH
221         int nleft, nread = 0;
222
223         nleft = sz;
224
225         while (nleft > 0) {
226                 int n;
227                 n = recv(sd, buf + nread, nleft, 0);
228                 if (n <= 0)
229                         return (nread);
230                 nleft -= n;
231                 nread += n;
232         }
233 #else /* !MACINTOSH */
234
235         OTResult bytesSent;
236
237         OTSnd(ep, (void *)buf, sz, 0);
238
239 #endif
240         return nread;
241 }
242
243 #if 0 /* おそらく使わない */
244 int soc_write_str(int sd, char *buf)
245 {
246         return soc_write(sd, buf, strlen(buf));
247 }
248 #endif
249
250 #if !defined(WINDOWS) && !defined(MACINTOSH)
251 static sigjmp_buf       env;
252 static void (*sig_int_saved)(int);
253 static void (*sig_alm_saved)(int);
254 #endif
255
256 static void restore_signal(void)
257 {
258 #if !defined(WINDOWS) && !defined(MACINTOSH)
259         struct itimerval        val0;
260
261         /* itimerリセット用 */
262         val0.it_interval.tv_sec = 0;
263         val0.it_interval.tv_usec = 0;
264         val0.it_value.tv_sec = 0;
265         val0.it_value.tv_usec = 0;
266
267         /* アラーム解除 */
268         setitimer(ITIMER_REAL, &val0, NULL);
269         signal(SIGALRM, sig_alm_saved);
270         signal(SIGINT, sig_int_saved);
271 #endif
272 }
273
274
275 #if !defined(WINDOWS) && !defined(MACINTOSH)
276 static void interrupt_report(int sig)
277 {
278         restore_signal();
279         siglongjmp(env, sig);
280 }
281 #endif
282
283
284 /* サーバにコネクトする関数。 */
285 int connect_server(int timeout, concptr host, int port)
286 #ifndef MACINTOSH
287 {
288         int                     sd;
289         struct sockaddr_in      to;
290         struct hostent  *hp;
291
292 #ifndef WINDOWS
293         struct itimerval        val;
294         int                     ret;
295
296         /* itimer設定用 */
297         val.it_interval.tv_sec = 0;
298         val.it_interval.tv_usec = 0;
299         val.it_value.tv_sec = timeout;
300         val.it_value.tv_usec = 0;
301
302         /* タイムアウト、もしくは中断した時の処理。 */
303         if ((ret = sigsetjmp(env,1)) != 0)
304         {
305 #ifdef JP
306                 if (ret == SIGALRM)
307                         errstr = "エラー: タイムアウト";
308                 else
309                         errstr = "エラー: インタラプト";
310 #else
311                 if (ret == SIGALRM)
312                         errstr = "Error : time out";
313                 else
314                         errstr = "Error : interupted";
315 #endif
316                 return -1;
317         }
318         sig_int_saved = signal(SIGINT, interrupt_report);
319         sig_alm_saved = signal(SIGALRM, interrupt_report);
320
321         /* タイムアウトの時間を設定 */
322         setitimer(ITIMER_REAL, &val, NULL);
323 #else
324         /* Unused in Windows */
325         (void)timeout;
326 #endif
327
328         /* プロキシが設定されていればプロキシに繋ぐ */
329         if (proxy && proxy[0])
330         {
331                 if ((hp = gethostbyname(proxy)) == NULL)
332                 {
333 #ifdef JP
334                         errstr = "エラー: プロキシのアドレスが不正です";
335 #else
336                         errstr = "Error : wrong proxy addres";
337 #endif
338
339                         restore_signal();
340
341                         return -1;
342                 }
343         }
344         else if ((hp = gethostbyname(host)) == NULL)
345         {
346 #ifdef JP
347                 errstr = "エラー: サーバのアドレスが不正です";
348 #else
349                 errstr = "Error : wrong server adress";
350 #endif
351
352                 restore_signal();
353
354                 return -1;
355         }
356
357         memset(&to, 0, sizeof(to));
358         memcpy(&to.sin_addr, hp->h_addr_list[0], hp->h_length);
359
360         to.sin_family = AF_INET;
361
362         if(proxy && proxy[0] && proxy_port)
363                 to.sin_port = htons((unsigned short int)proxy_port);
364         else
365                 to.sin_port = htons((unsigned short int)port);
366
367 #ifndef WINDOWS
368         if ((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
369 #else
370         if  ((sd = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
371 #endif
372         {
373 #ifdef JP
374                 errstr = "エラー: ソケットを生成できません";
375 #else
376                 errstr = "Error : cannot create socket.";
377 #endif
378                 restore_signal();
379                 return -1;
380         }
381
382         if (connect(sd, (struct sockaddr *)&to, sizeof(to)) < 0)
383         {
384 #ifdef JP
385                 errstr = "エラー: サーバに接続できません";
386 #else
387                 errstr = "Error : failed to connect server";
388 #endif
389                 restore_signal();
390 #ifndef WINDOWS
391                 close(sd);
392 #else
393                 closesocket(sd);
394 #endif
395                 return -1;
396         }
397
398         restore_signal();
399
400         return sd;
401 }
402
403 #else /* !MACINTOSH */
404
405         /* サーバにコネクトする関数。 Mac */
406 {
407         OSStatus err;
408         InetHostInfo    response;
409         InetHost                host_addr;
410         InetAddress     inAddr;
411         TCall                   sndCall;
412         Boolean                 bind    = false;
413         
414         memset(&response, 0, sizeof(response));
415         
416 #if TARGET_API_MAC_CARBON
417         inet_services = OTOpenInternetServicesInContext(kDefaultInternetServicesPath, 0, &err, NULL);
418 #else
419         inet_services = OTOpenInternetServices(kDefaultInternetServicesPath, 0, &err);
420 #endif 
421         
422         if (err == noErr) {
423                 
424                 if (proxy && proxy[0])
425                 {
426                         err = OTInetStringToAddress(inet_services, proxy, &response);
427                 }
428                 else
429                 {
430                         err = OTInetStringToAddress(inet_services, (char *)host, &response);
431                 }
432                 
433                 if (err == noErr)
434                 {
435                         host_addr = response.addrs[0];
436                 }
437                 else
438                 {
439                         errstr = "error: bad score server!\n";
440                 }
441                 
442 #if TARGET_API_MAC_CARBON
443                 ep = (void *)OTOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0, nil, &err, NULL);
444 #else
445                 ep = (void *)OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err);
446 #endif
447
448                 if (err == noErr)
449                 {
450                         err = OTBind(ep, nil, nil);
451                         bind = (err == noErr);
452                 }
453                 if (err == noErr)
454                 {
455                         if (proxy && proxy[0] && proxy_port)
456                                 OTInitInetAddress(&inAddr, proxy_port, host_addr);
457                         else
458                                 OTInitInetAddress(&inAddr, port, host_addr);
459                         
460                         sndCall.addr.len        = sizeof(InetAddress);                          
461                         sndCall.addr.buf        = (unsigned char*) &inAddr;
462                         sndCall.opt.buf         = nil;        /* no connection options */
463                         sndCall.opt.len         = 0;
464                         sndCall.udata.buf       = nil;        /* no connection data */
465                         sndCall.udata.len       = 0;
466                         sndCall.sequence        = 0;          /* ignored by OTConnect */
467                         
468                         err = OTConnect(ep, &sndCall, NULL);
469                         
470                         if (err != noErr)
471                         {
472                                 errstr = "error: cannot connect score server!\n";
473                         }
474                 }
475         }
476         
477         if ( err != noErr )
478         {
479                 if ( bind )
480                 {
481                         OTUnbind(ep);
482                 }
483                 /* Clean up. */
484                 if (ep != kOTInvalidEndpointRef)
485                 {
486                         OTCloseProvider(ep);
487                         ep = nil;
488                 }
489                 if (inet_services != nil)
490                 {
491                         OTCloseProvider(inet_services);
492                         inet_services = nil;
493                 }
494         
495                 return -1;
496         }
497         
498         return 1;
499 }
500 #endif
501
502
503 int disconnect_server(int sd)
504 {
505 #if defined(WINDOWS)
506         return closesocket(sd);
507 #elif defined(MACINTOSH)
508         if (ep != kOTInvalidEndpointRef)
509         {
510                 OTCloseProvider(ep);
511         }
512         
513         if (inet_services != nil)
514         {
515                 OTCloseProvider(inet_services);
516         }
517 #else
518         return close(sd);
519 #endif
520 }
521
522 concptr soc_err()
523 {
524         return errstr;
525 }
526
527 #endif /* WORLD_SCORE */