OSDN Git Service

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