OSDN Git Service

ファイルをcloseせずにremoveしていた場所をcloseするように修正。
[hengbandforosx/hengbandosx.git] / src / report.c
1 /* File: report.c */
2
3 #define _GNU_SOURCE
4 #include "angband.h"
5
6 #ifdef WORLD_SCORE
7
8 #include <stdio.h>
9 #include <stdarg.h>
10 #include <ctype.h>
11 #include <string.h>
12
13 #if defined(WINDOWS)
14 #include <winsock.h>
15 #elif defined(MACINTOSH)
16 #include <OpenTransport.h>
17 #include <OpenTptInternet.h>
18 #else
19 #include <sys/types.h>
20 #include <sys/socket.h>
21 #include <netinet/in.h>
22 #include <netdb.h>
23 #include <sys/time.h>
24
25 #include <setjmp.h>
26 #include <signal.h>
27 #endif
28
29 #ifdef JP
30 #define SCORE_PATH "http://www.kmc.gr.jp/~habu/local/hengscore/score.cgi"
31 #else
32 #define SCORE_PATH "http://www.kmc.gr.jp/~habu/local/hengscore-en/score.cgi"
33 #endif
34
35 /* for debug */
36 /*#define SCORE_PATH "http://www.kmc.gr.jp/~habu/local/scoretest/score.cgi" */
37
38 /*
39  * simple buffer library
40  */
41
42 typedef struct {
43         size_t max_size;
44         size_t size;
45         char *data;
46 } BUF;
47
48 #define BUFSIZE (65536)
49
50 #ifndef HAVE_VASPRINTF
51 #define vasprintf       Vasprintf
52
53 static int Vasprintf(char **buf, const char *fmt, va_list ap)
54 {
55         int ret;
56
57         *buf = malloc(1024);
58
59 #if defined(HAVE_VSNPRINTF)
60         ret = vsnprintf(*buf, 1024, fmt, ap);
61 #else
62         ret = vsprintf(*buf, fmt, ap);
63 #endif
64         return ret;
65 }
66
67 #endif /* ifndef HAVE_VASPRINTF */ 
68
69 static BUF* buf_new(void)
70 {
71         BUF *p;
72
73         if ((p = malloc(sizeof(BUF))) == NULL)
74                 return NULL;
75
76         p->size = 0;
77         p->max_size = BUFSIZE;
78         if ((p->data = malloc(BUFSIZE)) == NULL)
79         {
80                 free(p);
81                 return NULL;
82         }
83         return p;
84 }
85
86 #if 0
87 static void buf_delete(BUF *b)
88 {
89         free(b->data);
90         free(b);
91 }
92 #endif
93
94 static int buf_append(BUF *buf, const char *data, size_t size)
95 {
96         while (buf->size + size > buf->max_size)
97         {
98                 char *tmp;
99                 if ((tmp = malloc(buf->max_size * 2)) == NULL) return -1;
100
101                 memcpy(tmp, buf->data, buf->max_size);
102                 free(buf->data);
103
104                 buf->data = tmp;
105
106                 buf->max_size *= 2;
107         }
108         memcpy(buf->data + buf->size, data, size);
109         buf->size += size;
110
111         return buf->size;
112 }
113
114 static int buf_sprintf(BUF *buf, const char *fmt, ...)
115 {
116         int             ret;
117         char    *tmpbuf;
118         va_list ap;
119
120         va_start(ap, fmt);
121         vasprintf(&tmpbuf, fmt, ap);
122         va_end(ap);
123
124         if(!tmpbuf) return -1;
125
126         ret = buf_append(buf, tmpbuf, strlen(tmpbuf));
127
128         free(tmpbuf);
129
130         return ret;
131 }
132
133 #if 0
134 static int buf_read(BUF *buf, int fd)
135 {
136         int len;
137 #ifndef MACINTOSH
138         char tmp[BUFSIZE];
139 #else
140         char *tmp;
141         
142         tmp = calloc( BUFSIZE , sizeof(char) );
143 #endif
144
145         while ((len = read(fd, tmp, BUFSIZE)) > 0)
146                 buf_append(buf, tmp, len);
147
148         return buf->size;
149 }
150 #endif
151
152 #if 0
153 static int buf_write(BUF *buf, int fd)
154 {
155         write(fd, buf->data, buf->size);
156
157         return buf->size;
158 }
159
160 static int buf_search(BUF *buf, const char *str)
161 {
162         char *ret;
163
164         ret = strstr(buf->data, str);
165
166         if (!ret) return -1;
167
168         return ret - buf->data;
169 }
170
171 static BUF * buf_subbuf(BUF *buf, int pos1, size_t sz)
172 {
173         BUF *ret;
174
175         if (pos1 < 0) return NULL;
176
177         ret = buf_new();
178
179         if (sz <= 0) sz = buf->size - pos1;
180
181         buf_append(ret, buf->data + pos1, sz);
182
183         return ret;
184 }
185 #endif
186
187 static void http_post(int sd, char *url, BUF *buf)
188 {
189         BUF *output;
190
191         output = buf_new();
192         buf_sprintf(output, "POST %s HTTP/1.0\r\n", url);
193         buf_sprintf(output, "User-Agent: Hengband %d.%d.%d\r\n",
194                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
195
196         buf_sprintf(output, "Content-Length: %d\r\n", buf->size);
197         buf_sprintf(output, "Content-Encoding: binary\r\n");
198         buf_sprintf(output, "Content-Type: application/octet-stream\r\n");
199         buf_sprintf(output, "\r\n");
200         buf_append(output, buf->data, buf->size);
201
202         soc_write(sd, output->data, output->size);
203 }
204
205
206 /* ¥­¥ã¥é¥¯¥¿¥À¥ó¥×¤òºî¤Ã¤Æ BUF¤ËÊݸ */
207 static errr make_dump(BUF* dumpbuf)
208 {
209         errr make_character_dump(FILE *fff);
210
211         char            buf[1024];
212         FILE *fff;
213         char file_name[1024];
214
215         /* Open a new file */
216         fff = my_fopen_temp(file_name, 1024);
217         if (!fff)
218         {
219 #ifdef JP
220                 msg_format("°ì»þ¥Õ¥¡¥¤¥ë %s ¤òºîÀ®¤Ç¤­¤Þ¤»¤ó¤Ç¤·¤¿¡£", file_name);
221 #else
222                 msg_format("Failed to create temporary file %s.", file_name);
223 #endif
224                 msg_print(NULL);
225                 return 1;
226         }
227
228         /* °ìö°ì»þ¥Õ¥¡¥¤¥ë¤òºî¤ë¡£Ä̾ï¤Î¥À¥ó¥×½ÐÎϤȶ¦Ä̲½¤¹¤ë¤¿¤á¡£ */
229         (void)make_character_dump(fff);
230
231         /* Close the file */
232         my_fclose(fff);
233
234         /* Open for read */
235         fff = my_fopen(file_name, "r");
236
237         while (fgets(buf, 1024, fff))
238         {
239                 (void)buf_append(dumpbuf, buf, strlen(buf));
240         }
241
242         /* Close the file */
243         my_fclose(fff);
244
245         /* Remove the file */
246         fd_kill(file_name);
247
248         /* Success */
249         return (0);
250 }
251
252 errr report_score(void)
253 {
254 #ifdef MACINTOSH
255         OSStatus err;
256 #else
257         errr err = 0;
258 #endif
259
260 #ifdef WINDOWS
261         WSADATA wsaData;
262         WORD wVersionRequested =(WORD) (( 1) |  ( 1 << 8));
263 #endif
264
265         BUF *score;
266         int sd;
267         char seikakutmp[128];
268
269         score = buf_new();
270
271 #ifdef JP
272         sprintf(seikakutmp, "%s%s", ap_ptr->title, (ap_ptr->no ? "¤Î" : ""));
273 #else
274         sprintf(seikakutmp, "%s ", ap_ptr->title);
275 #endif
276
277         buf_sprintf(score, "name: %s\n", player_name);
278 #ifdef JP
279         buf_sprintf(score, "version: ÊѶòÈÚÅÜ %d.%d.%d\n",
280                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
281 #else
282         buf_sprintf(score, "version: Hengband %d.%d.%d\n",
283                     FAKE_VER_MAJOR-10, FAKE_VER_MINOR, FAKE_VER_PATCH);
284 #endif
285         buf_sprintf(score, "score: %d\n", total_points());
286         buf_sprintf(score, "level: %d\n", p_ptr->lev);
287         buf_sprintf(score, "depth: %d\n", dun_level);
288         buf_sprintf(score, "maxlv: %d\n", p_ptr->max_plv);
289         buf_sprintf(score, "maxdp: %d\n", max_dlv[DUNGEON_ANGBAND]);
290         buf_sprintf(score, "au: %d\n", p_ptr->au);
291         buf_sprintf(score, "turns: %d\n", turn_real(turn));
292         buf_sprintf(score, "sex: %d\n", p_ptr->psex);
293         buf_sprintf(score, "race: %s\n", rp_ptr->title);
294         buf_sprintf(score, "class: %s\n", cp_ptr->title);
295         buf_sprintf(score, "seikaku: %s\n", seikakutmp);
296         buf_sprintf(score, "realm1: %s\n", realm_names[p_ptr->realm1]);
297         buf_sprintf(score, "realm2: %s\n", realm_names[p_ptr->realm2]);
298         buf_sprintf(score, "killer: %s\n", died_from);
299         buf_sprintf(score, "-----charcter dump-----\n");
300
301         make_dump(score);
302
303         if (screen_dump)
304         {
305                 buf_sprintf(score, "-----screen shot-----\n");
306                 buf_sprintf(score, screen_dump);
307         }
308
309 #ifdef WINDOWS
310         if (WSAStartup(wVersionRequested, &wsaData))
311         {
312                 msg_print("Report: WSAStartup failed.");
313                 goto report_end;
314         }
315 #endif
316
317 #ifdef MACINTOSH
318 #if TARGET_API_MAC_CARBON
319         err = InitOpenTransportInContext(kInitOTForApplicationMask, NULL);
320 #else
321         err = InitOpenTransport();
322 #endif
323         if (err != noErr)
324         {
325                 msg_print("Report: OpenTransport failed.");
326                 return 1;
327         }
328 #endif
329
330         Term_clear();
331
332         while (1)
333         {
334                 char buff[160];
335 #ifdef JP
336                 prt("ÀܳÃæ...", 0, 0);
337 #else
338                 prt("connecting...", 0, 0);
339 #endif
340                 Term_fresh();
341                 
342                 sd = connect_scoreserver();
343                 if (!(sd < 0)) break;
344 #ifdef JP
345                 sprintf(buff, "¥¹¥³¥¢¡¦¥µ¡¼¥Ð¤Ø¤ÎÀܳ¤Ë¼ºÇÔ¤·¤Þ¤·¤¿¡£(%s)", soc_err());
346 #else
347                 sprintf(buff, "Failed to connect to the score server.(%s)", soc_err());
348 #endif
349                 prt(buff, 0, 0);
350                 (void)inkey();
351                 
352 #ifdef JP
353                 if (!get_check("¤â¤¦°ìÅÙÀܳ¤ò»î¤ß¤Þ¤¹¤«? "))
354 #else
355                 if (!get_check("Try again? "))
356 #endif
357                 {
358                         err = 1;
359                         goto report_end;
360                 }
361         }
362 #ifdef JP
363         prt("¥¹¥³¥¢Á÷¿®Ãæ...", 0, 0);
364 #else
365         prt("Sending the score...", 0, 0);
366 #endif
367         Term_fresh();
368         http_post(sd, SCORE_PATH, score);
369
370         disconnect_server(sd);
371  report_end:
372 #ifdef WINDOWS
373         WSACleanup();
374 #endif
375
376 #ifdef MACINTOSH
377 #if TARGET_API_MAC_CARBON
378         CloseOpenTransportInContext(NULL);
379 #else
380         CloseOpenTransport();
381 #endif
382 #endif
383
384         return err;
385 }
386
387 #endif /* WORLD_SCORE */