OSDN Git Service

Support to write messages.
[ntch/develop.git] / src / _2ch / _2ch.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <locale.h>
5 #include <assert.h>
6 #include <wchar.h>
7 #include <iconv.h>
8 #include <errno.h>
9 #include <time.h>
10
11 #include "env.h"
12 #include "utils/nt_std_t.h"
13 #include "utils/file.h"
14 #include "utils/base64.h"
15 #include "net/nt_http.h"
16 #include "net/nt_cookie.h"
17 #include "_2ch/model_2ch.h"
18 #include "_2ch/_2ch.h"
19
20 char *URL_2CH_BOARDMENU = "http://menu.2ch.net/bbsmenu.html";
21 nt_2ch_model_tp app_2ch_modelp;
22
23
24 #define S_SIZE  (1024*2)
25
26 static BOOL conv_sjis2wc(iconv_t icd, 
27         const char *src, wchar_t *data, size_t data_len);
28 static BOOL conv_wc2sjis(iconv_t icd, 
29         const wchar_t *src, char *data, size_t data_len);
30 static BOOL conv_local2sjis(iconv_t icd, 
31         const char *src, char *data, size_t data_len);
32 static BOOL set_post_data(char *data, size_t data_len,
33                 const wchar_t *bbs, const wchar_t *id, 
34                 const char *name, const char *mail, 
35                 const char *msg);
36
37 BOOL nt_2ch_model_init(){
38         app_2ch_modelp = nt_2ch_model_alloc();
39         return (NULL != app_2ch_modelp);
40 }
41
42 BOOL nt_init_board_menu()
43 {
44         char    *outp;
45         char    *url = URL_2CH_BOARDMENU;
46         iconv_t icd;
47         FILE    *fp_src;
48         char    s_src[S_SIZE],  s_dst[S_SIZE*sizeof(wchar_t)];
49         char    *p_src, *p_dst;
50         size_t  n_src,  n_dst;
51
52         memset(s_src, '\0', S_SIZE);
53         memset(s_dst, '\0', S_SIZE*sizeof(wchar_t));
54
55         if(!nt_make_sha1_path(LOG_PATH, url, &outp)){
56                 return  FALSE;
57         }
58
59
60         if(!nt_http_get(url, outp, NULL, NULL, NULL)){
61                 free(outp);
62                 return FALSE;
63         }
64
65         fp_src  =       fopen(outp, "r");
66         if(!fp_src){
67                 free(outp);
68                 return FALSE;
69         }
70         icd     =       iconv_open("wchar_t", "cp932");
71         if(((iconv_t)-1) == icd){
72                 free(outp);
73                 return FALSE;
74         }
75         while(1){
76                 if(feof(fp_src))
77                         break;
78                 s_src[0] = '\0';
79                 fgets(s_src, S_SIZE, fp_src);
80                 p_src = s_src;
81                 p_dst = s_dst;
82
83                 n_src   =       strlen(s_src);
84                 n_dst   =       S_SIZE-1;
85                 while(0 <       n_src){
86                         size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
87                         if(sz == -1){
88                                 fprintf(stderr, "errno: %d %s\n", errno, s_src);
89                                 break;
90                         }
91                 }
92                 //*p_dst        =       '\0';
93                 *((wchar_t*)p_dst) = L'\0';
94                 parse_board_menu(app_2ch_modelp, (const wchar_t*)s_dst);
95         }
96
97         if(fp_src)
98                 fclose(fp_src);
99         iconv_close(icd);
100
101         free(outp);
102         
103         return TRUE;
104 }
105
106
107 BOOL nt_read_thread(nt_2ch_model_tp modelp)
108 {
109         wchar_t url[1024];
110         wchar_t referer[1024];
111         wchar_t buf[1024];
112         char    *outp;
113         wchar_t *file_name, *cptr;
114         wchar_t *server_name, *board_name;
115         nt_board_tp boardp;
116         nt_thread_tp threadp;
117         int len;
118         iconv_t icd;
119         FILE    *fp_src;
120         char    s_src[S_SIZE*sizeof(wchar_t)];
121         char    s_dst[S_SIZE*sizeof(wchar_t)];
122         char    *p_src, *p_dst;
123         size_t  n_src,  n_dst;
124
125         memset(s_src, '\0', sizeof(s_src));
126         memset(s_dst, '\0', sizeof(s_dst));
127
128
129         if(!modelp->selected_categoryp)
130                 return FALSE;
131         if(!modelp->selected_boardp)
132                 return FALSE;
133         if(!modelp->selected_threadp)
134                 return FALSE;
135
136         boardp = modelp->selected_boardp;
137         threadp = modelp->selected_threadp;
138         file_name = threadp->file_name;
139
140         wcscpy(url, boardp->address);
141         len = wcslen(url);
142         if(len <= 0)
143                 return FALSE;
144         if(url[len-1] != L'/'){
145                 url[len] = L'/';
146                 len++;
147                 url[len] = L'\0';
148         }
149         wcscat(url, L"dat/");
150         wcscat(url, file_name);
151
152         if(!nt_parse_server_name_and_board_name(boardp->address,
153                 buf, sizeof(buf), &server_name, &board_name)){
154                 return FALSE;
155         }
156
157         wcscpy(referer, L"http://");
158         wcscat(referer, server_name);
159         wcscat(referer, L"/test/read.cgi/");
160         wcscat(referer, board_name);
161         wcscat(referer, L"/");
162         cptr = nt_rid_sufix(file_name);
163         if(!cptr)
164                 return FALSE;
165         wcscat(referer, cptr);
166         free(cptr);
167         wcscat(referer, L"/");
168         len = wcstombs(s_src, url, sizeof(s_src)-1);
169         if(len <= 0)
170                 return FALSE;
171         len = wcstombs(s_dst, referer, sizeof(s_dst)-1);
172         if(len <= 0)
173                 return FALSE;
174         if(!nt_make_sha1_path(LOG_PATH, s_src, &outp)){
175                 return  FALSE;
176         }
177
178         if(!nt_http_get(s_src, outp, s_dst, NULL, NULL)){
179                 free(outp);
180                 return FALSE;
181         }
182         fp_src = fopen(outp, "r");
183         if(!fp_src){
184                 free(outp);
185                 return FALSE;
186         }
187         icd     =       iconv_open("wchar_t", "cp932");
188         if(((iconv_t)-1) == icd){
189                 fclose(fp_src);
190                 free(outp);
191                 return FALSE;
192         }
193         threadp->num_res = 0;
194         while(1){
195                 if(feof(fp_src))
196                         break;
197                 s_src[0] = '\0';
198                 fgets(s_src, S_SIZE, fp_src);
199                 p_src = s_src;
200                 p_dst = s_dst;
201
202                 n_src   =       strlen(s_src);
203                 n_dst   =       sizeof(s_dst)-1;
204                 while(0 < n_src){
205                         size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
206                         if(sz == -1){
207                                 //fprintf(stderr, "errno: %d %s\n", errno, s_src);
208                                 break;
209                         }
210                 }
211                 *((wchar_t*)p_dst) = L'\0';
212                 parse_thread(threadp, (const wchar_t*)s_dst);
213         }
214
215         fclose(fp_src);
216         iconv_close(icd);
217         free(outp);
218         return TRUE;
219 }
220
221 BOOL nt_read_board(nt_2ch_model_tp modelp)
222 {
223         wchar_t *address;
224         char data[256+1];
225         iconv_t icd;
226         char *outp;
227         int len;
228         FILE    *fp_src;
229         char    s_src[S_SIZE],  s_dst[S_SIZE*sizeof(wchar_t)];
230         char    *p_src, *p_dst;
231         size_t  n_src,  n_dst;
232         nt_board_tp boardp;
233
234         memset(data, 0, sizeof(data));
235         memset(s_src, '\0', S_SIZE);
236         memset(s_dst, '\0', S_SIZE*sizeof(wchar_t));
237
238         if(!modelp->selected_categoryp)
239                 return FALSE;
240         if(!modelp->selected_boardp)
241                 return FALSE;
242
243         boardp = modelp->selected_boardp;
244         nt_board_children_free(boardp);
245         address = boardp->address;
246         assert(address);
247
248         len = wcstombs(data, address, sizeof(data)-1);
249         if(len <= 0)
250                 return FALSE;
251
252         if(data[len-1] != '/')
253                 strcat(data, "/");
254         strcat(data, "subject.txt");
255
256
257         if(!nt_make_sha1_path(LOG_PATH, data, &outp)){
258                 return  FALSE;
259         }
260
261         if(!nt_http_get(data, outp, URL_2CH_BOARDMENU, NULL, NULL)){
262                 free(outp);
263                 return FALSE;
264         }
265
266         fp_src = fopen(outp, "r");
267         if(!fp_src){
268                 free(outp);
269                 return FALSE;
270         }
271         icd     =       iconv_open("wchar_t", "cp932");
272         if(((iconv_t)-1) == icd){
273                 fclose(fp_src);
274                 free(outp);
275                 return FALSE;
276         }
277         while(1){
278                 if(feof(fp_src))
279                         break;
280                 s_src[0] = '\0';
281                 fgets(s_src, S_SIZE, fp_src);
282                 p_src = s_src;
283                 p_dst = s_dst;
284
285                 n_src   =       strlen(s_src);
286                 n_dst   =       S_SIZE-1;
287                 while(0 <       n_src){
288                         size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
289                         if(sz == -1){
290                                 fprintf(stderr, "errno: %d %s\n", errno, s_src);
291                                 break;
292                         }
293                 }
294                 *((wchar_t*)p_dst) = L'\0';
295                 parse_board(boardp, (const wchar_t*)s_dst);
296         }
297
298         fclose(fp_src);
299         iconv_close(icd);
300
301         free(outp);
302         return TRUE;
303 }
304
305 BOOL nt_write_msg(nt_2ch_model_tp modelp, nt_write_data_tp writep,
306                         nt_cookie_tp cookiep, nt_maru_2ch_tp marup)
307 {
308         wchar_t url[1024];      
309         wchar_t referer[1024];
310         char    post_data[1024*4];
311         wchar_t buf[512];
312         char    out_buf[1024*4];
313         wchar_t *dat_name;
314         wchar_t *file_name;
315         wchar_t *server_name,   *board_name;
316         nt_board_tp     boardp;
317         nt_thread_tp    threadp;
318         int     len;
319         char    s_src[S_SIZE*sizeof(wchar_t)];
320         char    s_dst[S_SIZE*sizeof(wchar_t)];
321         BOOL result = FALSE;
322         iconv_t icd = 0;
323
324         memset(s_src,   '\0',   sizeof(s_src));
325         memset(s_dst,   '\0',   sizeof(s_dst));
326         memset(post_data,       '\0',   sizeof(post_data));
327
328         assert(modelp);
329
330         if(!modelp->selected_categoryp)
331                 return  FALSE;
332         if(!modelp->selected_boardp)
333                 return  FALSE;
334         if(!modelp->selected_threadp)
335                 return  FALSE;
336
337         boardp = modelp->selected_boardp;
338         threadp = modelp->selected_threadp;
339         file_name = threadp->file_name;
340
341         if(!nt_parse_server_name_and_board_name(boardp->address,
342                 buf, sizeof(buf), &server_name, &board_name)){
343                 return FALSE;
344         }
345
346         wcscpy(url, L"http://");
347         wcscat(url, server_name);
348         wcscat(url, L"/test/bbs.cgi");
349         
350         wcscpy(referer, L"http://");
351         wcscat(referer, server_name);
352         wcscat(referer, L"/test/read.cgi/");
353         wcscat(referer, board_name);
354         wcscat(referer, L"/");
355         dat_name = nt_rid_sufix(file_name);
356         if(!dat_name)
357                 return FALSE;
358         wcscat(referer, dat_name);
359         wcscat(referer, L"/");
360
361         len = wcstombs(s_src, url, sizeof(s_src)-1);
362         if(len <= 0)
363                 goto ERROR_TRAP;
364         len = wcstombs(s_dst, referer, sizeof(s_dst)-1);
365         if(len <= 0)
366                 goto ERROR_TRAP;
367         if(!set_post_data(post_data, sizeof(post_data),
368                         board_name, dat_name, writep->name,
369                         writep->mail, writep->msg)){
370                 goto ERROR_TRAP;
371         }
372         strcat(post_data, "&yuki=akari");
373
374         if(marup && marup->sid){
375                 strcat(post_data, "&sid=");
376                 strcat(post_data, marup->sid);
377         }
378         if(!nt_http_post(s_src, post_data, out_buf, sizeof(out_buf),
379                     s_dst, NULL, NULL, cookiep)){
380                 goto ERROR_TRAP;
381         }
382         icd =   iconv_open("wchar_t", "cp932");
383         if(((iconv_t)-1) == icd){
384                 icd = 0;
385                 goto ERROR_TRAP;
386         }
387         if(writep->result_html)
388                 free(writep->result_html);
389         writep->result_html = malloc(1024*sizeof(wchar_t)*4);
390         if(!writep->result_html)
391                 goto ERROR_TRAP;
392
393         if(!conv_sjis2wc(icd, out_buf, writep->result_html, 
394                                 1024*sizeof(wchar_t)*4)){
395                 goto ERROR_TRAP;
396         }
397         result = TRUE;
398 ERROR_TRAP:
399         if(icd)
400                 iconv_close(icd);
401         free(dat_name);
402         return (result);
403 }
404
405 static BOOL set_post_data(char *data, size_t data_len,
406                 const wchar_t *bbs, const wchar_t *id, 
407                 const char *name, const char *mail, 
408                 const char *msg)
409 {
410         iconv_t icd;
411         time_t t;
412         char buf[1024*4];
413         char buf2[1024*4];
414         char *cptr;
415         assert(bbs && id && name && mail && msg);
416
417         memset(buf, 0, sizeof(buf));
418         memset(buf2, 0, sizeof(buf2));
419
420         icd =   iconv_open("cp932", "wchar_t");
421         if(((iconv_t)-1) == icd){
422             return FALSE;
423         }
424         t =  time(NULL);
425         t -= 600;
426
427         cptr = data;
428         strcpy(cptr, "bbs=");
429         cptr += strlen(data);
430         if(!conv_wc2sjis(icd, bbs, buf, sizeof(buf)))
431                 return FALSE;
432         strcpy(cptr, buf);
433         cptr+= strlen(cptr);
434         strcpy(cptr, "&key=");
435         cptr += strlen(cptr);
436         if(!conv_wc2sjis(icd, id, buf, sizeof(buf)))
437                 return FALSE;
438         strcpy(cptr, buf);
439         cptr+= strlen(cptr);
440         strcpy(cptr, "&time=");
441         cptr += strlen(cptr);
442         sprintf(buf, "%ld&FROM=", t);
443         strcpy(cptr, buf);
444         cptr+= strlen(cptr);
445
446         iconv_close(icd);
447
448         icd =   iconv_open("cp932", "UTF-8");
449         if(icd == (iconv_t)-1){
450                 perror("e");
451                 return FALSE;
452         }
453
454         if(name && 0 < strlen(name)){
455                 if(!conv_local2sjis(icd, name, buf, sizeof(buf)))
456                         return FALSE;
457                 if(!url_encode(buf, buf2, sizeof(buf2)))
458                         return FALSE;
459                 strcpy(cptr, buf2);
460                 cptr += strlen(buf2);
461         }
462         strcpy(cptr, "&mail=");
463         cptr += strlen(cptr);
464         if(mail && 0 < strlen(mail)){
465                 if(!conv_local2sjis(icd, mail, buf, sizeof(buf)))
466                         return FALSE;
467                 if(!url_encode(buf, buf2, sizeof(buf2)))
468                         return FALSE;
469                 strcpy(cptr, buf2);
470                 cptr += strlen(buf2);
471         }
472         strcpy(cptr, "&MESSAGE=");
473         cptr += strlen(cptr);
474         if(msg && 0 < strlen(msg)){
475                 if(!conv_local2sjis(icd, msg, buf, sizeof(buf)))
476                         return FALSE;
477                 if(!url_encode(buf, buf2, sizeof(buf2)))
478                         return FALSE;
479                 strcpy(cptr, buf2);
480                 cptr += strlen(buf2);
481         }
482         strcpy(cptr, "&submit=8F%91%82%AB%8D%9E%82%DE");
483
484         iconv_close(icd);
485         
486         return TRUE;
487 }
488
489 static BOOL conv_sjis2wc(iconv_t icd, 
490         const char *src, wchar_t *data, size_t data_len)
491 {
492         char    *p_src, *p_dst;
493         size_t  n_src,  n_dst, sz;
494         p_src = (char*)src;
495         p_dst = (char*)data;
496         n_src   =   strlen(src) * sizeof(char);
497         n_dst   =   data_len;
498         while(0 < n_src){
499                 sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
500                 if(sz == -1){
501                         perror("e");
502                         return FALSE;
503                 }
504         }
505         *((wchar_t*)p_dst) = L'\0';
506         return TRUE;
507 }
508
509 static BOOL conv_wc2sjis(iconv_t icd, 
510         const wchar_t *src, char *data, size_t data_len)
511 {
512         char    *p_src, *p_dst;
513         size_t  n_src,  n_dst, sz;
514         p_src = (char*)src;
515         p_dst = data;
516         n_src   =   wcslen(src) * sizeof(wchar_t);
517         n_dst   =   data_len;
518         while(0 < n_src){
519                 sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
520                 if(sz == -1){
521                         perror("e");
522                         return FALSE;
523                 }
524         }
525         *p_dst = '\0';
526         return TRUE;
527 }
528
529
530 static BOOL conv_local2sjis(iconv_t icd, 
531         const char *src, char *data, size_t data_len)
532 {
533         char    *p_src, *p_dst;
534         size_t  n_src,  n_dst, sz;
535         p_src = (char*)src;
536         p_dst = data;
537         n_src   =   strlen(p_src);
538         n_dst   =   data_len;
539         while(0 < n_src){
540                 sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
541                 if(((size_t)-1) == sz){
542                         return FALSE;
543                 }
544         }
545         *p_dst = '\0';
546         return TRUE;
547 }