OSDN Git Service

sync read count of threads.
[ntch/develop.git] / src / _2ch / _2ch.c
index b8a6ff5..d9a991a 100644 (file)
 #include <errno.h>
 #include <time.h>
 
+#define MODEL_2CH_PRIVATE_DATA
+
 #include "env.h"
 #include "utils/nt_std_t.h"
 #include "utils/nt_conv_char.h"
 #include "utils/file.h"
 #include "utils/base64.h"
+#include "utils/nt_pthread.h"
+#include "cloud/nt_cloud.h"
 #include "net/nt_http.h"
 #include "net/nt_cookie.h"
 #include "_2ch/model_2ch.h"
 #include "_2ch/_2ch.h"
 
 char *URL_2CH_BOARDMENU = "http://menu.2ch.net/bbsmenu.html";
-nt_2ch_model_tp app_2ch_modelp;
+nt_2ch_model_handle app_2ch_model;
 
 
 #define S_SIZE  (1024*2)
@@ -45,13 +49,24 @@ static BOOL set_post_data(char *data, size_t data_len,
                const wchar_t *bbs, const wchar_t *id, 
                const char *name, const char *mail, 
                const char *msg);
+static BOOL set_post_data_machibbs(char *data, size_t data_len,
+               const wchar_t *bbs, const wchar_t *id, 
+               const char *name, const char *mail, 
+               const char *msg);
 static BOOL set_offlaw_address(char *buf, size_t buf_len,
                        wchar_t *server_name, 
                        wchar_t * board_name, wchar_t *dat_name);
+static BOOL nt_write_msg_machibbs(nt_2ch_selected_item_tp selectp,
+                        nt_write_data_tp writep, nt_cookie_tp cookiep);
+
+static nt_pthread_result_t nt_read_board_async(void* data);
+static nt_pthread_result_t nt_read_board_async_result(
+                       nt_pthread_result_t result);
 
+                   
 BOOL nt_2ch_model_init(){
-       app_2ch_modelp = nt_2ch_model_alloc();
-       return (NULL != app_2ch_modelp);
+       app_2ch_model = nt_2ch_model_alloc();
+       return (NULL != app_2ch_model);
 }
 
 BOOL nt_init_board_menu()
@@ -72,7 +87,7 @@ BOOL nt_init_board_menu()
        }
 
 
-       if(!nt_http_get(url, outp, NULL, NULL, NULL, FALSE)){
+       if(!nt_http_get(url, outp, NULL, NULL, NULL, FALSE, FALSE)){
                free(outp);
                return FALSE;
        }
@@ -91,7 +106,8 @@ BOOL nt_init_board_menu()
                if(feof(fp_src))
                        break;
                s_src[0] = '\0';
-               fgets(s_src, S_SIZE, fp_src);
+               if(!fgets(s_src, S_SIZE, fp_src))
+                       break;
                p_src = s_src;
                p_dst = s_dst;
 
@@ -106,7 +122,7 @@ BOOL nt_init_board_menu()
                }
                //*p_dst        =       '\0';
                *((wchar_t*)p_dst) = L'\0';
-               parse_board_menu(app_2ch_modelp, (const wchar_t*)s_dst);
+               parse_board_menu(app_2ch_model, (const wchar_t*)s_dst);
        }
 
        if(fp_src)
@@ -118,8 +134,16 @@ BOOL nt_init_board_menu()
        return TRUE;
 }
 
-BOOL nt_read_thread(nt_2ch_model_tp modelp)
+static BOOL is_machibbs_address(const wchar_t *host_name)
 {
+       wchar_t *cptr;
+       cptr = wcsstr(host_name, L".machi.to");
+       return (cptr != NULL) ? TRUE : FALSE;
+}
+
+BOOL nt_read_thread(nt_2ch_selected_item_handle h_select)
+{
+       nt_2ch_selected_item_tp selectp;
        wchar_t url[1024];
        wchar_t referer[1024];
        wchar_t buf[1024];
@@ -135,50 +159,75 @@ BOOL nt_read_thread(nt_2ch_model_tp modelp)
        char    s_dst[S_SIZE*sizeof(wchar_t)];
        char    *p_src, *p_dst;
        size_t  n_src,  n_dst;
+       BOOL is_matchi_bbs;
+       nt_cloud_handle h_cloud;
+       
+       assert(h_select);
+       assert(h_select->chk_sum == NT_2CH_SELECTED_ITEM_CHK_SUM);
+       
+       selectp = (nt_2ch_selected_item_tp)h_select;
 
        memset(s_src, '\0', sizeof(s_src));
        memset(s_dst, '\0', sizeof(s_dst));
 
 
-       if(!modelp->selected_categoryp)
+       if(!selectp->selected_categoryp)
                return FALSE;
-       if(!modelp->selected_boardp)
+       if(!selectp->selected_boardp)
                return FALSE;
-       if(!modelp->selected_threadp)
+       if(!selectp->selected_threadp)
                return FALSE;
 
-       boardp = modelp->selected_boardp;
-       threadp = modelp->selected_threadp;
+       boardp = selectp->selected_boardp;
+       threadp = selectp->selected_threadp;
        file_name = threadp->file_name;
 
-       wcscpy(url, boardp->address);
-       len = wcslen(url);
-       if(len <= 0)
-               return FALSE;
-       if(url[len-1] != L'/'){
-               url[len] = L'/';
-               len++;
-               url[len] = L'\0';
-       }
-       wcscat(url, L"dat/");
-       wcscat(url, file_name);
 
        if(!nt_parse_server_name_and_board_name(boardp->address,
                buf, sizeof(buf), &server_name, &board_name)){
                return FALSE;
        }
-
-       wcscpy(referer, L"http://");
-       wcscat(referer, server_name);
-       wcscat(referer, L"/test/read.cgi/");
-       wcscat(referer, board_name);
-       wcscat(referer, L"/");
-       cptr = nt_rid_sufix(file_name);
-       if(!cptr)
-               return FALSE;
-       wcscat(referer, cptr);
-       free(cptr);
-       wcscat(referer, L"/");
+       if(is_machibbs_address(server_name)){
+               is_matchi_bbs = TRUE;
+               wcscpy(url, L"http://");
+               wcscat(url, server_name);
+               wcscat(url, L"/bbs/offlaw.cgi/");
+               wcscat(url, board_name);
+               wcscat(url, L"/");
+               cptr = nt_rid_sufix(file_name);
+               if(!cptr)
+                       return FALSE;
+               wcscat(url, cptr);
+               free(cptr);
+               wcscat(url, L"/");
+               
+               wcscpy(referer, boardp->address);
+               wcscat(referer, L"/");
+       }else{
+               is_matchi_bbs = FALSE;
+               wcscpy(url, boardp->address);
+               len = wcslen(url);
+               if(len <= 0)
+                       return FALSE;
+               if(url[len-1] != L'/'){
+                       url[len] = L'/';
+                       len++;
+                       url[len] = L'\0';
+               }
+               wcscat(url, L"dat/");
+               wcscat(url, file_name);
+               wcscpy(referer, L"http://");
+               wcscat(referer, server_name);
+               wcscat(referer, L"/test/read.cgi/");
+               wcscat(referer, board_name);
+               wcscat(referer, L"/");
+               cptr = nt_rid_sufix(file_name);
+               if(!cptr)
+                       return FALSE;
+               wcscat(referer, cptr);
+               free(cptr);
+               wcscat(referer, L"/");
+       }
        len = wcstombs(s_src, url, sizeof(s_src)-1);
        if(len <= 0)
                return FALSE;
@@ -189,13 +238,13 @@ BOOL nt_read_thread(nt_2ch_model_tp modelp)
                return  FALSE;
        }
 
-       if(!nt_http_get(s_src, outp, s_dst, NULL, NULL, TRUE)){
+       if(!nt_http_get(s_src, outp, s_dst, NULL, NULL, TRUE, FALSE)){
                if(!set_offlaw_address(s_src, sizeof(s_src),
                                server_name, board_name, file_name)){
                        free(outp);
                        return FALSE;
                }
-               if(!nt_http_get(s_src, outp, s_dst, NULL, NULL, FALSE)){
+               if(!nt_http_get(s_src, outp, s_dst, NULL, NULL, FALSE, FALSE)){
                        free(outp);
                        return FALSE;
                }
@@ -211,13 +260,14 @@ BOOL nt_read_thread(nt_2ch_model_tp modelp)
                free(outp);
                return FALSE;
        }
-       nt_thread_children_free(threadp);
+       nt_thread_clear_children(&threadp->handle);
        threadp->num_res = 0;
        while(1){
                if(feof(fp_src))
                        break;
                s_src[0] = '\0';
-               fgets(s_src, S_SIZE, fp_src);
+               if(!fgets(s_src, S_SIZE, fp_src))
+                       break;
                p_src = s_src;
                p_dst = s_dst;
 
@@ -231,18 +281,29 @@ BOOL nt_read_thread(nt_2ch_model_tp modelp)
                        }
                }
                *((wchar_t*)p_dst) = L'\0';
-               parse_thread(threadp, (const wchar_t*)s_dst);
+               if(!is_matchi_bbs)
+                       parse_thread(&threadp->handle, (const wchar_t*)s_dst);
+               else
+                       parse_thread_machi_bbs(&threadp->handle, (const wchar_t*)s_dst);
        }
 
        fclose(fp_src);
        iconv_close(icd);
        free(outp);
+       h_cloud = nt_cloud_get_handle();
+       if(h_cloud && threadp->num_res > 0){
+               nt_cloud_update_read_count_async(h_cloud,
+                               boardp->name, file_name, threadp->num_res);
+       }
+       if(h_cloud)
+               nt_cloud_release_ref(h_cloud);
        return (threadp->num_res > 0);
 }
 
-wchar_t* nt_read_thread_title(nt_board_tp boardp,
+wchar_t* nt_read_thread_title(nt_board_handle h_board,
                const wchar_t *dat_name)
 {
+       nt_board_tp boardp;
        wchar_t url[1024];
        char    *outp;
        wchar_t *title;
@@ -253,14 +314,19 @@ wchar_t* nt_read_thread_title(nt_board_tp boardp,
        char    s_dst[S_SIZE*sizeof(wchar_t)];
        char    *p_src, *p_dst;
        size_t  n_src,  n_dst;
+       
+       assert(h_board);
+       assert(h_board->chk_sum == NT_2CH_BOARD_CHK_SUM);
+       boardp = (nt_board_tp)h_board;
 
        memset(s_src, '\0', sizeof(s_src));
        memset(s_dst, '\0', sizeof(s_dst));
+       title = NULL;
 
        wcscpy(url, boardp->address);
        len = wcslen(url);
        if(len <= 0)
-               return FALSE;
+               return NULL;
        if(url[len-1] != L'/'){
                url[len] = L'/';
                len++;
@@ -272,27 +338,30 @@ wchar_t* nt_read_thread_title(nt_board_tp boardp,
 
        len = wcstombs(s_src, url, sizeof(s_src)-1);
        if(len <= 0)
-               return FALSE;
+               return NULL;
        if(!nt_make_sha1_path(LOG_PATH, s_src, &outp)){
-               return  FALSE;
+               return  NULL;
        }
 
        fp_src = fopen(outp, "r");
        if(!fp_src){
                free(outp);
-               return FALSE;
+               return NULL;
        }
        icd     =       iconv_open("wchar_t", "cp932");
        if(((iconv_t)-1) == icd){
                fclose(fp_src);
                free(outp);
-               return FALSE;
+               return NULL;
        }
-       //nt_thread_children_free(threadp);
-       //threadp->num_res = 0;
        if(!feof(fp_src)){
                s_src[0] = '\0';
-               fgets(s_src, S_SIZE, fp_src);
+               if(!fgets(s_src, S_SIZE, fp_src)){
+                       iconv_close(icd);
+                       fclose(fp_src);
+                       free(outp);
+                       return NULL;
+               }
                p_src = s_src;
                p_dst = s_dst;
 
@@ -314,8 +383,9 @@ wchar_t* nt_read_thread_title(nt_board_tp boardp,
        return title;
 }
 
-BOOL nt_read_board(nt_2ch_model_tp modelp)
+BOOL nt_read_board(nt_2ch_selected_item_handle h_select)
 {
+       nt_2ch_selected_item_tp selectp;
        wchar_t *address;
        char data[256+1];
        iconv_t icd;
@@ -326,24 +396,40 @@ BOOL nt_read_board(nt_2ch_model_tp modelp)
        char    *p_src, *p_dst;
        size_t  n_src,  n_dst;
        nt_board_tp boardp;
+       nt_mutex_handle h_mutex;
 
+       assert(h_select);
+       assert(h_select->chk_sum == NT_2CH_SELECTED_ITEM_CHK_SUM);
+       
+       selectp = (nt_2ch_selected_item_tp)h_select;
+       
        memset(data, 0, sizeof(data));
        memset(s_src, '\0', S_SIZE);
        memset(s_dst, '\0', S_SIZE*sizeof(wchar_t));
-
-       if(!modelp->selected_categoryp)
+       //fputs("enter nt_read_board\n",stderr);
+       if(!selectp->selected_categoryp)
                return FALSE;
-       if(!modelp->selected_boardp)
+       if(!selectp->selected_boardp)
                return FALSE;
+       
+       boardp = selectp->selected_boardp;
+       //fwprintf(stderr, L"%ls\n", boardp->name);
+       h_mutex = nt_board_get_mutex(&boardp->handle);
+       if(!h_mutex)
+               return FALSE;
+       if(!nt_mutex_lock(h_mutex))
+               return FALSE;
+       //fputs(" -- lock nt_read_board\n",stderr);
 
-       boardp = modelp->selected_boardp;
-       nt_board_children_free(boardp);
+       nt_board_clear_children(&boardp->handle);
        address = boardp->address;
        assert(address);
 
        len = wcstombs(data, address, sizeof(data)-1);
-       if(len <= 0)
+       if(len <= 0){
+               nt_mutex_unlock(h_mutex);
                return FALSE;
+       }
 
        if(data[len-1] != '/')
                strcat(data, "/");
@@ -351,35 +437,40 @@ BOOL nt_read_board(nt_2ch_model_tp modelp)
 
 
        if(!nt_make_sha1_path(LOG_PATH, data, &outp)){
+               nt_mutex_unlock(h_mutex);
                return  FALSE;
        }
 
-       if(!nt_http_get(data, outp, URL_2CH_BOARDMENU, NULL, NULL, FALSE)){
+       if(!nt_http_get(data, outp, URL_2CH_BOARDMENU, NULL, NULL, FALSE, FALSE)){
                free(outp);
+               nt_mutex_unlock(h_mutex);
                return FALSE;
        }
 
        fp_src = fopen(outp, "r");
        if(!fp_src){
                free(outp);
+               nt_mutex_unlock(h_mutex);
                return FALSE;
        }
        icd     =       iconv_open("wchar_t", "cp932");
        if(((iconv_t)-1) == icd){
                fclose(fp_src);
                free(outp);
+               nt_mutex_unlock(h_mutex);
                return FALSE;
        }
        while(1){
                if(feof(fp_src))
                        break;
                s_src[0] = '\0';
-               fgets(s_src, S_SIZE, fp_src);
+               if(!fgets(s_src, S_SIZE, fp_src))
+                       break;
                p_src = s_src;
                p_dst = s_dst;
 
                n_src   =       strlen(s_src);
-               n_dst   =       S_SIZE-1;
+               n_dst   =       (S_SIZE-1)*sizeof(wchar_t);
                while(0 <       n_src){
                        size_t sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
                        if(sz == -1){
@@ -388,19 +479,26 @@ BOOL nt_read_board(nt_2ch_model_tp modelp)
                        }
                }
                *((wchar_t*)p_dst) = L'\0';
-               parse_board(boardp, (const wchar_t*)s_dst);
+               if(!parse_board(&boardp->handle, (const wchar_t*)s_dst)){
+               }
        }
-
        fclose(fp_src);
        iconv_close(icd);
-
+       
+       //fputs(" -- unlock nt_read_board\n",stderr);
+       nt_mutex_unlock(h_mutex);
+       //fputs("exit nt_read_board\n",stderr);
        free(outp);
+       if(!boardp->threadlistp)
+               return FALSE;
        return TRUE;
 }
 
-BOOL nt_write_msg(nt_2ch_model_tp modelp, nt_write_data_tp writep,
+BOOL nt_write_msg(nt_2ch_selected_item_handle h_select, nt_write_data_handle h_write_data,
                        nt_cookie_tp cookiep, nt_maru_2ch_tp marup)
 {
+       nt_2ch_selected_item_tp selectp;
+       nt_write_data_tp writep;
        wchar_t url[1024];      
        wchar_t referer[1024];
        char    post_data[1024*4];
@@ -417,21 +515,27 @@ BOOL nt_write_msg(nt_2ch_model_tp modelp, nt_write_data_tp writep,
        BOOL result = FALSE;
        iconv_t icd = 0;
 
+       assert(h_select);
+       assert(h_select->chk_sum == NT_2CH_SELECTED_ITEM_CHK_SUM);
+       assert(h_write_data);
+       assert(h_write_data->chk_sum == NT_2CH_WRITE_DATA_CHK_SUM);
+       
+       selectp = (nt_2ch_selected_item_tp)h_select;
+       writep = (nt_write_data_tp)h_write_data;
+       
        memset(s_src,   '\0',   sizeof(s_src));
        memset(s_dst,   '\0',   sizeof(s_dst));
        memset(post_data,       '\0',   sizeof(post_data));
 
-       assert(modelp);
-
-       if(!modelp->selected_categoryp)
+       if(!selectp->selected_categoryp)
                return  FALSE;
-       if(!modelp->selected_boardp)
+       if(!selectp->selected_boardp)
                return  FALSE;
-       if(!modelp->selected_threadp)
+       if(!selectp->selected_threadp)
                return  FALSE;
 
-       boardp = modelp->selected_boardp;
-       threadp = modelp->selected_threadp;
+       boardp = selectp->selected_boardp;
+       threadp = selectp->selected_threadp;
        file_name = threadp->file_name;
 
        if(!nt_parse_server_name_and_board_name(boardp->address,
@@ -439,6 +543,10 @@ BOOL nt_write_msg(nt_2ch_model_tp modelp, nt_write_data_tp writep,
                return FALSE;
        }
 
+       if(is_machibbs_address(server_name)){
+               return nt_write_msg_machibbs(selectp, writep, cookiep);
+       }
+       
        wcscpy(url, L"http://");
        wcscat(url, server_name);
        wcscat(url, L"/test/bbs.cgi");
@@ -498,6 +606,101 @@ ERROR_TRAP:
        return (result);
 }
 
+
+static BOOL nt_write_msg_machibbs(nt_2ch_selected_item_tp selectp, 
+                       nt_write_data_tp writep, nt_cookie_tp cookiep)
+{
+       wchar_t url[1024];      
+       wchar_t referer[1024];
+       char    post_data[1024*4];
+       wchar_t buf[512];
+       char    out_buf[1024*4];
+       wchar_t *dat_name;
+       wchar_t *file_name;
+       wchar_t *server_name,   *board_name;
+       nt_board_tp     boardp;
+       nt_thread_tp    threadp;
+       int     len;
+       char    s_src[S_SIZE*sizeof(wchar_t)];
+       char    s_dst[S_SIZE*sizeof(wchar_t)];
+       BOOL result = FALSE;
+       iconv_t icd = 0;
+
+       memset(s_src,   '\0',   sizeof(s_src));
+       memset(s_dst,   '\0',   sizeof(s_dst));
+       memset(post_data,       '\0',   sizeof(post_data));
+
+       if(!selectp->selected_categoryp)
+               return  FALSE;
+       if(!selectp->selected_boardp)
+               return  FALSE;
+       if(!selectp->selected_threadp)
+               return  FALSE;
+
+       boardp = selectp->selected_boardp;
+       threadp = selectp->selected_threadp;
+       file_name = threadp->file_name;
+
+       if(!nt_parse_server_name_and_board_name(boardp->address,
+               buf, sizeof(buf), &server_name, &board_name)){
+               return FALSE;
+       }
+
+       
+       wcscpy(url, L"http://");
+       wcscat(url, server_name);
+       wcscat(url, L"/bbs/write.cgi");
+       dat_name = nt_rid_sufix(file_name);
+       if(!dat_name)
+               return FALSE;
+       
+       wcscpy(referer, boardp->address);
+
+       len = wcstombs(s_src, url, sizeof(s_src)-1);
+       if(len <= 0)
+               goto ERROR_TRAP;
+       len = wcstombs(s_dst, referer, sizeof(s_dst)-1);
+       if(len <= 0)
+               goto ERROR_TRAP;
+       if(!set_post_data_machibbs(post_data, sizeof(post_data),
+                       board_name, dat_name, writep->name,
+                       writep->mail, writep->msg)){
+               goto ERROR_TRAP;
+       }
+       len = wcstombs(s_src, url, sizeof(s_src)-1);
+       if(len <= 0)
+               goto ERROR_TRAP;
+       strcat(post_data, "&CC=%82%A0");
+       
+       if(!nt_http_post(s_src, post_data, out_buf, sizeof(out_buf),
+                   s_dst, NULL, NULL, cookiep)){
+               goto ERROR_TRAP;
+       }
+       icd =   iconv_open("wchar_t", "cp932");
+       if(((iconv_t)-1) == icd){
+               icd = 0;
+               goto ERROR_TRAP;
+       }
+       if(writep->result_html)
+               free(writep->result_html);
+       writep->result_html = malloc(1024*sizeof(wchar_t)*4);
+       if(!writep->result_html)
+               goto ERROR_TRAP;
+
+       if(!nt_conv_sjis2wc(icd, out_buf, writep->result_html, 
+                               1024*sizeof(wchar_t)*4)){
+               goto ERROR_TRAP;
+       }
+       result = TRUE;
+ERROR_TRAP:
+       if(icd)
+               iconv_close(icd);
+       free(dat_name);
+       return (result);
+}
+
+
+
 static BOOL set_post_data(char *data, size_t data_len,
                const wchar_t *bbs, const wchar_t *id, 
                const char *name, const char *mail, 
@@ -575,7 +778,91 @@ static BOOL set_post_data(char *data, size_t data_len,
                strcpy(cptr, buf2);
                cptr += strlen(buf2);
        }
-       strcpy(cptr, "&submit=8F%91%82%AB%8D%9E%82%DE");
+       strcpy(cptr, "&submit=%8F%91%82%AB%8D%9E%82%DE");
+
+       iconv_close(icd);
+       
+       return TRUE;
+}
+
+static BOOL set_post_data_machibbs(char *data, size_t data_len,
+               const wchar_t *bbs, const wchar_t *id, 
+               const char *name, const char *mail, 
+               const char *msg)
+{
+       iconv_t icd;
+       time_t t;
+       char buf[1024*4];
+       char buf2[1024*4];
+       char *cptr;
+       assert(bbs && id && name && mail && msg);
+
+       memset(buf, 0, sizeof(buf));
+       memset(buf2, 0, sizeof(buf2));
+
+       icd =   iconv_open("cp932", "wchar_t");
+       if(((iconv_t)-1) == icd){
+           return FALSE;
+       }
+       t =  time(NULL);
+       t -= 600;
+
+       cptr = data;
+       strcpy(cptr, "BBS=");
+       cptr += strlen(data);
+       if(!nt_conv_wc2sjis(icd, bbs, buf, sizeof(buf)))
+               return FALSE;
+       strcpy(cptr, buf);
+       cptr+= strlen(cptr);
+       strcpy(cptr, "&KEY=");
+       cptr += strlen(cptr);
+       if(!nt_conv_wc2sjis(icd, id, buf, sizeof(buf)))
+               return FALSE;
+       strcpy(cptr, buf);
+       cptr+= strlen(cptr);
+       strcpy(cptr, "&TIME=");
+       cptr += strlen(cptr);
+       sprintf(buf, "%ld&NAME=", t);
+       strcpy(cptr, buf);
+       cptr+= strlen(cptr);
+
+       iconv_close(icd);
+
+       icd =   iconv_open("cp932", "UTF-8");
+       if(icd == (iconv_t)-1){
+               perror("e");
+               return FALSE;
+       }
+
+       if(name && 0 < strlen(name)){
+               if(!nt_conv_local2sjis(icd, name, buf, sizeof(buf)))
+                       return FALSE;
+               if(!url_encode(buf, buf2, sizeof(buf2)))
+                       return FALSE;
+               strcpy(cptr, buf2);
+               cptr += strlen(buf2);
+       }
+       strcpy(cptr, "&MAIL=");
+       cptr += strlen(cptr);
+       if(mail && 0 < strlen(mail)){
+               if(!nt_conv_local2sjis(icd, mail, buf, sizeof(buf)))
+                       return FALSE;
+               if(!url_encode(buf, buf2, sizeof(buf2)))
+                       return FALSE;
+               strcpy(cptr, buf2);
+               cptr += strlen(buf2);
+       }
+       strcpy(cptr, "&MESSAGE=");
+       cptr += strlen(cptr);
+       if(msg && 0 < strlen(msg)){
+               if(!nt_conv_local2sjis(icd, msg, buf, sizeof(buf)))
+                       return FALSE;
+               if(!url_encode(buf, buf2, sizeof(buf2)))
+                       return FALSE;
+               strcpy(cptr, buf2);
+               cptr += strlen(buf2);
+       }
+       strcpy(cptr, "&submit=%8F%91%82%AB%8D%9E%82%DE");
 
        iconv_close(icd);
        
@@ -612,3 +899,148 @@ static BOOL set_offlaw_address(char *buf, size_t buf_len,
        return TRUE;
 }
 
+int nt_read_board_list(nt_link_tp selitem_list)
+{
+       nt_2ch_selected_item_handle h_select;
+       nt_link_tp linkp;
+       int num_success;
+       nt_pthread_handle h_pthread;
+       
+       assert(selitem_list);
+       num_success = 0;
+       linkp = selitem_list;
+       do{
+               h_select = (nt_2ch_selected_item_handle)linkp->data;
+#ifdef NT_DISABLE_PTHREAD
+               if(nt_read_board(h_select))
+                       num_success++;
+#else
+               nt_2ch_selected_item_add_ref(h_select);
+               h_pthread = nt_pthread_alloc(
+                               nt_read_board_async,
+                               h_select,
+                               nt_read_board_async_result);
+               if(!h_pthread){
+                       nt_2ch_selected_item_release_ref(h_select);
+               }else if(!nt_pthread_put_que(h_pthread)){
+                       nt_pthread_release_ref(h_pthread);
+                       nt_2ch_selected_item_release_ref(h_select);
+               }else{
+                       nt_pthread_release_ref(h_pthread);
+                       num_success++;
+               }
+#endif
+               linkp = linkp->next;
+       }while(linkp != selitem_list);
+       return num_success;
+}
+
+static nt_pthread_result_t nt_read_board_async(void* data)
+{
+       nt_2ch_selected_item_handle h_select;
+       nt_pthread_result_t result;
+       
+       result.code = NT_PTHREAD_RESULT_NONE;
+       result.data = NULL;
+       
+       h_select = (nt_2ch_selected_item_handle)data;
+       nt_2ch_selected_item_add_ref(h_select);
+       nt_2ch_selected_item_release_ref(h_select);
+       
+       if(nt_read_board(h_select)){
+               result.code = NT_PTHREAD_RESULT_UPDATE_BOARD;
+       }
+       nt_2ch_selected_item_release_ref(h_select);
+       return result;
+}
+
+static nt_pthread_result_t nt_read_board_async_result(
+                       nt_pthread_result_t result)
+{
+       return result;
+}
+
+BOOL nt_set_sel_item(nt_2ch_model_handle h_model,
+                       nt_2ch_selected_item_handle *h_sel_itemp, 
+                       nt_searched_thread_handle h_searched_thread, const wchar_t** errorpp)
+{
+       const wchar_t *board_name, *dat_name, *title;
+       nt_category_handle h_category;
+       nt_board_handle h_board;
+       nt_thread_handle h_thread;
+       nt_2ch_selected_item_handle h_sel_item;
+       nt_enum_handle h_enum;
+       
+       assert(h_sel_itemp);
+       
+       h_sel_item = nt_2ch_selected_item_alloc();
+       if(!h_sel_item){
+               return FALSE;
+       }
+       board_name = nt_searched_thread_get_board_name(h_searched_thread);
+       assert(board_name);
+       
+       dat_name = nt_searched_thread_get_dat_name(h_searched_thread);
+       title = nt_searched_thread_get_title(h_searched_thread);
+       
+       h_board = nt_get_board_by_name(
+                       h_model, board_name, &h_category);
+       if(!h_board || !h_category){
+               *errorpp = L"板情報が見つかりませんでした";
+               nt_2ch_selected_item_release_ref(h_sel_item);
+               return FALSE;
+       }
+       nt_set_selected_board(h_sel_item, h_category, h_board);
+       
+       
+       h_enum = nt_board_get_thread_enum(h_board);
+       if(!h_enum){
+               if(!nt_read_board(h_sel_item)){
+                       *errorpp = L"板が開けませんでした";
+                       goto ERROR_TRAP;
+               }
+               h_enum = nt_board_get_thread_enum(h_board);
+               if(!h_enum){
+                       *errorpp = L"板が開けませんでした";
+                       goto ERROR_TRAP;
+               }
+       }
+       
+       nt_enum_unset(h_enum);
+       
+       if(!dat_name){
+               nt_board_release_ref(h_board);
+               nt_category_release_ref(h_category);
+               *h_sel_itemp = h_sel_item;
+               return TRUE;
+       }
+       h_thread = nt_get_thread_by_dat_name(h_board, dat_name);
+       if(!h_thread){
+               if(!title)
+                       title = L"Dummy";
+               h_thread = nt_thread_dummy_alloc(title, dat_name, 0);
+               if(!h_thread){
+                       *errorpp = L"スレッド情報が見つかりませんでした";
+                       goto ERROR_TRAP;
+               }
+       }
+       
+       nt_set_selected_thread(h_sel_item, h_thread);
+       nt_thread_release_ref(h_thread);
+       
+       if(!nt_read_thread(h_sel_item)){
+               *errorpp = L"スレッドが開けませんでした";
+               goto ERROR_TRAP;
+       }
+       
+       nt_board_release_ref(h_board);
+       nt_category_release_ref(h_category);
+       *h_sel_itemp = h_sel_item;
+       return TRUE;
+ERROR_TRAP:
+       nt_board_release_ref(h_board);
+       nt_category_release_ref(h_category);
+       nt_2ch_selected_item_release_ref(h_sel_item);
+       return FALSE;
+}
+