OSDN Git Service

Initial revision
[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 char     *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 static void set_proxy()
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, 1024, ANGBAND_DIR_PREF, "proxy.prf");
116
117         /* ¥Õ¥¡¥¤¥ë¤«¤éÀßÄê¤òÆɤࡣ*/
118         fp = my_fopen(buf, "r");
119
120         if (!fp)
121         {
122                 /* ¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ïdefine.hÆâ¤Î¥Ç¥Õ¥©¥ë¥È¤òÀßÄê */
123                 proxy = HTTP_PROXY;
124                 proxy_port = HTTP_PROXY_PORT;
125                 return;
126         }
127
128         while (my_fgets(fp, buf, 1024)==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(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 = HTTP_PROXY_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 #ifndef WINDOWS
194         write(sd, buf, sz);
195 #else
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 #endif
208 #else /* !MACINTOSH */
209
210         OTResult bytesSent;
211         
212         OTSnd(ep, (void *) buf, sz, 0);
213
214 #endif
215         return sz;
216 }
217
218 #if 0 /* ¤ª¤½¤é¤¯»È¤ï¤Ê¤¤ */
219 int soc_write_str(int sd, char *buf)
220 {
221         return soc_write(sd, buf, strlen(buf));
222 }
223 #endif
224
225 #if !defined(WINDOWS) && !defined(MACINTOSH)
226 static jmp_buf  env;
227 static void (*sig_int_saved)(int);
228 static void (*sig_alm_saved)(int);
229 #endif
230
231 static void restore_signal()
232 {
233 #if !defined(WINDOWS) && !defined(MACINTOSH)
234         struct itimerval        val0;
235
236         /* itimer¥ê¥»¥Ã¥ÈÍÑ */
237         val0.it_interval.tv_sec = 0;
238         val0.it_interval.tv_usec = 0;
239         val0.it_value.tv_sec = 0;
240         val0.it_value.tv_usec = 0;
241
242         /* ¥¢¥é¡¼¥à²ò½ü */
243         setitimer(ITIMER_REAL, &val0, NULL);
244         signal(SIGALRM, sig_alm_saved);
245         signal(SIGINT, sig_int_saved);
246 #endif
247 }
248
249
250 #if !defined(WINDOWS) && !defined(MACINTOSH)
251 static void interrupt_report(int sig)
252 {
253         restore_signal();
254         siglongjmp(env, sig);
255 }
256 #endif
257
258
259 #ifndef MACINTOSH
260 /* ¥µ¡¼¥Ð¤Ë¥³¥Í¥¯¥È¤¹¤ë´Ø¿ô¡£ Win, unix */
261 static int connect_server(int timeout, const char *host, int port)
262 {
263         int                     sd;
264         struct sockaddr_in      to;
265         struct hostent  *hp;
266
267 #ifndef WINDOWS
268         struct itimerval        val;
269         int                     ret;
270
271         /* itimerÀßÄêÍÑ */
272         val.it_interval.tv_sec = 0;
273         val.it_interval.tv_usec = 0;
274         val.it_value.tv_sec = timeout;
275         val.it_value.tv_usec = 0;
276
277         /* ¥¿¥¤¥à¥¢¥¦¥È¡¢¤â¤·¤¯¤ÏÃæÃǤ·¤¿»þ¤Î½èÍý¡£*/
278         if ((ret = sigsetjmp(env,1)) != 0)
279         {
280 #ifdef JP
281                 if (ret == SIGALRM)
282                         errstr = "¥¨¥é¡¼: ¥¿¥¤¥à¥¢¥¦¥È";
283                 else
284                         errstr = "¥¨¥é¡¼: ¥¤¥ó¥¿¥é¥×¥È";
285 #else
286                 if (ret == SIGALRM)
287                         errstr = "Error : time out";
288                 else
289                         errstr = "Error : interupted";
290 #endif
291                 return -1;
292         }
293         sig_int_saved = signal(SIGINT, interrupt_report);
294         sig_alm_saved = signal(SIGALRM, interrupt_report);
295     
296         /* ¥¿¥¤¥à¥¢¥¦¥È¤Î»þ´Ö¤òÀßÄê */
297         setitimer(ITIMER_REAL, &val, NULL);
298 #endif
299
300         /* ¥×¥í¥­¥·¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ì¤Ð¥×¥í¥­¥·¤Ë·Ò¤° */
301         if (proxy && proxy[0])
302         {
303                 if ((hp = gethostbyname(proxy)) == NULL)
304                 {
305 #ifdef JP
306                         errstr = "¥¨¥é¡¼: ¥×¥í¥­¥·¤Î¥¢¥É¥ì¥¹¤¬ÉÔÀµ¤Ç¤¹";
307 #else
308                         errstr = "Error : wrong proxy addres";
309 #endif
310
311                         restore_signal();
312
313                         return -1;
314                 }
315         }
316         else if ((hp = gethostbyname(host)) == NULL)
317         {
318 #ifdef JP
319                 errstr = "¥¨¥é¡¼: ¥µ¡¼¥Ð¤Î¥¢¥É¥ì¥¹¤¬ÉÔÀµ¤Ç¤¹";
320 #else
321                 errstr = "Error : wrong server adress";
322 #endif
323
324                 restore_signal();
325
326                 return -1;
327         }
328
329         memset(&to, 0, sizeof(to));
330         memcpy(&to.sin_addr, hp->h_addr_list[0], hp->h_length);
331
332         to.sin_family = AF_INET;
333
334         if(proxy && proxy[0] && proxy_port)
335                 to.sin_port = htons(proxy_port);
336         else
337                 to.sin_port = htons(port);
338
339 #ifndef WINDOWS
340         if ((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
341         {
342 #ifdef JP
343                 errstr = "¥¨¥é¡¼: ¥½¥±¥Ã¥È¤òÀ¸À®¤Ç¤­¤Þ¤»¤ó";
344 #else
345                 errstr = "Error : cannot create socket.";
346 #endif
347                 restore_signal();
348                 return -1;
349         }
350 #else
351         if  ((sd = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
352         {
353 #ifdef JP
354                 errstr = "¥¨¥é¡¼: ¥½¥±¥Ã¥È¤òÀ¸À®¤Ç¤­¤Þ¤»¤ó";
355 #else
356                 errstr = "Error : cannot create socket.";
357 #endif
358                 restore_signal();
359                 return -1;
360         }
361 #endif
362
363         if (connect(sd, (struct sockaddr *)&to, sizeof(to)) < 0)
364         {
365 #ifdef JP
366                 errstr = "¥¨¥é¡¼: ¥µ¡¼¥Ð¤ËÀܳ¤Ç¤­¤Þ¤»¤ó";
367 #else
368                 errstr = "Error : failed to connect server";
369 #endif
370                 restore_signal();
371 #ifndef WINDOWS
372                 close(sd);
373 #else
374                 closesocket(sd);
375 #endif
376                 return -1;
377         }
378
379         restore_signal();
380
381         return sd;
382 }
383
384 #else /* !MACINTOSH */
385
386 /* ¥µ¡¼¥Ð¤Ë¥³¥Í¥¯¥È¤¹¤ë´Ø¿ô¡£ Mac */
387 static int connect_server(int timeout, const char *host, int port)
388 {
389         OSStatus err;
390         InetHostInfo    response;
391         InetHost                host_addr;
392         InetAddress     inAddr;
393         TCall                   sndCall;
394         Boolean                 bind    = false;
395         
396         memset(&response, 0, sizeof(response));
397         
398 #if TARGET_API_MAC_CARBON
399         inet_services = OTOpenInternetServicesInContext(kDefaultInternetServicesPath, 0, &err, NULL);
400 #else
401         inet_services = OTOpenInternetServices(kDefaultInternetServicesPath, 0, &err);
402 #endif 
403         
404         if (err == noErr) {
405                 
406                 if (proxy && proxy[0])
407                 {
408                         err = OTInetStringToAddress(inet_services, proxy, &response);
409                 }
410                 else
411                 {
412                         err = OTInetStringToAddress(inet_services, (char *)host, &response);
413                 }
414                 
415                 if (err == noErr)
416                 {
417                         host_addr = response.addrs[0];
418                 }
419                 else
420                 {
421                         errstr = "error: bad score server!\n";
422                 }
423                 
424 #if TARGET_API_MAC_CARBON
425                 ep = (void *)OTOpenEndpointInContext(OTCreateConfiguration(kTCPName), 0, nil, &err, NULL);
426 #else
427                 ep = (void *)OTOpenEndpoint(OTCreateConfiguration(kTCPName), 0, nil, &err);
428 #endif
429
430                 if (err == noErr)
431                 {
432                         err = OTBind(ep, nil, nil);
433                         bind = (err == noErr);
434                 }
435                 if (err == noErr)
436                 {
437                         if (proxy && proxy[0] && proxy_port)
438                                 OTInitInetAddress(&inAddr, proxy_port, host_addr);
439                         else
440                                 OTInitInetAddress(&inAddr, port, host_addr);
441                         
442                         sndCall.addr.len        = sizeof(InetAddress);                          
443                         sndCall.addr.buf        = (unsigned char*) &inAddr;
444                         sndCall.opt.buf         = nil;          // no connection options
445                         sndCall.opt.len         = 0;
446                         sndCall.udata.buf       = nil;          // no connection data
447                         sndCall.udata.len       = 0;
448                         sndCall.sequence        = 0;            // ignored by OTConnect
449                         
450                         err = OTConnect(ep, &sndCall, NULL);
451                         
452                         if (err != noErr)
453                         {
454                                 errstr = "error: cannot connect score server!\n";
455                         }
456                 }
457         }
458         
459         if ( err != noErr )
460         {
461                 if ( bind )
462                 {
463                         OTUnbind(ep);
464                 }
465                 /* Clean up. */
466                 if (ep != kOTInvalidEndpointRef)
467                 {
468                         OTCloseProvider(ep);
469                         ep = nil;
470                 }
471                 if (inet_services != nil)
472                 {
473                         OTCloseProvider(inet_services);
474                         inet_services = nil;
475                 }
476         
477                 return -1;
478         }
479         
480         return 1;
481 }
482 #endif
483
484 int connect_scoreserver(void)
485 {
486         /* ¥×¥í¥­¥·¤òÀßÄꤹ¤ë */
487         set_proxy();
488
489         return connect_server(HTTP_TIMEOUT, SCORE_SERVER, SCORE_PORT);
490 }
491
492 int disconnect_server(int sd)
493 {
494 #if defined(WINDOWS)
495         return closesocket(sd);
496 #elif defined(MACINTOSH)
497         if (ep != kOTInvalidEndpointRef)
498         {
499                 OTCloseProvider(ep);
500         }
501         
502         if (inet_services != nil)
503         {
504                 OTCloseProvider(inet_services);
505         }
506 #else
507         return close(sd);
508 #endif
509 }
510
511 char *
512 soc_err()
513 {
514         return errstr;
515 }
516
517 #endif /* WORLD_SCORE */