OSDN Git Service

sync read count of threads.
[ntch/develop.git] / src / _2ch / _2ch.c
1 /* Copyright 2013 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;
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         while(1){
266                 if(feof(fp_src))
267                         break;
268                 s_src[0] = '\0';
269                 if(!fgets(s_src, S_SIZE, fp_src))
270                         break;
271                 p_src = s_src;
272                 p_dst = s_dst;
273
274                 n_src   =       strlen(s_src);
275                 n_dst   =       sizeof(s_dst)-1;
276                 while(0 < n_src){
277                         size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
278                         if(sz == -1){
279                                 //fprintf(stderr, "errno: %d %s\n", errno, s_src);
280                                 break;
281                         }
282                 }
283                 *((wchar_t*)p_dst) = L'\0';
284                 if(!is_matchi_bbs)
285                         parse_thread(&threadp->handle, (const wchar_t*)s_dst);
286                 else
287                         parse_thread_machi_bbs(&threadp->handle, (const wchar_t*)s_dst);
288         }
289
290         fclose(fp_src);
291         iconv_close(icd);
292         free(outp);
293         h_cloud = nt_cloud_get_handle();
294         if(h_cloud && threadp->num_res > 0){
295                 nt_cloud_update_read_count_async(h_cloud,
296                                 boardp->name, file_name, threadp->num_res);
297         }
298         if(h_cloud)
299                 nt_cloud_release_ref(h_cloud);
300         return (threadp->num_res > 0);
301 }
302
303 wchar_t* nt_read_thread_title(nt_board_handle h_board,
304                 const wchar_t *dat_name)
305 {
306         nt_board_tp boardp;
307         wchar_t url[1024];
308         char    *outp;
309         wchar_t *title;
310         int len;
311         iconv_t icd;
312         FILE    *fp_src;
313         char    s_src[S_SIZE*sizeof(wchar_t)];
314         char    s_dst[S_SIZE*sizeof(wchar_t)];
315         char    *p_src, *p_dst;
316         size_t  n_src,  n_dst;
317         
318         assert(h_board);
319         assert(h_board->chk_sum == NT_2CH_BOARD_CHK_SUM);
320         boardp = (nt_board_tp)h_board;
321
322         memset(s_src, '\0', sizeof(s_src));
323         memset(s_dst, '\0', sizeof(s_dst));
324         title = NULL;
325
326         wcscpy(url, boardp->address);
327         len = wcslen(url);
328         if(len <= 0)
329                 return NULL;
330         if(url[len-1] != L'/'){
331                 url[len] = L'/';
332                 len++;
333                 url[len] = L'\0';
334         }
335         wcscat(url, L"dat/");
336         wcscat(url, dat_name);
337
338
339         len = wcstombs(s_src, url, sizeof(s_src)-1);
340         if(len <= 0)
341                 return NULL;
342         if(!nt_make_sha1_path(LOG_PATH, s_src, &outp)){
343                 return  NULL;
344         }
345
346         fp_src = fopen(outp, "r");
347         if(!fp_src){
348                 free(outp);
349                 return NULL;
350         }
351         icd     =       iconv_open("wchar_t", "cp932");
352         if(((iconv_t)-1) == icd){
353                 fclose(fp_src);
354                 free(outp);
355                 return NULL;
356         }
357         if(!feof(fp_src)){
358                 s_src[0] = '\0';
359                 if(!fgets(s_src, S_SIZE, fp_src)){
360                         iconv_close(icd);
361                         fclose(fp_src);
362                         free(outp);
363                         return NULL;
364                 }
365                 p_src = s_src;
366                 p_dst = s_dst;
367
368                 n_src   =       strlen(s_src);
369                 n_dst   =       sizeof(s_dst)-1;
370                 while(0 < n_src){
371                         size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
372                         if(sz == -1){
373                                 //fprintf(stderr, "errno: %d %s\n", errno, s_src);
374                                 break;
375                         }
376                 }
377                 *((wchar_t*)p_dst) = L'\0';
378                 title = parse_thread_title((const wchar_t*)s_dst);
379         }
380         fclose(fp_src);
381         iconv_close(icd);
382         free(outp);
383         return title;
384 }
385
386 BOOL nt_read_board(nt_2ch_selected_item_handle h_select)
387 {
388         nt_2ch_selected_item_tp selectp;
389         wchar_t *address;
390         char data[256+1];
391         iconv_t icd;
392         char *outp;
393         int len;
394         FILE    *fp_src;
395         char    s_src[S_SIZE],  s_dst[S_SIZE*sizeof(wchar_t)];
396         char    *p_src, *p_dst;
397         size_t  n_src,  n_dst;
398         nt_board_tp boardp;
399         nt_mutex_handle h_mutex;
400
401         assert(h_select);
402         assert(h_select->chk_sum == NT_2CH_SELECTED_ITEM_CHK_SUM);
403         
404         selectp = (nt_2ch_selected_item_tp)h_select;
405         
406         memset(data, 0, sizeof(data));
407         memset(s_src, '\0', S_SIZE);
408         memset(s_dst, '\0', S_SIZE*sizeof(wchar_t));
409         //fputs("enter nt_read_board\n",stderr);
410         if(!selectp->selected_categoryp)
411                 return FALSE;
412         if(!selectp->selected_boardp)
413                 return FALSE;
414         
415         boardp = selectp->selected_boardp;
416         //fwprintf(stderr, L"%ls\n", boardp->name);
417         h_mutex = nt_board_get_mutex(&boardp->handle);
418         if(!h_mutex)
419                 return FALSE;
420         if(!nt_mutex_lock(h_mutex))
421                 return FALSE;
422         //fputs(" -- lock nt_read_board\n",stderr);
423
424         nt_board_clear_children(&boardp->handle);
425         address = boardp->address;
426         assert(address);
427
428         len = wcstombs(data, address, sizeof(data)-1);
429         if(len <= 0){
430                 nt_mutex_unlock(h_mutex);
431                 return FALSE;
432         }
433
434         if(data[len-1] != '/')
435                 strcat(data, "/");
436         strcat(data, "subject.txt");
437
438
439         if(!nt_make_sha1_path(LOG_PATH, data, &outp)){
440                 nt_mutex_unlock(h_mutex);
441                 return  FALSE;
442         }
443
444         if(!nt_http_get(data, outp, URL_2CH_BOARDMENU, NULL, NULL, FALSE, FALSE)){
445                 free(outp);
446                 nt_mutex_unlock(h_mutex);
447                 return FALSE;
448         }
449
450         fp_src = fopen(outp, "r");
451         if(!fp_src){
452                 free(outp);
453                 nt_mutex_unlock(h_mutex);
454                 return FALSE;
455         }
456         icd     =       iconv_open("wchar_t", "cp932");
457         if(((iconv_t)-1) == icd){
458                 fclose(fp_src);
459                 free(outp);
460                 nt_mutex_unlock(h_mutex);
461                 return FALSE;
462         }
463         while(1){
464                 if(feof(fp_src))
465                         break;
466                 s_src[0] = '\0';
467                 if(!fgets(s_src, S_SIZE, fp_src))
468                         break;
469                 p_src = s_src;
470                 p_dst = s_dst;
471
472                 n_src   =       strlen(s_src);
473                 n_dst   =       (S_SIZE-1)*sizeof(wchar_t);
474                 while(0 <       n_src){
475                         size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
476                         if(sz == -1){
477                                 //fprintf(stderr, "errno: %d %s\n", errno, s_src);
478                                 break;
479                         }
480                 }
481                 *((wchar_t*)p_dst) = L'\0';
482                 if(!parse_board(&boardp->handle, (const wchar_t*)s_dst)){
483                 }
484         }
485         fclose(fp_src);
486         iconv_close(icd);
487         
488         //fputs(" -- unlock nt_read_board\n",stderr);
489         nt_mutex_unlock(h_mutex);
490         //fputs("exit nt_read_board\n",stderr);
491         free(outp);
492         if(!boardp->threadlistp)
493                 return FALSE;
494         return TRUE;
495 }
496
497 BOOL nt_write_msg(nt_2ch_selected_item_handle h_select, nt_write_data_handle h_write_data,
498                         nt_cookie_tp cookiep, nt_maru_2ch_tp marup)
499 {
500         nt_2ch_selected_item_tp selectp;
501         nt_write_data_tp writep;
502         wchar_t url[1024];      
503         wchar_t referer[1024];
504         char    post_data[1024*4];
505         wchar_t buf[512];
506         char    out_buf[1024*4];
507         wchar_t *dat_name;
508         wchar_t *file_name;
509         wchar_t *server_name,   *board_name;
510         nt_board_tp     boardp;
511         nt_thread_tp    threadp;
512         int     len;
513         char    s_src[S_SIZE*sizeof(wchar_t)];
514         char    s_dst[S_SIZE*sizeof(wchar_t)];
515         BOOL result = FALSE;
516         iconv_t icd = 0;
517
518         assert(h_select);
519         assert(h_select->chk_sum == NT_2CH_SELECTED_ITEM_CHK_SUM);
520         assert(h_write_data);
521         assert(h_write_data->chk_sum == NT_2CH_WRITE_DATA_CHK_SUM);
522         
523         selectp = (nt_2ch_selected_item_tp)h_select;
524         writep = (nt_write_data_tp)h_write_data;
525         
526         memset(s_src,   '\0',   sizeof(s_src));
527         memset(s_dst,   '\0',   sizeof(s_dst));
528         memset(post_data,       '\0',   sizeof(post_data));
529
530         if(!selectp->selected_categoryp)
531                 return  FALSE;
532         if(!selectp->selected_boardp)
533                 return  FALSE;
534         if(!selectp->selected_threadp)
535                 return  FALSE;
536
537         boardp = selectp->selected_boardp;
538         threadp = selectp->selected_threadp;
539         file_name = threadp->file_name;
540
541         if(!nt_parse_server_name_and_board_name(boardp->address,
542                 buf, sizeof(buf), &server_name, &board_name)){
543                 return FALSE;
544         }
545
546         if(is_machibbs_address(server_name)){
547                 return nt_write_msg_machibbs(selectp, writep, cookiep);
548         }
549         
550         wcscpy(url, L"http://");
551         wcscat(url, server_name);
552         wcscat(url, L"/test/bbs.cgi");
553         
554         wcscpy(referer, L"http://");
555         wcscat(referer, server_name);
556         wcscat(referer, L"/test/read.cgi/");
557         wcscat(referer, board_name);
558         wcscat(referer, L"/");
559         dat_name = nt_rid_sufix(file_name);
560         if(!dat_name)
561                 return FALSE;
562         wcscat(referer, dat_name);
563         wcscat(referer, L"/");
564
565         len = wcstombs(s_src, url, sizeof(s_src)-1);
566         if(len <= 0)
567                 goto ERROR_TRAP;
568         len = wcstombs(s_dst, referer, sizeof(s_dst)-1);
569         if(len <= 0)
570                 goto ERROR_TRAP;
571         if(!set_post_data(post_data, sizeof(post_data),
572                         board_name, dat_name, writep->name,
573                         writep->mail, writep->msg)){
574                 goto ERROR_TRAP;
575         }
576         strcat(post_data, "&yuki=akari");
577
578         if(marup && marup->sid){
579                 strcat(post_data, "&sid=");
580                 strcat(post_data, marup->sid);
581         }
582         if(!nt_http_post(s_src, post_data, out_buf, sizeof(out_buf),
583                     s_dst, NULL, NULL, cookiep)){
584                 goto ERROR_TRAP;
585         }
586         icd =   iconv_open("wchar_t", "cp932");
587         if(((iconv_t)-1) == icd){
588                 icd = 0;
589                 goto ERROR_TRAP;
590         }
591         if(writep->result_html)
592                 free(writep->result_html);
593         writep->result_html = malloc(1024*sizeof(wchar_t)*4);
594         if(!writep->result_html)
595                 goto ERROR_TRAP;
596
597         if(!nt_conv_sjis2wc(icd, out_buf, writep->result_html, 
598                                 1024*sizeof(wchar_t)*4)){
599                 goto ERROR_TRAP;
600         }
601         result = TRUE;
602 ERROR_TRAP:
603         if(icd)
604                 iconv_close(icd);
605         free(dat_name);
606         return (result);
607 }
608
609
610 static BOOL nt_write_msg_machibbs(nt_2ch_selected_item_tp selectp, 
611                         nt_write_data_tp writep, nt_cookie_tp cookiep)
612 {
613         wchar_t url[1024];      
614         wchar_t referer[1024];
615         char    post_data[1024*4];
616         wchar_t buf[512];
617         char    out_buf[1024*4];
618         wchar_t *dat_name;
619         wchar_t *file_name;
620         wchar_t *server_name,   *board_name;
621         nt_board_tp     boardp;
622         nt_thread_tp    threadp;
623         int     len;
624         char    s_src[S_SIZE*sizeof(wchar_t)];
625         char    s_dst[S_SIZE*sizeof(wchar_t)];
626         BOOL result = FALSE;
627         iconv_t icd = 0;
628
629         memset(s_src,   '\0',   sizeof(s_src));
630         memset(s_dst,   '\0',   sizeof(s_dst));
631         memset(post_data,       '\0',   sizeof(post_data));
632
633         if(!selectp->selected_categoryp)
634                 return  FALSE;
635         if(!selectp->selected_boardp)
636                 return  FALSE;
637         if(!selectp->selected_threadp)
638                 return  FALSE;
639
640         boardp = selectp->selected_boardp;
641         threadp = selectp->selected_threadp;
642         file_name = threadp->file_name;
643
644         if(!nt_parse_server_name_and_board_name(boardp->address,
645                 buf, sizeof(buf), &server_name, &board_name)){
646                 return FALSE;
647         }
648
649         
650         wcscpy(url, L"http://");
651         wcscat(url, server_name);
652         wcscat(url, L"/bbs/write.cgi");
653         dat_name = nt_rid_sufix(file_name);
654         if(!dat_name)
655                 return FALSE;
656         
657         wcscpy(referer, boardp->address);
658
659         len = wcstombs(s_src, url, sizeof(s_src)-1);
660         if(len <= 0)
661                 goto ERROR_TRAP;
662         len = wcstombs(s_dst, referer, sizeof(s_dst)-1);
663         if(len <= 0)
664                 goto ERROR_TRAP;
665         if(!set_post_data_machibbs(post_data, sizeof(post_data),
666                         board_name, dat_name, writep->name,
667                         writep->mail, writep->msg)){
668                 goto ERROR_TRAP;
669         }
670         len = wcstombs(s_src, url, sizeof(s_src)-1);
671         if(len <= 0)
672                 goto ERROR_TRAP;
673         strcat(post_data, "&CC=%82%A0");
674         
675         if(!nt_http_post(s_src, post_data, out_buf, sizeof(out_buf),
676                     s_dst, NULL, NULL, cookiep)){
677                 goto ERROR_TRAP;
678         }
679         icd =   iconv_open("wchar_t", "cp932");
680         if(((iconv_t)-1) == icd){
681                 icd = 0;
682                 goto ERROR_TRAP;
683         }
684         if(writep->result_html)
685                 free(writep->result_html);
686         writep->result_html = malloc(1024*sizeof(wchar_t)*4);
687         if(!writep->result_html)
688                 goto ERROR_TRAP;
689
690         if(!nt_conv_sjis2wc(icd, out_buf, writep->result_html, 
691                                 1024*sizeof(wchar_t)*4)){
692                 goto ERROR_TRAP;
693         }
694         result = TRUE;
695 ERROR_TRAP:
696         if(icd)
697                 iconv_close(icd);
698         free(dat_name);
699         return (result);
700 }
701
702
703
704 static BOOL set_post_data(char *data, size_t data_len,
705                 const wchar_t *bbs, const wchar_t *id, 
706                 const char *name, const char *mail, 
707                 const char *msg)
708 {
709         iconv_t icd;
710         time_t t;
711         char buf[1024*4];
712         char buf2[1024*4];
713         char *cptr;
714         assert(bbs && id && name && mail && msg);
715
716         memset(buf, 0, sizeof(buf));
717         memset(buf2, 0, sizeof(buf2));
718
719         icd =   iconv_open("cp932", "wchar_t");
720         if(((iconv_t)-1) == icd){
721             return FALSE;
722         }
723         t =  time(NULL);
724         t -= 600;
725
726         cptr = data;
727         strcpy(cptr, "bbs=");
728         cptr += strlen(data);
729         if(!nt_conv_wc2sjis(icd, bbs, buf, sizeof(buf)))
730                 return FALSE;
731         strcpy(cptr, buf);
732         cptr+= strlen(cptr);
733         strcpy(cptr, "&key=");
734         cptr += strlen(cptr);
735         if(!nt_conv_wc2sjis(icd, id, buf, sizeof(buf)))
736                 return FALSE;
737         strcpy(cptr, buf);
738         cptr+= strlen(cptr);
739         strcpy(cptr, "&time=");
740         cptr += strlen(cptr);
741         sprintf(buf, "%ld&FROM=", t);
742         strcpy(cptr, buf);
743         cptr+= strlen(cptr);
744
745         iconv_close(icd);
746
747         icd =   iconv_open("cp932", "UTF-8");
748         if(icd == (iconv_t)-1){
749                 perror("e");
750                 return FALSE;
751         }
752
753         if(name && 0 < strlen(name)){
754                 if(!nt_conv_local2sjis(icd, name, buf, sizeof(buf)))
755                         return FALSE;
756                 if(!url_encode(buf, buf2, sizeof(buf2)))
757                         return FALSE;
758                 strcpy(cptr, buf2);
759                 cptr += strlen(buf2);
760         }
761         strcpy(cptr, "&mail=");
762         cptr += strlen(cptr);
763         if(mail && 0 < strlen(mail)){
764                 if(!nt_conv_local2sjis(icd, mail, buf, sizeof(buf)))
765                         return FALSE;
766                 if(!url_encode(buf, buf2, sizeof(buf2)))
767                         return FALSE;
768                 strcpy(cptr, buf2);
769                 cptr += strlen(buf2);
770         }
771         strcpy(cptr, "&MESSAGE=");
772         cptr += strlen(cptr);
773         if(msg && 0 < strlen(msg)){
774                 if(!nt_conv_local2sjis(icd, msg, buf, sizeof(buf)))
775                         return FALSE;
776                 if(!url_encode(buf, buf2, sizeof(buf2)))
777                         return FALSE;
778                 strcpy(cptr, buf2);
779                 cptr += strlen(buf2);
780         }
781         strcpy(cptr, "&submit=%8F%91%82%AB%8D%9E%82%DE");
782
783         iconv_close(icd);
784         
785         return TRUE;
786 }
787
788 static BOOL set_post_data_machibbs(char *data, size_t data_len,
789                 const wchar_t *bbs, const wchar_t *id, 
790                 const char *name, const char *mail, 
791                 const char *msg)
792 {
793         iconv_t icd;
794         time_t t;
795         char buf[1024*4];
796         char buf2[1024*4];
797         char *cptr;
798         assert(bbs && id && name && mail && msg);
799
800         memset(buf, 0, sizeof(buf));
801         memset(buf2, 0, sizeof(buf2));
802
803         icd =   iconv_open("cp932", "wchar_t");
804         if(((iconv_t)-1) == icd){
805             return FALSE;
806         }
807         t =  time(NULL);
808         t -= 600;
809
810         cptr = data;
811         strcpy(cptr, "BBS=");
812         cptr += strlen(data);
813         if(!nt_conv_wc2sjis(icd, bbs, buf, sizeof(buf)))
814                 return FALSE;
815         strcpy(cptr, buf);
816         cptr+= strlen(cptr);
817         strcpy(cptr, "&KEY=");
818         cptr += strlen(cptr);
819         if(!nt_conv_wc2sjis(icd, id, buf, sizeof(buf)))
820                 return FALSE;
821         strcpy(cptr, buf);
822         cptr+= strlen(cptr);
823         strcpy(cptr, "&TIME=");
824         cptr += strlen(cptr);
825         sprintf(buf, "%ld&NAME=", t);
826         strcpy(cptr, buf);
827         cptr+= strlen(cptr);
828
829         iconv_close(icd);
830
831         icd =   iconv_open("cp932", "UTF-8");
832         if(icd == (iconv_t)-1){
833                 perror("e");
834                 return FALSE;
835         }
836
837         if(name && 0 < strlen(name)){
838                 if(!nt_conv_local2sjis(icd, name, buf, sizeof(buf)))
839                         return FALSE;
840                 if(!url_encode(buf, buf2, sizeof(buf2)))
841                         return FALSE;
842                 strcpy(cptr, buf2);
843                 cptr += strlen(buf2);
844         }
845         strcpy(cptr, "&MAIL=");
846         cptr += strlen(cptr);
847         if(mail && 0 < strlen(mail)){
848                 if(!nt_conv_local2sjis(icd, mail, buf, sizeof(buf)))
849                         return FALSE;
850                 if(!url_encode(buf, buf2, sizeof(buf2)))
851                         return FALSE;
852                 strcpy(cptr, buf2);
853                 cptr += strlen(buf2);
854         }
855         strcpy(cptr, "&MESSAGE=");
856         cptr += strlen(cptr);
857         if(msg && 0 < strlen(msg)){
858                 if(!nt_conv_local2sjis(icd, msg, buf, sizeof(buf)))
859                         return FALSE;
860                 if(!url_encode(buf, buf2, sizeof(buf2)))
861                         return FALSE;
862                 strcpy(cptr, buf2);
863                 cptr += strlen(buf2);
864         }
865         strcpy(cptr, "&submit=%8F%91%82%AB%8D%9E%82%DE");
866
867         iconv_close(icd);
868         
869         return TRUE;
870 }
871
872 static BOOL set_offlaw_address(char *buf, size_t buf_len,
873                         wchar_t *server_name, 
874                         wchar_t * board_name, wchar_t *dat_name)
875 {
876         wchar_t *cptr;
877         int len;
878         wchar_t url[512];
879
880         cptr = wcsstr(server_name, L".2ch.net");
881         if(!cptr)
882                 return FALSE;
883         cptr = wcsstr(dat_name, L".dat");
884         if(!cptr)
885                 return FALSE;
886         cptr = nt_rid_sufix(dat_name);
887         if(!cptr)
888                 return FALSE;
889         wcscpy(url, L"http://");
890         wcscat(url, server_name);
891         wcscat(url, L"/test/offlaw2.so?shiro=kuma&sid=ERROR&bbs=");
892         wcscat(url, board_name);
893         wcscat(url, L"&key=");
894         wcscat(url, cptr);
895         free(cptr);
896         len = wcstombs(buf, url, buf_len-1);
897         if(len <= 0)
898                 return FALSE;
899         return TRUE;
900 }
901
902 int nt_read_board_list(nt_link_tp selitem_list)
903 {
904         nt_2ch_selected_item_handle h_select;
905         nt_link_tp linkp;
906         int num_success;
907         nt_pthread_handle h_pthread;
908         
909         assert(selitem_list);
910         num_success = 0;
911         linkp = selitem_list;
912         do{
913                 h_select = (nt_2ch_selected_item_handle)linkp->data;
914 #ifdef NT_DISABLE_PTHREAD
915                 if(nt_read_board(h_select))
916                         num_success++;
917 #else
918                 nt_2ch_selected_item_add_ref(h_select);
919                 h_pthread = nt_pthread_alloc(
920                                 nt_read_board_async,
921                                 h_select,
922                                 nt_read_board_async_result);
923                 if(!h_pthread){
924                         nt_2ch_selected_item_release_ref(h_select);
925                 }else if(!nt_pthread_put_que(h_pthread)){
926                         nt_pthread_release_ref(h_pthread);
927                         nt_2ch_selected_item_release_ref(h_select);
928                 }else{
929                         nt_pthread_release_ref(h_pthread);
930                         num_success++;
931                 }
932 #endif
933                 linkp = linkp->next;
934         }while(linkp != selitem_list);
935         return num_success;
936 }
937
938 static nt_pthread_result_t nt_read_board_async(void* data)
939 {
940         nt_2ch_selected_item_handle h_select;
941         nt_pthread_result_t result;
942         
943         result.code = NT_PTHREAD_RESULT_NONE;
944         result.data = NULL;
945         
946         h_select = (nt_2ch_selected_item_handle)data;
947         nt_2ch_selected_item_add_ref(h_select);
948         nt_2ch_selected_item_release_ref(h_select);
949         
950         if(nt_read_board(h_select)){
951                 result.code = NT_PTHREAD_RESULT_UPDATE_BOARD;
952         }
953         nt_2ch_selected_item_release_ref(h_select);
954         return result;
955 }
956
957 static nt_pthread_result_t nt_read_board_async_result(
958                         nt_pthread_result_t result)
959 {
960         return result;
961 }
962
963 BOOL nt_set_sel_item(nt_2ch_model_handle h_model,
964                         nt_2ch_selected_item_handle *h_sel_itemp, 
965                         nt_searched_thread_handle h_searched_thread, const wchar_t** errorpp)
966 {
967         const wchar_t *board_name, *dat_name, *title;
968         nt_category_handle h_category;
969         nt_board_handle h_board;
970         nt_thread_handle h_thread;
971         nt_2ch_selected_item_handle h_sel_item;
972         nt_enum_handle h_enum;
973         
974         assert(h_sel_itemp);
975         
976         h_sel_item = nt_2ch_selected_item_alloc();
977         if(!h_sel_item){
978                 return FALSE;
979         }
980         board_name = nt_searched_thread_get_board_name(h_searched_thread);
981         assert(board_name);
982         
983         dat_name = nt_searched_thread_get_dat_name(h_searched_thread);
984         title = nt_searched_thread_get_title(h_searched_thread);
985         
986         h_board = nt_get_board_by_name(
987                         h_model, board_name, &h_category);
988         if(!h_board || !h_category){
989                 *errorpp = L"板情報が見つかりませんでした";
990                 nt_2ch_selected_item_release_ref(h_sel_item);
991                 return FALSE;
992         }
993         nt_set_selected_board(h_sel_item, h_category, h_board);
994         
995         
996         h_enum = nt_board_get_thread_enum(h_board);
997         if(!h_enum){
998                 if(!nt_read_board(h_sel_item)){
999                         *errorpp = L"板が開けませんでした";
1000                         goto ERROR_TRAP;
1001                 }
1002                 h_enum = nt_board_get_thread_enum(h_board);
1003                 if(!h_enum){
1004                         *errorpp = L"板が開けませんでした";
1005                         goto ERROR_TRAP;
1006                 }
1007         }
1008         
1009         nt_enum_unset(h_enum);
1010         
1011         if(!dat_name){
1012                 nt_board_release_ref(h_board);
1013                 nt_category_release_ref(h_category);
1014                 *h_sel_itemp = h_sel_item;
1015                 return TRUE;
1016         }
1017         h_thread = nt_get_thread_by_dat_name(h_board, dat_name);
1018         if(!h_thread){
1019                 if(!title)
1020                         title = L"Dummy";
1021                 h_thread = nt_thread_dummy_alloc(title, dat_name, 0);
1022                 if(!h_thread){
1023                         *errorpp = L"スレッド情報が見つかりませんでした";
1024                         goto ERROR_TRAP;
1025                 }
1026         }
1027         
1028         nt_set_selected_thread(h_sel_item, h_thread);
1029         nt_thread_release_ref(h_thread);
1030         
1031         if(!nt_read_thread(h_sel_item)){
1032                 *errorpp = L"スレッドが開けませんでした";
1033                 goto ERROR_TRAP;
1034         }
1035         
1036         nt_board_release_ref(h_board);
1037         nt_category_release_ref(h_category);
1038         *h_sel_itemp = h_sel_item;
1039         return TRUE;
1040 ERROR_TRAP:
1041         nt_board_release_ref(h_board);
1042         nt_category_release_ref(h_category);
1043         nt_2ch_selected_item_release_ref(h_sel_item);
1044         return FALSE;
1045 }
1046