OSDN Git Service

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