OSDN Git Service

v1.0.2.8
[ntch/develop.git] / src / _2ch / _2ch.c
1 /* Copyright 2013,2014 Akira Ohta (akohta001@gmail.com)
2     This file is part of ntch.
3
4     The ntch is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 3 of the License, or
7     (at your option) any later version.
8
9     The ntch is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with ntch.  If not, see <http://www.gnu.org/licenses/>.
16     
17 */
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <locale.h>
22 #include <assert.h>
23 #include <wchar.h>
24 #include <iconv.h>
25 #include <errno.h>
26 #include <time.h>
27
28 #define MODEL_2CH_PRIVATE_DATA
29
30 #include "env.h"
31 #include "utils/nt_std_t.h"
32 #include "utils/nt_conv_char.h"
33 #include "utils/file.h"
34 #include "utils/base64.h"
35 #include "utils/nt_pthread.h"
36 #include "cloud/nt_cloud.h"
37 #include "net/nt_http.h"
38 #include "net/nt_cookie.h"
39 #include "_2ch/model_2ch.h"
40 #include "_2ch/_2ch.h"
41
42 char *URL_2CH_BOARDMENU = "http://menu.2ch.net/bbsmenu.html";
43 nt_2ch_model_handle app_2ch_model;
44
45
46 #define S_SIZE  (1024*2)
47
48 static BOOL set_post_data(char *data, size_t data_len,
49                 const wchar_t *bbs, const wchar_t *id, 
50                 const char *name, const char *mail, 
51                 const char *msg);
52 static BOOL set_post_data_machibbs(char *data, size_t data_len,
53                 const wchar_t *bbs, const wchar_t *id, 
54                 const char *name, const char *mail, 
55                 const char *msg);
56 static BOOL set_offlaw_address(char *buf, size_t buf_len,
57                         wchar_t *server_name, 
58                         wchar_t * board_name, wchar_t *dat_name);
59 static BOOL nt_write_msg_machibbs(nt_2ch_selected_item_tp selectp,
60                          nt_write_data_tp writep, nt_cookie_tp cookiep);
61
62 static nt_pthread_result_t nt_read_board_async(void* data);
63 static nt_pthread_result_t nt_read_board_async_result(
64                         nt_pthread_result_t result);
65
66                     
67 BOOL nt_2ch_model_init(){
68         app_2ch_model = nt_2ch_model_alloc();
69         return (NULL != app_2ch_model);
70 }
71
72 BOOL nt_init_board_menu()
73 {
74         char    *outp;
75         char    *url = URL_2CH_BOARDMENU;
76         iconv_t icd;
77         FILE    *fp_src;
78         char    s_src[S_SIZE],  s_dst[S_SIZE*sizeof(wchar_t)];
79         char    *p_src, *p_dst;
80         size_t  n_src,  n_dst;
81
82         memset(s_src, '\0', S_SIZE);
83         memset(s_dst, '\0', S_SIZE*sizeof(wchar_t));
84
85         if(!nt_make_sha1_path(LOG_PATH, url, &outp)){
86                 return  FALSE;
87         }
88
89
90         if(!nt_http_get(url, outp, NULL, NULL, NULL, FALSE, FALSE)){
91                 free(outp);
92                 return FALSE;
93         }
94
95         fp_src  =       fopen(outp, "r");
96         if(!fp_src){
97                 free(outp);
98                 return FALSE;
99         }
100         icd     =       iconv_open("wchar_t", "cp932");
101         if(((iconv_t)-1) == icd){
102                 free(outp);
103                 return FALSE;
104         }
105         while(1){
106                 if(feof(fp_src))
107                         break;
108                 s_src[0] = '\0';
109                 if(!fgets(s_src, S_SIZE, fp_src))
110                         break;
111                 p_src = s_src;
112                 p_dst = s_dst;
113
114                 n_src   =       strlen(s_src);
115                 n_dst   =       S_SIZE-1;
116                 while(0 <       n_src){
117                         size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
118                         if(sz == -1){
119                                 //fprintf(stderr, "errno: %d %s\n", errno, s_src);
120                                 break;
121                         }
122                 }
123                 //*p_dst        =       '\0';
124                 *((wchar_t*)p_dst) = L'\0';
125                 parse_board_menu(app_2ch_model, (const wchar_t*)s_dst);
126         }
127
128         if(fp_src)
129                 fclose(fp_src);
130         iconv_close(icd);
131
132         free(outp);
133         
134         return TRUE;
135 }
136
137 static BOOL is_machibbs_address(const wchar_t *host_name)
138 {
139         wchar_t *cptr;
140         cptr = wcsstr(host_name, L".machi.to");
141         return (cptr != NULL) ? TRUE : FALSE;
142 }
143
144 BOOL nt_read_thread(nt_2ch_selected_item_handle h_select)
145 {
146         nt_2ch_selected_item_tp selectp;
147         wchar_t url[1024];
148         wchar_t referer[1024];
149         wchar_t buf[1024];
150         char    *outp;
151         wchar_t *file_name, *cptr;
152         wchar_t *server_name, *board_name;
153         nt_board_tp boardp;
154         nt_thread_tp threadp;
155         int len, res_no;
156         iconv_t icd;
157         FILE    *fp_src;
158         char    s_src[S_SIZE*sizeof(wchar_t)];
159         char    s_dst[S_SIZE*sizeof(wchar_t)];
160         char    *p_src, *p_dst;
161         size_t  n_src,  n_dst;
162         BOOL is_matchi_bbs;
163         nt_cloud_handle h_cloud;
164         
165         assert(h_select);
166         assert(h_select->chk_sum == NT_2CH_SELECTED_ITEM_CHK_SUM);
167         
168         selectp = (nt_2ch_selected_item_tp)h_select;
169
170         memset(s_src, '\0', sizeof(s_src));
171         memset(s_dst, '\0', sizeof(s_dst));
172
173
174         if(!selectp->selected_categoryp)
175                 return FALSE;
176         if(!selectp->selected_boardp)
177                 return FALSE;
178         if(!selectp->selected_threadp)
179                 return FALSE;
180
181         boardp = selectp->selected_boardp;
182         threadp = selectp->selected_threadp;
183         file_name = threadp->file_name;
184
185
186         if(!nt_parse_server_name_and_board_name(boardp->address,
187                 buf, sizeof(buf), &server_name, &board_name)){
188                 return FALSE;
189         }
190         if(is_machibbs_address(server_name)){
191                 is_matchi_bbs = TRUE;
192                 wcscpy(url, L"http://");
193                 wcscat(url, server_name);
194                 wcscat(url, L"/bbs/offlaw.cgi/");
195                 wcscat(url, board_name);
196                 wcscat(url, L"/");
197                 cptr = nt_rid_sufix(file_name);
198                 if(!cptr)
199                         return FALSE;
200                 wcscat(url, cptr);
201                 free(cptr);
202                 wcscat(url, L"/");
203                 
204                 wcscpy(referer, boardp->address);
205                 wcscat(referer, L"/");
206         }else{
207                 is_matchi_bbs = FALSE;
208                 wcscpy(url, boardp->address);
209                 len = wcslen(url);
210                 if(len <= 0)
211                         return FALSE;
212                 if(url[len-1] != L'/'){
213                         url[len] = L'/';
214                         len++;
215                         url[len] = L'\0';
216                 }
217                 wcscat(url, L"dat/");
218                 wcscat(url, file_name);
219                 wcscpy(referer, L"http://");
220                 wcscat(referer, server_name);
221                 wcscat(referer, L"/test/read.cgi/");
222                 wcscat(referer, board_name);
223                 wcscat(referer, L"/");
224                 cptr = nt_rid_sufix(file_name);
225                 if(!cptr)
226                         return FALSE;
227                 wcscat(referer, cptr);
228                 free(cptr);
229                 wcscat(referer, L"/");
230         }
231         len = wcstombs(s_src, url, sizeof(s_src)-1);
232         if(len <= 0)
233                 return FALSE;
234         len = wcstombs(s_dst, referer, sizeof(s_dst)-1);
235         if(len <= 0)
236                 return FALSE;
237         if(!nt_make_sha1_path(LOG_PATH, s_src, &outp)){
238                 return  FALSE;
239         }
240
241         if(!nt_http_get(s_src, outp, s_dst, NULL, NULL, TRUE, FALSE)){
242                 if(!set_offlaw_address(s_src, sizeof(s_src),
243                                 server_name, board_name, file_name)){
244                         free(outp);
245                         return FALSE;
246                 }
247                 if(!nt_http_get(s_src, outp, s_dst, NULL, NULL, FALSE, FALSE)){
248                         free(outp);
249                         return FALSE;
250                 }
251         }
252         fp_src = fopen(outp, "r");
253         if(!fp_src){
254                 free(outp);
255                 return FALSE;
256         }
257         icd     =       iconv_open("wchar_t", "cp932");
258         if(((iconv_t)-1) == icd){
259                 fclose(fp_src);
260                 free(outp);
261                 return FALSE;
262         }
263         nt_thread_clear_children(&threadp->handle);
264         threadp->num_res = 0;
265         res_no = 0;
266         while(1){
267                 res_no++;
268                 if(feof(fp_src))
269                         break;
270                 s_src[0] = '\0';
271                 if(!fgets(s_src, S_SIZE, fp_src))
272                         break;
273                 p_src = s_src;
274                 p_dst = s_dst;
275
276                 n_src   =       strlen(s_src);
277                 n_dst   =       sizeof(s_dst)-1;
278                 while(0 < n_src){
279                         size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
280                         if(sz == -1){
281                                 //fprintf(stderr, "errno: %d %s\n", errno, s_src);
282                                 break;
283                         }
284                 }
285                 *((wchar_t*)p_dst) = L'\0';
286                 if(!is_matchi_bbs)
287                         parse_thread(&threadp->handle, (const wchar_t*)s_dst, res_no);
288                 else
289                         parse_thread_machi_bbs(&threadp->handle, (const wchar_t*)s_dst);
290         }
291
292         fclose(fp_src);
293         iconv_close(icd);
294         free(outp);
295         h_cloud = nt_cloud_get_handle();
296         if(h_cloud && threadp->num_res > 0){
297                 nt_cloud_update_read_count_async(h_cloud,
298                                 boardp->name, file_name, threadp->num_res);
299         }
300         if(h_cloud)
301                 nt_cloud_release_ref(h_cloud);
302         return (threadp->num_res > 0);
303 }
304
305 wchar_t* nt_read_thread_title(nt_board_handle h_board,
306                 const wchar_t *dat_name)
307 {
308         nt_board_tp boardp;
309         wchar_t url[1024];
310         char    *outp;
311         wchar_t *title;
312         int len;
313         iconv_t icd;
314         FILE    *fp_src;
315         char    s_src[S_SIZE*sizeof(wchar_t)];
316         char    s_dst[S_SIZE*sizeof(wchar_t)];
317         char    *p_src, *p_dst;
318         size_t  n_src,  n_dst;
319         
320         assert(h_board);
321         assert(h_board->chk_sum == NT_2CH_BOARD_CHK_SUM);
322         boardp = (nt_board_tp)h_board;
323
324         memset(s_src, '\0', sizeof(s_src));
325         memset(s_dst, '\0', sizeof(s_dst));
326         title = NULL;
327
328         wcscpy(url, boardp->address);
329         len = wcslen(url);
330         if(len <= 0)
331                 return NULL;
332         if(url[len-1] != L'/'){
333                 url[len] = L'/';
334                 len++;
335                 url[len] = L'\0';
336         }
337         wcscat(url, L"dat/");
338         wcscat(url, dat_name);
339
340
341         len = wcstombs(s_src, url, sizeof(s_src)-1);
342         if(len <= 0)
343                 return NULL;
344         if(!nt_make_sha1_path(LOG_PATH, s_src, &outp)){
345                 return  NULL;
346         }
347
348         fp_src = fopen(outp, "r");
349         if(!fp_src){
350                 free(outp);
351                 return NULL;
352         }
353         icd     =       iconv_open("wchar_t", "cp932");
354         if(((iconv_t)-1) == icd){
355                 fclose(fp_src);
356                 free(outp);
357                 return NULL;
358         }
359         if(!feof(fp_src)){
360                 s_src[0] = '\0';
361                 if(!fgets(s_src, S_SIZE, fp_src)){
362                         iconv_close(icd);
363                         fclose(fp_src);
364                         free(outp);
365                         return NULL;
366                 }
367                 p_src = s_src;
368                 p_dst = s_dst;
369
370                 n_src   =       strlen(s_src);
371                 n_dst   =       sizeof(s_dst)-1;
372                 while(0 < n_src){
373                         size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
374                         if(sz == -1){
375                                 //fprintf(stderr, "errno: %d %s\n", errno, s_src);
376                                 break;
377                         }
378                 }
379                 *((wchar_t*)p_dst) = L'\0';
380                 title = parse_thread_title((const wchar_t*)s_dst);
381         }
382         fclose(fp_src);
383         iconv_close(icd);
384         free(outp);
385         return title;
386 }
387
388 BOOL nt_read_board(nt_2ch_selected_item_handle h_select)
389 {
390         nt_2ch_selected_item_tp selectp;
391         wchar_t *address;
392         char data[256+1];
393         iconv_t icd;
394         char *outp;
395         int len;
396         FILE    *fp_src;
397         char    s_src[S_SIZE],  s_dst[S_SIZE*sizeof(wchar_t)];
398         char    *p_src, *p_dst;
399         size_t  n_src,  n_dst;
400         nt_board_tp boardp;
401         nt_mutex_handle h_mutex;
402
403         assert(h_select);
404         assert(h_select->chk_sum == NT_2CH_SELECTED_ITEM_CHK_SUM);
405         
406         selectp = (nt_2ch_selected_item_tp)h_select;
407         
408         memset(data, 0, sizeof(data));
409         memset(s_src, '\0', S_SIZE);
410         memset(s_dst, '\0', S_SIZE*sizeof(wchar_t));
411         //fputs("enter nt_read_board\n",stderr);
412         if(!selectp->selected_categoryp)
413                 return FALSE;
414         if(!selectp->selected_boardp)
415                 return FALSE;
416         
417         boardp = selectp->selected_boardp;
418         //fwprintf(stderr, L"%ls\n", boardp->name);
419         h_mutex = nt_board_get_mutex(&boardp->handle);
420         if(!h_mutex)
421                 return FALSE;
422         if(!nt_mutex_lock(h_mutex))
423                 return FALSE;
424         //fputs(" -- lock nt_read_board\n",stderr);
425
426         nt_board_clear_children(&boardp->handle);
427         address = boardp->address;
428         assert(address);
429
430         len = wcstombs(data, address, sizeof(data)-1);
431         if(len <= 0){
432                 nt_mutex_unlock(h_mutex);
433                 return FALSE;
434         }
435
436         if(data[len-1] != '/')
437                 strcat(data, "/");
438         strcat(data, "subject.txt");
439
440
441         if(!nt_make_sha1_path(LOG_PATH, data, &outp)){
442                 nt_mutex_unlock(h_mutex);
443                 return  FALSE;
444         }
445
446         if(!nt_http_get(data, outp, URL_2CH_BOARDMENU, NULL, NULL, FALSE, FALSE)){
447                 free(outp);
448                 nt_mutex_unlock(h_mutex);
449                 return FALSE;
450         }
451
452         fp_src = fopen(outp, "r");
453         if(!fp_src){
454                 free(outp);
455                 nt_mutex_unlock(h_mutex);
456                 return FALSE;
457         }
458         icd     =       iconv_open("wchar_t", "cp932");
459         if(((iconv_t)-1) == icd){
460                 fclose(fp_src);
461                 free(outp);
462                 nt_mutex_unlock(h_mutex);
463                 return FALSE;
464         }
465         while(1){
466                 if(feof(fp_src))
467                         break;
468                 s_src[0] = '\0';
469                 if(!fgets(s_src, S_SIZE, fp_src))
470                         break;
471                 p_src = s_src;
472                 p_dst = s_dst;
473
474                 n_src   =       strlen(s_src);
475                 n_dst   =       (S_SIZE-1)*sizeof(wchar_t);
476                 while(0 <       n_src){
477                         size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
478                         if(sz == -1){
479                                 //fprintf(stderr, "errno: %d %s\n", errno, s_src);
480                                 break;
481                         }
482                 }
483                 *((wchar_t*)p_dst) = L'\0';
484                 if(!parse_board(&boardp->handle, (const wchar_t*)s_dst)){
485                 }
486         }
487         fclose(fp_src);
488         iconv_close(icd);
489         
490         //fputs(" -- unlock nt_read_board\n",stderr);
491         nt_mutex_unlock(h_mutex);
492         //fputs("exit nt_read_board\n",stderr);
493         free(outp);
494         if(!boardp->threadlistp)
495                 return FALSE;
496         return TRUE;
497 }
498
499 BOOL nt_write_msg(nt_2ch_selected_item_handle h_select, nt_write_data_handle h_write_data,
500                         nt_cookie_tp cookiep, nt_maru_2ch_tp marup)
501 {
502         nt_2ch_selected_item_tp selectp;
503         nt_write_data_tp writep;
504         wchar_t url[1024];      
505         wchar_t referer[1024];
506         char    post_data[1024*4];
507         wchar_t buf[512];
508         char    out_buf[1024*4];
509         wchar_t *dat_name;
510         wchar_t *file_name;
511         wchar_t *server_name,   *board_name;
512         nt_board_tp     boardp;
513         nt_thread_tp    threadp;
514         int     len;
515         char    s_src[S_SIZE*sizeof(wchar_t)];
516         char    s_dst[S_SIZE*sizeof(wchar_t)];
517         BOOL result = FALSE;
518         iconv_t icd = 0;
519
520         assert(h_select);
521         assert(h_select->chk_sum == NT_2CH_SELECTED_ITEM_CHK_SUM);
522         assert(h_write_data);
523         assert(h_write_data->chk_sum == NT_2CH_WRITE_DATA_CHK_SUM);
524         
525         selectp = (nt_2ch_selected_item_tp)h_select;
526         writep = (nt_write_data_tp)h_write_data;
527         
528         memset(s_src,   '\0',   sizeof(s_src));
529         memset(s_dst,   '\0',   sizeof(s_dst));
530         memset(post_data,       '\0',   sizeof(post_data));
531
532         if(!selectp->selected_categoryp)
533                 return  FALSE;
534         if(!selectp->selected_boardp)
535                 return  FALSE;
536         if(!selectp->selected_threadp)
537                 return  FALSE;
538
539         boardp = selectp->selected_boardp;
540         threadp = selectp->selected_threadp;
541         file_name = threadp->file_name;
542
543         if(!nt_parse_server_name_and_board_name(boardp->address,
544                 buf, sizeof(buf), &server_name, &board_name)){
545                 return FALSE;
546         }
547
548         if(is_machibbs_address(server_name)){
549                 return nt_write_msg_machibbs(selectp, writep, cookiep);
550         }
551         
552         wcscpy(url, L"http://");
553         wcscat(url, server_name);
554         wcscat(url, L"/test/bbs.cgi");
555         
556         wcscpy(referer, L"http://");
557         wcscat(referer, server_name);
558         wcscat(referer, L"/test/read.cgi/");
559         wcscat(referer, board_name);
560         wcscat(referer, L"/");
561         dat_name = nt_rid_sufix(file_name);
562         if(!dat_name)
563                 return FALSE;
564         wcscat(referer, dat_name);
565         wcscat(referer, L"/");
566
567         len = wcstombs(s_src, url, sizeof(s_src)-1);
568         if(len <= 0)
569                 goto ERROR_TRAP;
570         len = wcstombs(s_dst, referer, sizeof(s_dst)-1);
571         if(len <= 0)
572                 goto ERROR_TRAP;
573         if(!set_post_data(post_data, sizeof(post_data),
574                         board_name, dat_name, writep->name,
575                         writep->mail, writep->msg)){
576                 goto ERROR_TRAP;
577         }
578         strcat(post_data, "&yuki=akari");
579
580         if(marup && marup->sid){
581                 strcat(post_data, "&sid=");
582                 strcat(post_data, marup->sid);
583         }
584         if(!nt_http_post(s_src, post_data, out_buf, sizeof(out_buf),
585                     s_dst, NULL, NULL, cookiep)){
586                 goto ERROR_TRAP;
587         }
588         icd =   iconv_open("wchar_t", "cp932");
589         if(((iconv_t)-1) == icd){
590                 icd = 0;
591                 goto ERROR_TRAP;
592         }
593         if(writep->result_html)
594                 free(writep->result_html);
595         writep->result_html = malloc(1024*sizeof(wchar_t)*4);
596         if(!writep->result_html)
597                 goto ERROR_TRAP;
598
599         if(!nt_conv_sjis2wc(icd, out_buf, writep->result_html, 
600                                 1024*sizeof(wchar_t)*4)){
601                 goto ERROR_TRAP;
602         }
603         result = TRUE;
604 ERROR_TRAP:
605         if(icd)
606                 iconv_close(icd);
607         free(dat_name);
608         return (result);
609 }
610
611
612 static BOOL nt_write_msg_machibbs(nt_2ch_selected_item_tp selectp, 
613                         nt_write_data_tp writep, nt_cookie_tp cookiep)
614 {
615         wchar_t url[1024];      
616         wchar_t referer[1024];
617         char    post_data[1024*4];
618         wchar_t buf[512];
619         char    out_buf[1024*4];
620         wchar_t *dat_name;
621         wchar_t *file_name;
622         wchar_t *server_name,   *board_name;
623         nt_board_tp     boardp;
624         nt_thread_tp    threadp;
625         int     len;
626         char    s_src[S_SIZE*sizeof(wchar_t)];
627         char    s_dst[S_SIZE*sizeof(wchar_t)];
628         BOOL result = FALSE;
629         iconv_t icd = 0;
630
631         memset(s_src,   '\0',   sizeof(s_src));
632         memset(s_dst,   '\0',   sizeof(s_dst));
633         memset(post_data,       '\0',   sizeof(post_data));
634
635         if(!selectp->selected_categoryp)
636                 return  FALSE;
637         if(!selectp->selected_boardp)
638                 return  FALSE;
639         if(!selectp->selected_threadp)
640                 return  FALSE;
641
642         boardp = selectp->selected_boardp;
643         threadp = selectp->selected_threadp;
644         file_name = threadp->file_name;
645
646         if(!nt_parse_server_name_and_board_name(boardp->address,
647                 buf, sizeof(buf), &server_name, &board_name)){
648                 return FALSE;
649         }
650
651         
652         wcscpy(url, L"http://");
653         wcscat(url, server_name);
654         wcscat(url, L"/bbs/write.cgi");
655         dat_name = nt_rid_sufix(file_name);
656         if(!dat_name)
657                 return FALSE;
658         
659         wcscpy(referer, boardp->address);
660
661         len = wcstombs(s_src, url, sizeof(s_src)-1);
662         if(len <= 0)
663                 goto ERROR_TRAP;
664         len = wcstombs(s_dst, referer, sizeof(s_dst)-1);
665         if(len <= 0)
666                 goto ERROR_TRAP;
667         if(!set_post_data_machibbs(post_data, sizeof(post_data),
668                         board_name, dat_name, writep->name,
669                         writep->mail, writep->msg)){
670                 goto ERROR_TRAP;
671         }
672         len = wcstombs(s_src, url, sizeof(s_src)-1);
673         if(len <= 0)
674                 goto ERROR_TRAP;
675         strcat(post_data, "&CC=%82%A0");
676         
677         if(!nt_http_post(s_src, post_data, out_buf, sizeof(out_buf),
678                     s_dst, NULL, NULL, cookiep)){
679                 goto ERROR_TRAP;
680         }
681         icd =   iconv_open("wchar_t", "cp932");
682         if(((iconv_t)-1) == icd){
683                 icd = 0;
684                 goto ERROR_TRAP;
685         }
686         if(writep->result_html)
687                 free(writep->result_html);
688         writep->result_html = malloc(1024*sizeof(wchar_t)*4);
689         if(!writep->result_html)
690                 goto ERROR_TRAP;
691
692         if(!nt_conv_sjis2wc(icd, out_buf, writep->result_html, 
693                                 1024*sizeof(wchar_t)*4)){
694                 goto ERROR_TRAP;
695         }
696         result = TRUE;
697 ERROR_TRAP:
698         if(icd)
699                 iconv_close(icd);
700         free(dat_name);
701         return (result);
702 }
703
704
705
706 static BOOL set_post_data(char *data, size_t data_len,
707                 const wchar_t *bbs, const wchar_t *id, 
708                 const char *name, const char *mail, 
709                 const char *msg)
710 {
711         iconv_t icd;
712         time_t t;
713         char buf[1024*4];
714         char buf2[1024*4];
715         char *cptr;
716         assert(bbs && id && name && mail && msg);
717
718         memset(buf, 0, sizeof(buf));
719         memset(buf2, 0, sizeof(buf2));
720
721         icd =   iconv_open("cp932", "wchar_t");
722         if(((iconv_t)-1) == icd){
723             return FALSE;
724         }
725         t =  time(NULL);
726         t -= 600;
727
728         cptr = data;
729         strcpy(cptr, "bbs=");
730         cptr += strlen(data);
731         if(!nt_conv_wc2sjis(icd, bbs, buf, sizeof(buf)))
732                 return FALSE;
733         strcpy(cptr, buf);
734         cptr+= strlen(cptr);
735         strcpy(cptr, "&key=");
736         cptr += strlen(cptr);
737         if(!nt_conv_wc2sjis(icd, id, buf, sizeof(buf)))
738                 return FALSE;
739         strcpy(cptr, buf);
740         cptr+= strlen(cptr);
741         strcpy(cptr, "&time=");
742         cptr += strlen(cptr);
743         sprintf(buf, "%ld&FROM=", t);
744         strcpy(cptr, buf);
745         cptr+= strlen(cptr);
746
747         iconv_close(icd);
748
749         icd =   iconv_open("cp932", "UTF-8");
750         if(icd == (iconv_t)-1){
751                 perror("e");
752                 return FALSE;
753         }
754
755         if(name && 0 < strlen(name)){
756                 if(!nt_conv_local2sjis(icd, name, buf, sizeof(buf)))
757                         return FALSE;
758                 if(!url_encode(buf, buf2, sizeof(buf2)))
759                         return FALSE;
760                 strcpy(cptr, buf2);
761                 cptr += strlen(buf2);
762         }
763         strcpy(cptr, "&mail=");
764         cptr += strlen(cptr);
765         if(mail && 0 < strlen(mail)){
766                 if(!nt_conv_local2sjis(icd, mail, buf, sizeof(buf)))
767                         return FALSE;
768                 if(!url_encode(buf, buf2, sizeof(buf2)))
769                         return FALSE;
770                 strcpy(cptr, buf2);
771                 cptr += strlen(buf2);
772         }
773         strcpy(cptr, "&MESSAGE=");
774         cptr += strlen(cptr);
775         if(msg && 0 < strlen(msg)){
776                 if(!nt_conv_local2sjis(icd, msg, buf, sizeof(buf)))
777                         return FALSE;
778                 if(!url_encode(buf, buf2, sizeof(buf2)))
779                         return FALSE;
780                 strcpy(cptr, buf2);
781                 cptr += strlen(buf2);
782         }
783         strcpy(cptr, "&submit=%8F%91%82%AB%8D%9E%82%DE");
784
785         iconv_close(icd);
786         
787         return TRUE;
788 }
789
790 static BOOL set_post_data_machibbs(char *data, size_t data_len,
791                 const wchar_t *bbs, const wchar_t *id, 
792                 const char *name, const char *mail, 
793                 const char *msg)
794 {
795         iconv_t icd;
796         time_t t;
797         char buf[1024*4];
798         char buf2[1024*4];
799         char *cptr;
800         assert(bbs && id && name && mail && msg);
801
802         memset(buf, 0, sizeof(buf));
803         memset(buf2, 0, sizeof(buf2));
804
805         icd =   iconv_open("cp932", "wchar_t");
806         if(((iconv_t)-1) == icd){
807             return FALSE;
808         }
809         t =  time(NULL);
810         t -= 600;
811
812         cptr = data;
813         strcpy(cptr, "BBS=");
814         cptr += strlen(data);
815         if(!nt_conv_wc2sjis(icd, bbs, buf, sizeof(buf)))
816                 return FALSE;
817         strcpy(cptr, buf);
818         cptr+= strlen(cptr);
819         strcpy(cptr, "&KEY=");
820         cptr += strlen(cptr);
821         if(!nt_conv_wc2sjis(icd, id, buf, sizeof(buf)))
822                 return FALSE;
823         strcpy(cptr, buf);
824         cptr+= strlen(cptr);
825         strcpy(cptr, "&TIME=");
826         cptr += strlen(cptr);
827         sprintf(buf, "%ld&NAME=", t);
828         strcpy(cptr, buf);
829         cptr+= strlen(cptr);
830
831         iconv_close(icd);
832
833         icd =   iconv_open("cp932", "UTF-8");
834         if(icd == (iconv_t)-1){
835                 perror("e");
836                 return FALSE;
837         }
838
839         if(name && 0 < strlen(name)){
840                 if(!nt_conv_local2sjis(icd, name, buf, sizeof(buf)))
841                         return FALSE;
842                 if(!url_encode(buf, buf2, sizeof(buf2)))
843                         return FALSE;
844                 strcpy(cptr, buf2);
845                 cptr += strlen(buf2);
846         }
847         strcpy(cptr, "&MAIL=");
848         cptr += strlen(cptr);
849         if(mail && 0 < strlen(mail)){
850                 if(!nt_conv_local2sjis(icd, mail, buf, sizeof(buf)))
851                         return FALSE;
852                 if(!url_encode(buf, buf2, sizeof(buf2)))
853                         return FALSE;
854                 strcpy(cptr, buf2);
855                 cptr += strlen(buf2);
856         }
857         strcpy(cptr, "&MESSAGE=");
858         cptr += strlen(cptr);
859         if(msg && 0 < strlen(msg)){
860                 if(!nt_conv_local2sjis(icd, msg, buf, sizeof(buf)))
861                         return FALSE;
862                 if(!url_encode(buf, buf2, sizeof(buf2)))
863                         return FALSE;
864                 strcpy(cptr, buf2);
865                 cptr += strlen(buf2);
866         }
867         strcpy(cptr, "&submit=%8F%91%82%AB%8D%9E%82%DE");
868
869         iconv_close(icd);
870         
871         return TRUE;
872 }
873
874 static BOOL set_offlaw_address(char *buf, size_t buf_len,
875                         wchar_t *server_name, 
876                         wchar_t * board_name, wchar_t *dat_name)
877 {
878         wchar_t *cptr;
879         int len;
880         wchar_t url[512];
881
882         cptr = wcsstr(server_name, L".2ch.net");
883         if(!cptr)
884                 return FALSE;
885         cptr = wcsstr(dat_name, L".dat");
886         if(!cptr)
887                 return FALSE;
888         cptr = nt_rid_sufix(dat_name);
889         if(!cptr)
890                 return FALSE;
891         wcscpy(url, L"http://");
892         wcscat(url, server_name);
893         wcscat(url, L"/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs=");
894         wcscat(url, board_name);
895         wcscat(url, L"&key=");
896         wcscat(url, cptr);
897         free(cptr);
898         len = wcstombs(buf, url, buf_len-1);
899         if(len <= 0)
900                 return FALSE;
901         return TRUE;
902 }
903
904 int nt_read_board_list(nt_link_tp selitem_list)
905 {
906         nt_2ch_selected_item_handle h_select;
907         nt_link_tp linkp;
908         int num_success;
909         nt_pthread_handle h_pthread;
910         
911         assert(selitem_list);
912         num_success = 0;
913         linkp = selitem_list;
914         do{
915                 h_select = (nt_2ch_selected_item_handle)linkp->data;
916 #ifdef NT_DISABLE_PTHREAD
917                 if(nt_read_board(h_select))
918                         num_success++;
919 #else
920                 nt_2ch_selected_item_add_ref(h_select);
921                 h_pthread = nt_pthread_alloc(
922                                 nt_read_board_async,
923                                 h_select,
924                                 nt_read_board_async_result);
925                 if(!h_pthread){
926                         nt_2ch_selected_item_release_ref(h_select);
927                 }else if(!nt_pthread_put_que(h_pthread)){
928                         nt_pthread_release_ref(h_pthread);
929                         nt_2ch_selected_item_release_ref(h_select);
930                 }else{
931                         nt_pthread_release_ref(h_pthread);
932                         num_success++;
933                 }
934 #endif
935                 linkp = linkp->next;
936         }while(linkp != selitem_list);
937         return num_success;
938 }
939
940 static nt_pthread_result_t nt_read_board_async(void* data)
941 {
942         nt_2ch_selected_item_handle h_select;
943         nt_pthread_result_t result;
944         
945         result.code = NT_PTHREAD_RESULT_NONE;
946         result.data = NULL;
947         
948         h_select = (nt_2ch_selected_item_handle)data;
949         nt_2ch_selected_item_add_ref(h_select);
950         nt_2ch_selected_item_release_ref(h_select);
951         
952         if(nt_read_board(h_select)){
953                 result.code = NT_PTHREAD_RESULT_UPDATE_BOARD;
954         }
955         nt_2ch_selected_item_release_ref(h_select);
956         return result;
957 }
958
959 static nt_pthread_result_t nt_read_board_async_result(
960                         nt_pthread_result_t result)
961 {
962         return result;
963 }
964
965 BOOL nt_set_sel_item(nt_2ch_model_handle h_model,
966                         nt_2ch_selected_item_handle *h_sel_itemp, 
967                         nt_searched_thread_handle h_searched_thread, const wchar_t** errorpp)
968 {
969         const wchar_t *board_name, *dat_name, *title;
970         wchar_t *cptr;
971         nt_category_handle h_category;
972         nt_board_handle h_board;
973         nt_thread_handle h_thread;
974         nt_2ch_selected_item_handle h_sel_item;
975         nt_enum_handle h_enum;
976         
977         assert(h_sel_itemp);
978         
979         h_thread = NULL;
980         
981         h_sel_item = nt_2ch_selected_item_alloc();
982         if(!h_sel_item){
983                 return FALSE;
984         }
985         board_name = nt_searched_thread_get_board_name(h_searched_thread);
986         assert(board_name);
987         
988         dat_name = nt_searched_thread_get_dat_name(h_searched_thread);
989         title = nt_searched_thread_get_title(h_searched_thread);
990         
991         h_board = nt_get_board_by_name(
992                         h_model, board_name, &h_category);
993         if(!h_board || !h_category){
994                 *errorpp = L"板情報が見つかりませんでした";
995                 nt_2ch_selected_item_release_ref(h_sel_item);
996                 return FALSE;
997         }
998         nt_set_selected_board(h_sel_item, h_category, h_board);
999         
1000         
1001         h_enum = nt_board_get_thread_enum(h_board);
1002         if(!h_enum){
1003                 if(!nt_read_board(h_sel_item)){
1004                         *errorpp = L"板が開けませんでした";
1005                         goto ERROR_TRAP;
1006                 }
1007                 h_enum = nt_board_get_thread_enum(h_board);
1008                 if(!h_enum){
1009                         *errorpp = L"板が開けませんでした";
1010                         goto ERROR_TRAP;
1011                 }
1012         }
1013         
1014         nt_enum_unset(h_enum);
1015         
1016         if(!dat_name){
1017                 nt_board_release_ref(h_board);
1018                 nt_category_release_ref(h_category);
1019                 *h_sel_itemp = h_sel_item;
1020                 return TRUE;
1021         }
1022         h_thread = nt_get_thread_by_dat_name(h_board, dat_name);
1023         if(!h_thread){
1024                 if(!title)
1025                         h_thread = nt_thread_dummy_alloc(L"Dummy", dat_name, 0);
1026                 else
1027                         h_thread = nt_thread_dummy_alloc(title, dat_name, 0);
1028                 if(!h_thread){
1029                         *errorpp = L"スレッド情報が見つかりませんでした";
1030                         goto ERROR_TRAP;
1031                 }
1032         }
1033         
1034         nt_set_selected_thread(h_sel_item, h_thread);
1035         
1036         if(!nt_read_thread(h_sel_item)){
1037                 *errorpp = L"スレッドが開けませんでした";
1038                 goto ERROR_TRAP;
1039         }
1040         if(!title){
1041                 cptr = nt_read_thread_title(h_board, dat_name);
1042                 if(cptr){
1043                         nt_thread_set_title(h_thread, cptr);
1044                         free(cptr);
1045                 }
1046         }
1047         
1048         nt_thread_release_ref(h_thread);
1049         nt_board_release_ref(h_board);
1050         nt_category_release_ref(h_category);
1051         *h_sel_itemp = h_sel_item;
1052         return TRUE;
1053 ERROR_TRAP:
1054         if(h_thread)
1055                 nt_thread_release_ref(h_thread);
1056         nt_board_release_ref(h_board);
1057         nt_category_release_ref(h_category);
1058         nt_2ch_selected_item_release_ref(h_sel_item);
1059         return FALSE;
1060 }
1061