OSDN Git Service

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