From 01f2ec93ea55fb94f24267381e625c9299c5ec4a Mon Sep 17 00:00:00 2001 From: Akira Date: Mon, 30 Dec 2013 18:48:06 +0900 Subject: [PATCH] sync read count of threads. .ntchrc supports '#'commnet. --- Makefile | 5 + Makefile.in | 5 + README | 2 +- config.h | 4 +- configure | 18 +- configure.ac | 2 +- help.txt | 7 +- nce/account.php | 2 +- nce/env.php | 14 + nce/nc_checkuser.php | 1 - nce/nc_delete_attribute_db.php | 4 +- ...ord_by_type_db.php => nc_delete_readcnt_db.php} | 43 +- ...dcnt_list_db.php => nc_query_attributes_db.php} | 41 +- nce/nc_query_board_attribute_list_db.php | 86 -- ...st2_db.php => nc_query_board_attributes_db.php} | 31 +- nce/nc_query_thread_attribute_list_db.php | 89 -- nce/nc_update_readcnt_db.php | 23 +- src/_2ch/_2ch.c | 9 + src/cloud/nt_cloud.c | 134 ++- src/cloud/nt_cloud2.c | 923 +++++++++++++++++++++ src/env.c | 24 +- src/inc/cloud/nt_cloud.h | 74 +- src/inc/config.h | 4 +- src/inc/env.h | 2 + src/inc/usr/usr_db_t.h | 5 +- src/inc/utils/nt_pthread.h | 1 + src/main.c | 5 + src/net/nt_http.c | 7 +- src/ui/disp_favorite.c | 7 +- src/ui/disp_reslist.c | 3 +- src/ui/disp_threadlist.c | 31 +- src/usr/favorite_t.c | 3 +- src/usr/usr_db_t.c | 104 ++- src/utils/text.c | 43 +- 34 files changed, 1425 insertions(+), 331 deletions(-) create mode 100644 nce/env.php rename nce/{nc_query_record_by_type_db.php => nc_delete_readcnt_db.php} (51%) rename nce/{nc_query_readcnt_list_db.php => nc_query_attributes_db.php} (56%) delete mode 100644 nce/nc_query_board_attribute_list_db.php rename nce/{nc_query_readcnt_list2_db.php => nc_query_board_attributes_db.php} (67%) delete mode 100644 nce/nc_query_thread_attribute_list_db.php create mode 100644 src/cloud/nt_cloud2.c diff --git a/Makefile b/Makefile index 24e6b15..ac381da 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,7 @@ OBJS = ${OBJ_DIR}/main.o ${OBJ_DIR}/utils/nt_std_t.o \ ${OBJ_DIR}/env.o \ ${OBJ_DIR}/print_help.o \ ${OBJ_DIR}/cloud/nt_cloud.o \ + ${OBJ_DIR}/cloud/nt_cloud2.o \ ${OBJ_DIR}/utils/base64.o \ ${OBJ_DIR}/utils/crypt.o \ ${OBJ_DIR}/utils/file.o \ @@ -147,6 +148,10 @@ $(OBJ_DIR)/cloud/nt_cloud.o : ${SRC_DIR}/cloud/nt_cloud.c ${INC_FILES} @ ${SHELL} prepare_proj.sh ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< +$(OBJ_DIR)/cloud/nt_cloud2.o : ${SRC_DIR}/cloud/nt_cloud2.c ${INC_FILES} + @ ${SHELL} prepare_proj.sh + ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< + $(OBJ_DIR)/utils/nt_std_t.o : ${SRC_DIR}/utils/nt_std_t.c ${INC_FILES} @ ${SHELL} prepare_proj.sh ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< diff --git a/Makefile.in b/Makefile.in index e352b6c..481f729 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,6 +14,7 @@ OBJS = ${OBJ_DIR}/main.o ${OBJ_DIR}/utils/nt_std_t.o \ ${OBJ_DIR}/env.o \ ${OBJ_DIR}/print_help.o \ ${OBJ_DIR}/cloud/nt_cloud.o \ + ${OBJ_DIR}/cloud/nt_cloud2.o \ ${OBJ_DIR}/utils/base64.o \ ${OBJ_DIR}/utils/crypt.o \ ${OBJ_DIR}/utils/file.o \ @@ -147,6 +148,10 @@ $(OBJ_DIR)/cloud/nt_cloud.o : ${SRC_DIR}/cloud/nt_cloud.c ${INC_FILES} @ ${SHELL} prepare_proj.sh ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< +$(OBJ_DIR)/cloud/nt_cloud2.o : ${SRC_DIR}/cloud/nt_cloud2.c ${INC_FILES} + @ ${SHELL} prepare_proj.sh + ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< + $(OBJ_DIR)/utils/nt_std_t.o : ${SRC_DIR}/utils/nt_std_t.c ${INC_FILES} @ ${SHELL} prepare_proj.sh ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< diff --git a/README b/README index 796bf66..79acf97 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ - ntch version 1.0.2.2 + ntch version 1.0.2.3 This file is part of ntch. diff --git a/config.h b/config.h index 9fe9b3b..2777958 100644 --- a/config.h +++ b/config.h @@ -141,7 +141,7 @@ #define PACKAGE_NAME "ntch" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "ntch 1.0.2.2" +#define PACKAGE_STRING "ntch 1.0.2.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "ntch" @@ -150,7 +150,7 @@ #define PACKAGE_URL "https://sourceforge.jp/projects/ntch/" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.0.2.2" +#define PACKAGE_VERSION "1.0.2.3" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 diff --git a/configure b/configure index f2a3568..f804b6d 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for ntch 1.0.2.2. +# Generated by GNU Autoconf 2.69 for ntch 1.0.2.3. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ntch' PACKAGE_TARNAME='ntch' -PACKAGE_VERSION='1.0.2.2' -PACKAGE_STRING='ntch 1.0.2.2' +PACKAGE_VERSION='1.0.2.3' +PACKAGE_STRING='ntch 1.0.2.3' PACKAGE_BUGREPORT='akohta001@gmail.com' PACKAGE_URL='https://sourceforge.jp/projects/ntch/' @@ -1230,7 +1230,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures ntch 1.0.2.2 to adapt to many kinds of systems. +\`configure' configures ntch 1.0.2.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1291,7 +1291,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of ntch 1.0.2.2:";; + short | recursive ) echo "Configuration of ntch 1.0.2.3:";; esac cat <<\_ACEOF @@ -1372,7 +1372,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -ntch configure 1.0.2.2 +ntch configure 1.0.2.3 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1795,7 +1795,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by ntch $as_me 1.0.2.2, which was +It was created by ntch $as_me 1.0.2.3, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4797,7 +4797,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by ntch $as_me 1.0.2.2, which was +This file was extended by ntch $as_me 1.0.2.3, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4864,7 +4864,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -ntch config.status 1.0.2.2 +ntch config.status 1.0.2.3 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 7f5b5c3..4c7bc5e 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([ntch], [1.0.2.2], [akohta001@gmail.com],[ntch],[https://sourceforge.jp/projects/ntch/]) +AC_INIT([ntch], [1.0.2.3], [akohta001@gmail.com],[ntch],[https://sourceforge.jp/projects/ntch/]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_HEADERS([config.h]) diff --git a/help.txt b/help.txt index 50b3b3d..009de46 100644 --- a/help.txt +++ b/help.txt @@ -1,5 +1,5 @@ - ntch version 1.0.2.2 + ntch version 1.0.2.3 This file is part of ntch. @@ -40,6 +40,11 @@ Linux用 2ch専用ブラウザー 無指定の時は、実行時のカレントディレクトリの配下にlogディレクトリを 作成して出力します。 +-p --pem + pem形式のCAファイルを指定します。未指定時にはカレントディレクトリから + cacert.pemファイルを探します。 + ※クラウド拡張(後述)使用時にSSL通信を行う場合に使用します + キーコマンド 全般 diff --git a/nce/account.php b/nce/account.php index dfdc6f4..b1c5213 100644 --- a/nce/account.php +++ b/nce/account.php @@ -31,7 +31,7 @@ SELECT_USER; return FALSE; } if(!$result || $result->num_rows != 1){ - print_r($result); + //print_r($result); return FALSE; } $row = $result->fetch_assoc(); diff --git a/nce/env.php b/nce/env.php new file mode 100644 index 0000000..5b79a4d --- /dev/null +++ b/nce/env.php @@ -0,0 +1,14 @@ += 5){ + date_default_timezone_set("Asia/Tokyo"); +} +?> diff --git a/nce/nc_checkuser.php b/nce/nc_checkuser.php index f338856..0158253 100644 --- a/nce/nc_checkuser.php +++ b/nce/nc_checkuser.php @@ -15,7 +15,6 @@ include_once "error_code.php"; $user_id = $_POST['user']; $pass = $_POST['passwd']; - if(!chk_param($user_id) || !chk_param($pass)){ echo ERROR302; exit; diff --git a/nce/nc_delete_attribute_db.php b/nce/nc_delete_attribute_db.php index de83a09..eac6906 100644 --- a/nce/nc_delete_attribute_db.php +++ b/nce/nc_delete_attribute_db.php @@ -15,14 +15,14 @@ include_once "http_util.php"; include_once "error_code.php"; $user_id = $_POST['user']; -$hashed_passwd = $_POST['hashed_passwd']; +$token = $_POST['token']; $board_name = $_POST['board_name']; $dat_name = $_POST['dat_name']; $res_number = $_POST['res_number']; $record_type = $_POST['record_type']; //--- authorization --- -$user = chk_passwd( $user_id, $hashed_passwd); +$user = chk_passwd( $user_id, $token); if(FALSE === $user){ echo $ERROR_MSG; exit; diff --git a/nce/nc_query_record_by_type_db.php b/nce/nc_delete_readcnt_db.php similarity index 51% rename from nce/nc_query_record_by_type_db.php rename to nce/nc_delete_readcnt_db.php index 5398f3f..6e46b6c 100644 --- a/nce/nc_query_record_by_type_db.php +++ b/nce/nc_delete_readcnt_db.php @@ -1,12 +1,12 @@ 6){ - echo ERROR304; - exit; -} //--- parameter check end --- $table_name = TABLE_PREFIX."tbl{$user->home_dir}"; -$query = <<< QUERY1 -select board_name, dat_name, last_update from $table_name - where record_type = '{$record_type}' order by last_update desc limit 0,50 -QUERY1; +$error_msg; +$query = "update $table_name set record_type = 4 ". + "where record_type = 1 and board_name='{$board_name}' "; +if('*' != $dat_name){ + $query = $query."and dat_name='{$dat_name}' "; +} try{ $db->open(); $result = $db->execute($query); - if(!$result){ - echo ERROR503; + echo ERROR504; exit; } $db->close(); }catch(Exception $e){ $error = __FILE__."(".__LINE__. - ") An error occured during query."; + ") An error occured during delete."; + nc_logging($error, $e); echo ERROR500; exit; } echo SUCCESS100; -for($i = 0; $i < $result->num_rows; $i++){ - $row = $result->fetch_assoc(); - echo $row['board_name'].",".$row['dat_name'].",".$row['last_update']."\n"; -} ?> diff --git a/nce/nc_query_readcnt_list_db.php b/nce/nc_query_attributes_db.php similarity index 56% rename from nce/nc_query_readcnt_list_db.php rename to nce/nc_query_attributes_db.php index fb5d59f..93cfea3 100644 --- a/nce/nc_query_readcnt_list_db.php +++ b/nce/nc_query_attributes_db.php @@ -1,12 +1,13 @@ '{$last_query}'"; -if(!is_numeric($record_type)){ - echo ERROR303; - exit; -} - -if(1 != $record_type && 4 != $record_type){ - echo ERROR304; - exit; } //--- parameter check end --- $table_name = TABLE_PREFIX."tbl{$user->home_dir}"; $query1 = <<< QUERY1 -select dat_name, res_number from $table_name - where board_name='{$board_name}' and record_type = '{$record_type}' +select record_type, res_number, dat_name, board_name, last_update from $table_name {$extra_filter} QUERY1; try{ @@ -71,9 +59,12 @@ try{ } echo SUCCESS100; +echo date("Y-m-d H:i:s"); +echo "\n"; for($i = 0; $i < $result->num_rows; $i++){ $row = $result->fetch_assoc(); - echo $row['dat_name']."=".$row['res_number']."\n"; + echo $row['board_name'].",".$row['dat_name'].",".$row['res_number']. + ",".$row['record_type'].",".$row['last_update']."\n"; } ?> diff --git a/nce/nc_query_board_attribute_list_db.php b/nce/nc_query_board_attribute_list_db.php deleted file mode 100644 index 23169e7..0000000 --- a/nce/nc_query_board_attribute_list_db.php +++ /dev/null @@ -1,86 +0,0 @@ -home_dir}"; -$query = <<< QUERY1 -select res_number, record_type, dat_name from $table_name - where board_name='{$board_name}' and ( record_type = '{$type1}' -QUERY1; - -if(chk_param($type2)){ - if(!is_numeric($type2) || - ($type2!=2 && $type2!=3 && $type2!=5 && $type2!=6) || - ($type1 == $type2)){ - echo ERROR303; - exit; - } - $query = $query." or record_type = '{$type2}')"; -}else{ - $query = $query." )"; -} - -try{ - $db->open(); - $result = $db->execute($query); - - if(!$result){ - echo ERROR503; - exit; - } - $db->close(); -}catch(Exception $e){ - $error = __FILE__."(".__LINE__. - ") An error occured during query."; - nc_logging($error, $e); - echo ERROR500; - exit; -} - -echo SUCCESS100; -for($i = 0; $i < $result->num_rows; $i++){ - $row = $result->fetch_assoc(); - echo $row['dat_name'].",".$row['record_type'].",".$row['res_number']."\n"; -} - -?> diff --git a/nce/nc_query_readcnt_list2_db.php b/nce/nc_query_board_attributes_db.php similarity index 67% rename from nce/nc_query_readcnt_list2_db.php rename to nce/nc_query_board_attributes_db.php index 147e98e..deb4f2f 100644 --- a/nce/nc_query_readcnt_list2_db.php +++ b/nce/nc_query_board_attributes_db.php @@ -1,12 +1,13 @@ '{$last_query}'"; -if(isset($aes_enable) && $aes_enable==1){ - $extra_filter = "record_type > 3 and record_type < 7"; -}else{ - $extra_filter = "record_type > 0 and record_type < 4"; } //--- parameter check end --- $table_name = TABLE_PREFIX."tbl{$user->home_dir}"; $query1 = <<< QUERY1 -select res_number, record_type, dat_name, last_update from $table_name - where board_name='{$board_name}' and {$extra_filter} +select record_type, res_number, dat_name, last_update from $table_name {$extra_filter} QUERY1; try{ @@ -64,8 +65,8 @@ try{ } echo SUCCESS100; -//echo $query1."\n"; -//print_r($result); +echo date("Y-m-d H:i:s"); +echo "\n"; for($i = 0; $i < $result->num_rows; $i++){ $row = $result->fetch_assoc(); echo $row['dat_name'].",".$row['res_number'].",".$row['record_type'].",".$row['last_update']."\n"; diff --git a/nce/nc_query_thread_attribute_list_db.php b/nce/nc_query_thread_attribute_list_db.php deleted file mode 100644 index c8ae026..0000000 --- a/nce/nc_query_thread_attribute_list_db.php +++ /dev/null @@ -1,89 +0,0 @@ -home_dir}"; -$query = <<< QUERY1 -select res_number, record_type from $table_name - where board_name='{$board_name}' and dat_name='{$dat_name}' - and ( record_type = '{$type1}' -QUERY1; - -if(chk_param($type2)){ - if(!is_numeric($type2) || - ($type2!=2 && $type2!=3 && $type2!=5 && $type2!=6) || - ($type1 == $type2)){ - echo ERROR303; - exit; - } - $query = $query." or record_type = '{$type2}')"; -}else{ - $query = $query." )"; -} - -try{ - $db->open(); - $result = $db->execute($query); - - if(!$result){ - echo ERROR503; - exit; - } - $db->close(); -}catch(Exception $e){ - $error = __FILE__."(".__LINE__. - ") An error occured during query."; - nc_logging($error, $e); - echo ERROR500; - exit; -} - -echo SUCCESS100; -for($i = 0; $i < $result->num_rows; $i++){ - $row = $result->fetch_assoc(); - echo $row['record_type']."=".$row['res_number']."\n"; -} - -?> diff --git a/nce/nc_update_readcnt_db.php b/nce/nc_update_readcnt_db.php index dce9bc5..ec31eeb 100644 --- a/nce/nc_update_readcnt_db.php +++ b/nce/nc_update_readcnt_db.php @@ -15,14 +15,13 @@ include_once "http_util.php"; include_once "error_code.php"; $user_id = $_POST['user']; -$hashed_passwd = $_POST['hashed_passwd']; +$token = $_POST['token']; $board_name = $_POST['board_name']; $dat_name = $_POST['dat_name']; $res_number = $_POST['res_number']; -$record_type = $_POST['record_type']; //--- authorization --- -$user = chk_passwd( $user_id, $hashed_passwd); +$user = chk_passwd( $user_id, $token); if(FALSE === $user){ echo $ERROR_MSG; exit; @@ -30,28 +29,18 @@ if(FALSE === $user){ //--- parameter check start --- if(!chk_param($board_name) || !chk_param($dat_name) || - !chk_param($res_number) || !chk_param($record_type)){ + !chk_param($res_number)){ echo ERROR303; exit; } -if(!is_numeric($record_type)){ - echo ERROR303; - exit; -} - -if(1 != $record_type && 4 != $record_type){ - echo ERROR304; - exit; -} - //--- parameter check end --- $table_name = TABLE_PREFIX."tbl{$user->home_dir}"; $query1 = <<< QUERY1 select id from $table_name - where record_type="{$record_type}" and + where record_type=1 and board_name='{$board_name}' and dat_name='{$dat_name}' QUERY1; @@ -59,13 +48,13 @@ QUERY1; $query2 = <<< QUERY2 insert into $table_name (record_type, res_number, dat_name, board_name) - values ('{$record_type}', '{$res_number}', "{$dat_name}", "{$board_name}") + values (1, '{$res_number}', "{$dat_name}", "{$board_name}") QUERY2; $query3 = <<< QUERY3 update $table_name set res_number="{$res_number}" - where record_type="{$record_type}" and + where record_type=1 and board_name="{$board_name}" and dat_name='{$dat_name}' QUERY3; diff --git a/src/_2ch/_2ch.c b/src/_2ch/_2ch.c index 2122782..d9a991a 100644 --- a/src/_2ch/_2ch.c +++ b/src/_2ch/_2ch.c @@ -33,6 +33,7 @@ #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" @@ -159,6 +160,7 @@ BOOL nt_read_thread(nt_2ch_selected_item_handle h_select) 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); @@ -288,6 +290,13 @@ BOOL nt_read_thread(nt_2ch_selected_item_handle h_select) 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); } diff --git a/src/cloud/nt_cloud.c b/src/cloud/nt_cloud.c index b0cfbdf..3c3a200 100644 --- a/src/cloud/nt_cloud.c +++ b/src/cloud/nt_cloud.c @@ -24,6 +24,8 @@ #include #include +#define NT_CLOUD_PRIVATE + #include "env.h" #include "utils/nt_std_t.h" #include "utils/text.h" @@ -35,28 +37,18 @@ #include "cloud/nt_cloud.h" -#define NT_CLOUD_CHK_SUM (1478428) - -typedef struct tag_nt_cloud_t *nt_cloud_tp; -typedef struct tag_nt_cloud_t { - nt_cloud_handle_t handle; - int ref_count; - char *usr_id; - char *passwd; - char *auth_url; - char *query_url; - char *home_url; - char *token; - int error_no; -}nt_cloud_t; - - -static nt_link_tp nt_split_line(char *data); -static int nt_get_cloud_result(const char *ptr); static BOOL nt_cloud_edit_lines_file(nt_cloud_handle handle, const char *file_name, nt_link_tp lines, const char *php_file, int depth); static BOOL nt_cloud_upload_file_local(nt_cloud_handle handle, const char *file_name, nt_link_tp lines, int depth); +static nt_cloud_handle g_cloud_handle = NULL; + +nt_cloud_handle nt_cloud_get_handle(){ + if(!g_cloud_handle) + return NULL; + nt_cloud_add_ref(g_cloud_handle); + return g_cloud_handle; +} nt_cloud_handle nt_cloud_init( const char *auth_url, const char *usr_id, const char *pass) @@ -96,7 +88,7 @@ nt_cloud_handle nt_cloud_init( nt_cloud_release_ref(&cloudp->handle); return NULL; } - + g_cloud_handle = &cloudp->handle; return &cloudp->handle; } @@ -131,6 +123,7 @@ int nt_cloud_release_ref(nt_cloud_handle handle) if(cloudp->token) free(cloudp->token); free(cloudp); + g_cloud_handle = NULL; return 0; } @@ -183,7 +176,7 @@ BOOL nt_cloud_chk_user(nt_cloud_handle handle) break; case 3: cloudp->home_url = nt_str_clone((const char*)wrkp->data); - if(!cloudp->query_url) + if(!cloudp->home_url) goto ERROR_TRAP; break; case 4: @@ -215,12 +208,12 @@ ERROR_TRAP: BOOL nt_cloud_insert_lines_into_file(nt_cloud_handle handle, const char *file_name, nt_link_tp lines) { - return nt_cloud_edit_lines_file(handle, file_name, lines, "nc_insert_lines_file.php", 0); + return nt_cloud_edit_lines_file(handle, file_name, lines, NT_CLOUD_INSERT_LINES_FILE_PHP, 0); } BOOL nt_cloud_delete_lines_from_file(nt_cloud_handle handle, const char *file_name, nt_link_tp lines) { - return nt_cloud_edit_lines_file(handle, file_name, lines, "nc_delete_lines_file.php", 0); + return nt_cloud_edit_lines_file(handle, file_name, lines, NT_CLOUD_DELETE_LINES_FILE_PHP, 0); } static BOOL nt_cloud_edit_lines_file(nt_cloud_handle handle, @@ -459,12 +452,12 @@ static BOOL nt_cloud_upload_file_local(nt_cloud_handle handle, assert(cloudp->token); len = strlen(cloudp->query_url); - len += strlen("nc_write_file.php"); + len += strlen(NT_CLOUD_WRITE_FILE_PHP); url = malloc(len+1); if(!url) return FALSE; strcpy(url, cloudp->query_url); - strcat(url, "nc_write_file.php"); + strcat(url, NT_CLOUD_WRITE_FILE_PHP); post_data = malloc(buf_delta); if(!post_data){ @@ -529,7 +522,96 @@ static BOOL nt_cloud_upload_file_local(nt_cloud_handle handle, return TRUE; } -static int nt_get_cloud_result(const char *ptr) +BOOL nt_wc_sjis_aes_b64_url_encode( + iconv_t icd, nt_crypt_handle h_crypt, + const wchar_t *in_data, + unsigned char *wrk_buf, char *out_data, size_t max_len) +{ + int len; + if(!nt_conv_wc2sjis(icd, in_data, + out_data, max_len)) + return FALSE; + + len = nt_crypt_encrypt(h_crypt, + (const unsigned char*)out_data,strlen(out_data), + wrk_buf, max_len); + if(len == -1) + return FALSE; + + if(!nt_base64_url_encode( + (const unsigned char*)wrk_buf, + len, out_data, max_len)){ + return FALSE; + } + return TRUE; +} + +BOOL nt_ascii_aes_b64_url_encode( + iconv_t icd, nt_crypt_handle h_crypt, + const char *in_data, + unsigned char *wrk_buf, char *out_data, size_t max_len) +{ + int len; + + len = nt_crypt_encrypt(h_crypt, + (const unsigned char*)in_data,strlen(in_data), + wrk_buf, max_len); + if(len == -1) + return FALSE; + + if(!nt_base64_url_encode( + (const unsigned char*)wrk_buf, + len, out_data, max_len)){ + return FALSE; + } + return TRUE; +} + +BOOL nt_url_b64_aes_sjis_wc_decode( + iconv_t icd, nt_crypt_handle h_crypt, + const char *in_data, + unsigned char *wrk_buf, wchar_t *out_data, size_t max_len) +{ + int len; + + len = nt_base64_url_decode(in_data, strlen(in_data), + (unsigned char*)out_data, max_len); + if(len == -1) + return FALSE; + len = nt_crypt_decrypt(h_crypt, + (const unsigned char*)out_data, len, + (unsigned char*)wrk_buf, max_len); + if(len == -1) + return FALSE; + wrk_buf[len] = '\0'; + if(!nt_conv_sjis2wc(icd, (const char*)wrk_buf, + out_data, max_len)){ + return FALSE; + } + return TRUE; +} + +BOOL nt_url_b64_aes_ascii_decode( + iconv_t icd, nt_crypt_handle h_crypt, + const char *in_data, + unsigned char *wrk_buf, char *out_data, size_t max_len) +{ + int len; + + len = nt_base64_url_decode(in_data, strlen(in_data), + wrk_buf, max_len); + if(len == -1) + return FALSE; + len = nt_crypt_decrypt(h_crypt, + (const unsigned char*)wrk_buf, len, + (unsigned char*)out_data, max_len); + if(len == -1) + return FALSE; + out_data[len] = '\0'; + return TRUE; +} + +int nt_get_cloud_result(const char *ptr) { int num; @@ -551,7 +633,7 @@ static int nt_get_cloud_result(const char *ptr) return num; } -static nt_link_tp nt_split_line(char *data) +nt_link_tp nt_split_line(char *data) { nt_link_tp linkp, wrkp; char *cptr, *p; diff --git a/src/cloud/nt_cloud2.c b/src/cloud/nt_cloud2.c new file mode 100644 index 0000000..0c435e8 --- /dev/null +++ b/src/cloud/nt_cloud2.c @@ -0,0 +1,923 @@ +/* Copyright 2013 Akira Ohta (akohta001@gmail.com) + This file is part of ntch. + + The ntch is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + The ntch is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with ntch. If not, see . + +*/ +#include +#include +#include +#include +#include +#include +#include +#include + +#define NT_CLOUD_PRIVATE + +#include "env.h" +#include "utils/nt_std_t.h" +#include "utils/text.h" +#include "utils/file.h" +#include "utils/nt_pthread.h" +#include "utils/base64.h" +#include "utils/crypt.h" +#include "utils/nt_conv_char.h" +#include "net/nt_http.h" +#include "cloud/nt_cloud.h" + +static BOOL arrange_res_number( + int number, const char *seed, char *buf, const wchar_t *dat_name); +static int parse_res_number(const char *buf); +static nt_pthread_result_t update_read_count_fnc(void *param); +static nt_pthread_result_t delete_read_count_fnc(void *param); + + +void nt_cloud_update_read_count_async(nt_cloud_handle handle, + const wchar_t *_board_name, const wchar_t *_dat_name, + int res_number) +{ + nt_link_tp param; + nt_pthread_handle h_pthread; + wchar_t *board_name, *dat_name; + + board_name = nt_w_str_clone(_board_name); + if(!board_name) + return; + dat_name = nt_w_str_clone(_dat_name); + if(!dat_name){ + free(board_name); + return; + } + param = nt_link_add_data(NULL, handle); + if(!param){ + free(board_name); + free(dat_name); + return; + } + nt_cloud_add_ref(handle); + if(!nt_link_add_data(param, board_name)){ + goto ERROR_TRAP; + } + if(!nt_link_add_data(param, dat_name)){ + goto ERROR_TRAP; + } + if(!nt_link_add_n_data(param, res_number)){ + goto ERROR_TRAP; + } + + h_pthread = nt_pthread_alloc( + update_read_count_fnc, param, NULL); + if(!h_pthread){ + goto ERROR_TRAP; + } + + if(!nt_pthread_put_que(h_pthread)){ + nt_pthread_release_ref(h_pthread); + goto ERROR_TRAP; + } + + nt_pthread_release_ref(h_pthread); + return; +ERROR_TRAP: + nt_cloud_release_ref(handle); + nt_all_link_free(param, NULL); + free(board_name); + free(dat_name); + + +} + +BOOL nt_cloud_update_read_count(nt_cloud_handle handle, + const wchar_t *board_name, const wchar_t *dat_name, + int res_number, int depth) +{ + char *url; + char buf1[1024]; + char buf2[1024]; + char buf3[1024]; + char *post_data; + nt_cloud_tp cloudp; + int len; + nt_crypt_handle h_crypt; + iconv_t icd; + static const int buf_delta = 1024; + int result_code; + + assert(handle); + assert(handle->chk_sum == NT_CLOUD_CHK_SUM); + cloudp = (nt_cloud_tp)handle; + assert(cloudp->usr_id); + assert(cloudp->token); + assert(cloudp->query_url); + + len = strlen(cloudp->query_url); + len += strlen(NT_CLOUD_UPDATE_READ_CNT_PHP); + url = malloc(len+1); + if(!url) + return FALSE; + strcpy(url, cloudp->query_url); + strcat(url, NT_CLOUD_UPDATE_READ_CNT_PHP); + + post_data = malloc(buf_delta); + if(!post_data){ + free(url); + return FALSE; + } + + h_crypt = nt_crypt_get_handle(); + if(!h_crypt){ + free(url); + free(post_data); + return FALSE; + } + icd = iconv_open("cp932", "wchar_t"); + if(((iconv_t)-1) == icd){ + nt_crypt_release_ref(h_crypt); + free(url); + free(post_data); + return FALSE; + } + sprintf(post_data, "user=%s&token=%s", + cloudp->usr_id, cloudp->token); + + + if(!nt_wc_sjis_aes_b64_url_encode(icd, h_crypt, + board_name, + (unsigned char *)buf2, buf3, sizeof(buf3))){ + iconv_close(icd); + nt_crypt_release_ref(h_crypt); + free(url); + free(post_data); + return FALSE; + } + strcat(post_data, "&board_name="); + strcat(post_data, buf3); + + if(!nt_wc_sjis_aes_b64_url_encode(icd, h_crypt, + dat_name, + (unsigned char *)buf2, buf3, sizeof(buf3))){ + iconv_close(icd); + nt_crypt_release_ref(h_crypt); + free(url); + free(post_data); + return FALSE; + } + strcat(post_data, "&dat_name="); + strcat(post_data, buf3); + + assert(AES256_PASS); + if(!arrange_res_number(res_number, AES256_PASS, buf1, dat_name)){ + iconv_close(icd); + nt_crypt_release_ref(h_crypt); + free(url); + free(post_data); + return FALSE; + } + if(!nt_ascii_aes_b64_url_encode(icd, h_crypt, + buf1, (unsigned char *)buf2, buf3, sizeof(buf3))){ + iconv_close(icd); + nt_crypt_release_ref(h_crypt); + free(url); + free(post_data); + return FALSE; + } + iconv_close(icd); + strcat(post_data, "&res_number="); + strcat(post_data, buf3); + if(!nt_http_post(url, post_data, + buf1, sizeof(buf1), NULL, NULL, NULL, NULL)){ + free(post_data); + free(url); + return FALSE; + } + free(post_data); + free(url); + result_code = nt_get_cloud_result(buf1); + if(result_code == 301 && depth == 0){ + if(!nt_cloud_chk_user(handle)) + return FALSE; + return nt_cloud_update_read_count(handle, + board_name, dat_name, res_number, ++depth); + }else if(result_code != 100){ + return FALSE; + } + return TRUE; +} + +static nt_pthread_result_t update_read_count_fnc(void *param) +{ + nt_pthread_result_t result; + nt_link_tp linkp; + wchar_t *board_name, *dat_name; + int res_num; + nt_cloud_handle h_cloud; + + + result.code = 0; + result.data = NULL; + + linkp = (nt_link_tp)param; + if(4 != nt_link_num(linkp)){ + nt_all_link_free(linkp, NULL); + return result; + } + h_cloud = linkp->data; + board_name = linkp->next->data; + dat_name = linkp->next->next->data; + res_num = linkp->next->next->next->n_data; + nt_all_link_free(linkp, NULL); + + nt_cloud_update_read_count(h_cloud, + board_name, dat_name, res_num, 0); + + nt_cloud_release_ref(h_cloud); + free(board_name); + free(dat_name); + return result; +} + + +BOOL nt_cloud_query_board_attributes(nt_cloud_handle handle, + const wchar_t *board_name, nt_usr_db_handle db_handle, int depth) +{ + char *url, *post_data, *line, *cptr; + char buf1[1024]; + char buf2[1024]; + char buf3[1024]; + wchar_t wc[1024]; + nt_cloud_tp cloudp; + nt_link_tp linkp, wrkp; + wchar_t *dat_name; + char *last_query; + int len, i, read_cnt, r_type; + nt_crypt_handle h_crypt; + iconv_t icd; + static const int buf_delta = 1024; + int result_code; + + assert(handle); + assert(handle->chk_sum == NT_CLOUD_CHK_SUM); + cloudp = (nt_cloud_tp)handle; + assert(cloudp->usr_id); + assert(cloudp->token); + assert(cloudp->query_url); + + len = strlen(cloudp->query_url); + len += strlen(NT_CLOUD_QUERY_BOARD_ATTRIBUTES_PHP); + url = malloc(len+1); + if(!url) + return FALSE; + strcpy(url, cloudp->query_url); + strcat(url, NT_CLOUD_QUERY_BOARD_ATTRIBUTES_PHP); + + post_data = malloc(buf_delta); + if(!post_data){ + free(url); + return FALSE; + } + + h_crypt = nt_crypt_get_handle(); + if(!h_crypt){ + free(url); + free(post_data); + return FALSE; + } + icd = iconv_open("cp932", "wchar_t"); + if(((iconv_t)-1) == icd){ + nt_crypt_release_ref(h_crypt); + free(url); + free(post_data); + return FALSE; + } + sprintf(post_data, "user=%s&token=%s", + cloudp->usr_id, cloudp->token); + + + if(!nt_wc_sjis_aes_b64_url_encode(icd, h_crypt, + board_name, + (unsigned char *)buf2, buf3, sizeof(buf3))){ + iconv_close(icd); + nt_crypt_release_ref(h_crypt); + free(url); + free(post_data); + return FALSE; + } + iconv_close(icd); + + strcat(post_data, "&board_name="); + strcat(post_data, buf3); + last_query = nt_usr_db_board_last_query(db_handle, board_name); + if(last_query){ + strcat(post_data, "&last_query="); + strcat(post_data, last_query); + } + + if(!nt_http_post(url, post_data, + buf1, sizeof(buf1), NULL, NULL, NULL, NULL)){ + nt_crypt_release_ref(h_crypt); + if(last_query) + free(last_query); + free(post_data); + free(url); + return FALSE; + } + if(last_query) + free(last_query); + free(post_data); + free(url); + + result_code = nt_get_cloud_result(buf1); + if(result_code == 301 && depth == 0){ + if(!nt_cloud_chk_user(handle)){ + nt_crypt_release_ref(h_crypt); + return FALSE; + } + return nt_cloud_query_board_attributes(handle, + board_name, db_handle, ++depth); + }else if(result_code != 100){ + nt_crypt_release_ref(h_crypt); + return FALSE; + } + + linkp = nt_split_line(buf1); + if(!linkp){ + nt_crypt_release_ref(h_crypt); + return FALSE; + } + + /* There is little data. */ + if(nt_link_num(linkp) < 4){ + nt_crypt_release_ref(h_crypt); + return TRUE; + } + wrkp = linkp; + for(i = 0; i < 2; i++) + wrkp = wrkp->next; + + last_query = nt_str_clone((const char*)wrkp->data); + if(!last_query){ + nt_crypt_release_ref(h_crypt); + return FALSE; + } + wrkp = wrkp->next; + icd = iconv_open("wchar_t", "cp932"); + if(((iconv_t)-1) == icd){ + nt_crypt_release_ref(h_crypt); + free(last_query); + return FALSE; + } + while(wrkp != linkp){ + line = (char*)wrkp->data; + cptr = strchr(line, ','); + if(!cptr) + goto LABEL1; + *cptr = '\0'; + if(!nt_url_b64_aes_sjis_wc_decode(icd, h_crypt, + line, + (unsigned char *)buf2, wc, sizeof(buf2))){ + goto LABEL1; + } + dat_name = wc; + line = cptr+1; + cptr = strchr(line, ','); + if(!cptr) + goto LABEL1; + *cptr = '\0'; + if(!nt_url_b64_aes_ascii_decode(icd, h_crypt, + line, + (unsigned char *)buf2, buf3, sizeof(buf2))){ + goto LABEL1; + } + read_cnt = parse_res_number(buf3); + if(read_cnt == 0) + goto LABEL1; + line = cptr+1; + cptr = strchr(line, ','); + if(!cptr) + goto LABEL1; + *cptr = '\0'; + r_type = atoi(line); + line = cptr+1; + if(1 == r_type) + nt_usr_db_update_read_count(db_handle, + board_name, dat_name, read_cnt, line); + else if(4 == r_type) + nt_usr_db_delete_thread_log(db_handle, + board_name, dat_name, NULL); +LABEL1: + wrkp = wrkp->next; + } + nt_usr_db_update_read_count(db_handle, + board_name, L"query_time", 0, last_query); + + free(last_query); + nt_all_link_free(linkp, NULL); + iconv_close(icd); + nt_crypt_release_ref(h_crypt); + return TRUE; +} + +static nt_pthread_result_t query_attributes_func(void* data) +{ + nt_pthread_result_t result; + result.code = NT_PTHREAD_RESULT_NONE; + result.data = NULL; + nt_link_tp linkp; + nt_cloud_handle handle; + nt_usr_db_handle db_handle; + + linkp = (nt_link_tp)data; + assert(2 == nt_link_num(linkp)); + + handle = (nt_cloud_handle)linkp->data; + db_handle = (nt_usr_db_handle)linkp->next->data; + + if(nt_cloud_query_attributes(handle, db_handle, 0)){ + result.code = NT_PTHREAD_RESULT_UPDATE_FAVORITE; + } + nt_cloud_release_ref(handle); + nt_all_link_free(linkp, NULL); + return result; +} + +static nt_pthread_result_t query_attributes_result_func( + nt_pthread_result_t result) +{ + return result; +} + +BOOL nt_cloud_query_favorite_attributes_async(nt_cloud_handle handle, + nt_usr_db_handle db_handle) +{ + nt_pthread_handle h_pthread; + nt_link_tp linkp; + + nt_cloud_add_ref(handle); + linkp = nt_link_add_data(NULL, handle); + if(!linkp){ + nt_cloud_release_ref(handle); + return FALSE; + } + if(!nt_link_add_data(linkp, db_handle)){ + nt_cloud_release_ref(handle); + free(linkp); + return FALSE; + } + + + h_pthread = nt_pthread_alloc( + query_attributes_func, linkp, + query_attributes_result_func); + if(!h_pthread){ + nt_cloud_release_ref(handle); + nt_all_link_free(linkp, NULL); + return FALSE; + } + + if(!nt_pthread_put_que(h_pthread)){ + nt_pthread_release_ref(h_pthread); + nt_cloud_release_ref(handle); + nt_all_link_free(linkp, NULL); + return FALSE; + } + return TRUE; +} + +BOOL nt_cloud_query_attributes(nt_cloud_handle handle, + nt_usr_db_handle db_handle, int depth) +{ + char *url, *post_data, *line, *cptr; + char buf1[1024*16]; + char buf2[256]; + char buf3[256]; + wchar_t board_nm_buf[128]; + wchar_t dat_nm_buf[128]; + nt_cloud_tp cloudp; + nt_link_tp linkp, wrkp; + char *last_query; + int len, i, read_cnt, r_type; + nt_crypt_handle h_crypt; + iconv_t icd; + static const int buf_delta = 1024; + int result_code; + + assert(handle); + assert(handle->chk_sum == NT_CLOUD_CHK_SUM); + cloudp = (nt_cloud_tp)handle; + assert(cloudp->usr_id); + assert(cloudp->token); + assert(cloudp->query_url); + + len = strlen(cloudp->query_url); + len += strlen(NT_CLOUD_QUERY_ATTRIBUTES_PHP); + url = malloc(len+1); + if(!url) + return FALSE; + strcpy(url, cloudp->query_url); + strcat(url, NT_CLOUD_QUERY_ATTRIBUTES_PHP); + + post_data = malloc(buf_delta); + if(!post_data){ + free(url); + return FALSE; + } + + h_crypt = nt_crypt_get_handle(); + if(!h_crypt){ + free(url); + free(post_data); + return FALSE; + } + sprintf(post_data, "user=%s&token=%s", + cloudp->usr_id, cloudp->token); + + + last_query = nt_usr_db_board_last_query(db_handle, L"favorite"); + if(last_query){ + strcat(post_data, "&last_query="); + strcat(post_data, last_query); + } + + if(!nt_http_post(url, post_data, + buf1, sizeof(buf1), NULL, NULL, NULL, NULL)){ + nt_crypt_release_ref(h_crypt); + if(last_query) + free(last_query); + free(post_data); + free(url); + return FALSE; + } + if(last_query) + free(last_query); + free(post_data); + free(url); + + result_code = nt_get_cloud_result(buf1); + if(result_code == 301 && depth == 0){ + if(!nt_cloud_chk_user(handle)){ + nt_crypt_release_ref(h_crypt); + return FALSE; + } + return nt_cloud_query_attributes(handle, + db_handle, ++depth); + }else if(result_code != 100){ + nt_crypt_release_ref(h_crypt); + return FALSE; + } + + linkp = nt_split_line(buf1); + if(!linkp){ + nt_crypt_release_ref(h_crypt); + return FALSE; + } + + /* There is little data. */ + if(nt_link_num(linkp) < 4){ + nt_crypt_release_ref(h_crypt); + return TRUE; + } + wrkp = linkp; + for(i = 0; i < 2; i++) + wrkp = wrkp->next; + + last_query = nt_str_clone((const char*)wrkp->data); + if(!last_query){ + nt_crypt_release_ref(h_crypt); + return FALSE; + } + wrkp = wrkp->next; + icd = iconv_open("wchar_t", "cp932"); + if(((iconv_t)-1) == icd){ + nt_crypt_release_ref(h_crypt); + free(last_query); + return FALSE; + } + while(wrkp != linkp){ + line = (char*)wrkp->data; + cptr = strchr(line, ','); + if(!cptr) + goto LABEL1; + *cptr = '\0'; + if(!nt_url_b64_aes_sjis_wc_decode(icd, h_crypt, + line, + (unsigned char *)buf2, board_nm_buf, sizeof(board_nm_buf))){ + goto LABEL1; + } + //board_name = wc; + line = cptr+1; + cptr = strchr(line, ','); + if(!cptr) + goto LABEL1; + *cptr = '\0'; + if(!nt_url_b64_aes_sjis_wc_decode(icd, h_crypt, + line, + (unsigned char *)buf2, dat_nm_buf, sizeof(dat_nm_buf))){ + goto LABEL1; + } + //dat_name = wc; + line = cptr+1; + cptr = strchr(line, ','); + if(!cptr) + goto LABEL1; + *cptr = '\0'; + if(!nt_url_b64_aes_ascii_decode(icd, h_crypt, + line, + (unsigned char *)buf2, buf3, sizeof(buf2))){ + goto LABEL1; + } + read_cnt = parse_res_number(buf3); + if(read_cnt == 0) + goto LABEL1; + line = cptr+1; + cptr = strchr(line, ','); + if(!cptr) + goto LABEL1; + *cptr = '\0'; + r_type = atoi(line); + line = cptr+1; + if(1 == r_type) + nt_usr_db_update_read_count(db_handle, + board_nm_buf, dat_nm_buf, read_cnt, line); + else if(4 == r_type) + nt_usr_db_delete_thread_log(db_handle, + board_nm_buf, dat_nm_buf, NULL); +LABEL1: + wrkp = wrkp->next; + } + nt_usr_db_update_read_count(db_handle, + L"favorite", L"query_time", 0, last_query); + + free(last_query); + nt_all_link_free(linkp, NULL); + iconv_close(icd); + nt_crypt_release_ref(h_crypt); + return TRUE; +} + +void nt_cloud_delete_read_count_async(nt_cloud_handle handle, + const wchar_t *_board_name, const wchar_t *_dat_name) +{ + nt_link_tp param; + nt_pthread_handle h_pthread; + wchar_t *board_name, *dat_name; + + board_name = nt_w_str_clone(_board_name); + if(!board_name) + return; + dat_name = nt_w_str_clone(_dat_name); + if(!dat_name){ + free(board_name); + return; + } + param = nt_link_add_data(NULL, handle); + if(!param){ + free(board_name); + free(dat_name); + return; + } + nt_cloud_add_ref(handle); + if(!nt_link_add_data(param, board_name)){ + goto ERROR_TRAP; + } + if(dat_name){ + if(!nt_link_add_data(param, dat_name)){ + goto ERROR_TRAP; + } + } + h_pthread = nt_pthread_alloc( + delete_read_count_fnc, param, NULL); + if(!h_pthread){ + goto ERROR_TRAP; + } + + if(!nt_pthread_put_que(h_pthread)){ + nt_pthread_release_ref(h_pthread); + goto ERROR_TRAP; + } + + nt_pthread_release_ref(h_pthread); + return; +ERROR_TRAP: + nt_cloud_release_ref(handle); + nt_all_link_free(param, NULL); + free(board_name); + free(dat_name); + + +} + +static nt_pthread_result_t delete_read_count_fnc(void *param) +{ + nt_pthread_result_t result; + nt_link_tp linkp; + wchar_t *board_name, *dat_name; + int num; + nt_cloud_handle h_cloud; + + + result.code = 0; + result.data = NULL; + + linkp = (nt_link_tp)param; + num = nt_link_num(linkp); + if(2 != num && 3 != num){ + nt_all_link_free(linkp, NULL); + return result; + } + h_cloud = linkp->data; + board_name = linkp->next->data; + if(num == 3) + dat_name = linkp->next->next->data; + else + dat_name = NULL; + nt_all_link_free(linkp, NULL); + + nt_cloud_delete_read_count(h_cloud, + board_name, dat_name, 0); + + nt_cloud_release_ref(h_cloud); + free(board_name); + free(dat_name); + return result; +} +BOOL nt_cloud_delete_read_count(nt_cloud_handle handle, + const wchar_t *board_name, const wchar_t *dat_name, + int depth) +{ + char *url, *post_data; + char buf1[1024]; + char buf2[1024]; + char buf3[1024]; + nt_cloud_tp cloudp; + int len; + nt_crypt_handle h_crypt; + iconv_t icd; + static const int buf_delta = 1024; + int result_code; + + + assert(handle); + assert(handle->chk_sum == NT_CLOUD_CHK_SUM); + cloudp = (nt_cloud_tp)handle; + assert(cloudp->usr_id); + assert(cloudp->token); + assert(cloudp->query_url); + + len = strlen(cloudp->query_url); + len += strlen(NT_CLOUD_DELETE_READ_CNT_PHP); + url = malloc(len+1); + if(!url) + return FALSE; + strcpy(url, cloudp->query_url); + strcat(url, NT_CLOUD_DELETE_READ_CNT_PHP); + + post_data = malloc(buf_delta); + if(!post_data){ + free(url); + return FALSE; + } + + h_crypt = nt_crypt_get_handle(); + if(!h_crypt){ + free(url); + free(post_data); + return FALSE; + } + icd = iconv_open("cp932", "wchar_t"); + if(((iconv_t)-1) == icd){ + nt_crypt_release_ref(h_crypt); + free(url); + free(post_data); + return FALSE; + } + sprintf(post_data, "user=%s&token=%s", + cloudp->usr_id, cloudp->token); + + + if(!nt_wc_sjis_aes_b64_url_encode(icd, h_crypt, + board_name, + (unsigned char *)buf2, buf3, sizeof(buf3))){ + iconv_close(icd); + nt_crypt_release_ref(h_crypt); + free(url); + free(post_data); + return FALSE; + } + strcat(post_data, "&board_name="); + strcat(post_data, buf3); + + if(dat_name){ + if(!nt_wc_sjis_aes_b64_url_encode(icd, h_crypt, + dat_name, + (unsigned char *)buf2, buf3, sizeof(buf3))){ + iconv_close(icd); + nt_crypt_release_ref(h_crypt); + free(url); + free(post_data); + return FALSE; + } + strcat(post_data, "&dat_name="); + strcat(post_data, buf3); + }else{ + strcat(post_data, "&dat_name=*"); + } + iconv_close(icd); + nt_crypt_release_ref(h_crypt); + + if(!nt_http_post(url, post_data, + buf1, sizeof(buf1), NULL, NULL, NULL, NULL)){ + free(post_data); + return FALSE; + } + free(post_data); + free(url); + + result_code = nt_get_cloud_result(buf1); + if(result_code == 301 && depth == 0){ + if(!nt_cloud_chk_user(handle)){ + return FALSE; + } + return nt_cloud_delete_read_count(handle, + board_name, dat_name, ++depth); + }else if(result_code != 100){ + return FALSE; + } + + return TRUE; +} + + + +static BOOL arrange_res_number( + int number, const char *seed, char *buf, const wchar_t *dat_name) +{ + int i, n, len; + char c; + wchar_t *wptr; + + + len = wcslen(dat_name); + assert(len > 0); + wptr = wcschr(dat_name, L'.'); + if(wptr && wptr > dat_name){ + c = (char)*(wptr-1); + }else{ + c = (char)dat_name[len-1]; + } + n = number; + i = 0; + do{ + buf[i] = '0' + n % 10; + n /= 10; + i += 2; + }while(n); + + for( ;i < 15; i+=2) + buf[i] = ' '; + + len = strlen(seed); + + for(i = 1; i < 15; i+=2){ + if(i/2 < len) + buf[i] = seed[i/2]; + else + buf[i] = ' '; + } + buf[13] = c; + buf[15] = '\0'; + return TRUE; +} + +static int parse_res_number(const char *buf) +{ + int i, n, len; + int coefficient; + char c; + + len = strlen(buf); + assert(len == 15); + + coefficient = 1; + n = 0; + for(i = 0; i < 15; i+=2){ + c = buf[i]; + if(c < '0' || c > '9') + break; + n += (c - '0') * coefficient; + coefficient *= 10; + } + return n; +} + diff --git a/src/env.c b/src/env.c index 5b975ce..bf2fcba 100644 --- a/src/env.c +++ b/src/env.c @@ -57,6 +57,8 @@ char *NCE_AUTH_URL; char *NCE_ID; char *NCE_PASS; +char CA_FILE_PATH[1024]; + static char *app_name = PACKAGE_NAME; static char *version_name = PACKAGE_VERSION; static char *def_editor_cmd = "vi"; @@ -69,7 +71,9 @@ struct option longopts[] = { {"version", 0, NULL, 'v'}, {"help", 0, NULL, 'h'}, {"editor", 1, NULL, 'e'}, - {"out-path", 1, NULL, 'o'} + {"out-path", 1, NULL, 'o'}, + {"pem", 1, NULL, 'p'}, + {NULL, 0, NULL, 0} }; extern void print_help(); @@ -101,6 +105,7 @@ int set_option(int argc, char* argv[]) NCE_AUTH_URL = NULL; NCE_ID = NULL; NCE_PASS = NULL; + CA_FILE_PATH[0] = '\0'; NT_MAINLOOP_POLLING_INTERVAL = 100; NT_PTHREAD_POOL_SIZE = 5; @@ -137,7 +142,7 @@ int set_option(int argc, char* argv[]) } while((opt = getopt_long( - argc, argv, "hvro:", longopts, NULL)) != -1){ + argc, argv, "hvro:p:", longopts, NULL)) != -1){ switch(opt){ case 'r': @@ -154,7 +159,7 @@ int set_option(int argc, char* argv[]) case 'o': printf("output path: %s\n", optarg); len = strlen(optarg); - if(len == 0) + if(len == 0 || len > sizeof(LOG_PATH)-5) break; strcpy(LOG_PATH, optarg); if(LOG_PATH[len-1] != '/'){ @@ -162,10 +167,21 @@ int set_option(int argc, char* argv[]) } strcpy(LOG_PATH+len, "log"); break; + case 'p': + printf("ca file path: %s\n", optarg); + len = strlen(optarg); + if(len == 0 || len > sizeof(CA_FILE_PATH)-1) + break; + strcpy(CA_FILE_PATH, optarg); + break; default: break; } } + + if(CA_FILE_PATH[0] == '\0'){ + strcpy(CA_FILE_PATH, "cacert.pem"); + } /*for(; optind < argc; optind++){ fprintf(stderr, "Unrecognized argument %s\n", argv[optind]); @@ -187,6 +203,8 @@ extern BOOL read_resource(const char *path) return FALSE; while(fgets(buf, sizeof(buf), fp)){ + if(buf[0] == '#') + continue; cptr = strchr(buf, '='); if(!cptr) continue; diff --git a/src/inc/cloud/nt_cloud.h b/src/inc/cloud/nt_cloud.h index 39d39b2..f2255ce 100644 --- a/src/inc/cloud/nt_cloud.h +++ b/src/inc/cloud/nt_cloud.h @@ -19,9 +19,10 @@ #ifndef _NT_CLOUD_H_ #define _NT_CLOUD_H_ +#include "usr/usr_db_t.h" + #ifdef NT_CLOUD -#define NT_CLOUD_TEST_SERVER ("https://neetchan.securesite.jp/test.php") typedef struct tag_nt_cloud_handle *nt_cloud_handle; typedef struct tag_nt_cloud_handle{ @@ -41,8 +42,79 @@ extern BOOL nt_cloud_insert_lines_into_file(nt_cloud_handle handle, extern BOOL nt_cloud_delete_lines_from_file(nt_cloud_handle handle, const char *file_name, nt_link_tp lines); +extern void nt_cloud_update_read_count_async(nt_cloud_handle handle, + const wchar_t *board_name, const wchar_t *dat_name, + int res_number); +extern BOOL nt_cloud_update_read_count(nt_cloud_handle handle, + const wchar_t *board_name, const wchar_t *dat_name, + int res_number, int depth); +extern BOOL nt_cloud_query_board_attributes(nt_cloud_handle handle, + const wchar_t *board_name, nt_usr_db_handle db_handle, int depth); + +extern void nt_cloud_delete_read_count_async(nt_cloud_handle handle, + const wchar_t *board_name, const wchar_t *dat_name); +extern BOOL nt_cloud_delete_read_count(nt_cloud_handle handle, + const wchar_t *board_name, const wchar_t *dat_name, + int depth); + +extern BOOL nt_cloud_query_favorite_attributes_async(nt_cloud_handle handle, + nt_usr_db_handle db_handle); +extern BOOL nt_cloud_query_attributes(nt_cloud_handle handle, + nt_usr_db_handle db_handle, int depth); + + + +extern nt_cloud_handle nt_cloud_get_handle(); extern int nt_cloud_add_ref(nt_cloud_handle); extern int nt_cloud_release_ref(nt_cloud_handle); +#ifdef NT_CLOUD_PRIVATE + +#define NT_CLOUD_CHK_SUM (1478428) + +typedef struct tag_nt_cloud_t *nt_cloud_tp; +typedef struct tag_nt_cloud_t { + nt_cloud_handle_t handle; + int ref_count; + char *usr_id; + char *passwd; + char *auth_url; + char *query_url; + char *home_url; + char *token; + int error_no; +}nt_cloud_t; + +extern int nt_get_cloud_result(const char *ptr); +extern nt_link_tp nt_split_line(char *data); + +extern BOOL nt_wc_sjis_aes_b64_url_encode( + iconv_t icd, nt_crypt_handle h_crypt, + const wchar_t *in_data, + unsigned char *wrk_buf, char *out_data, size_t max_len); +extern BOOL nt_url_b64_aes_sjis_wc_decode( + iconv_t icd, nt_crypt_handle h_crypt, + const char *in_data, + unsigned char *wrk_buf, wchar_t *out_data, size_t max_len); + +extern BOOL nt_ascii_aes_b64_url_encode( + iconv_t icd, nt_crypt_handle h_crypt, + const char *in_data, + unsigned char *wrk_buf, char *out_data, size_t max_len); +extern BOOL nt_url_b64_aes_ascii_decode( + iconv_t icd, nt_crypt_handle h_crypt, + const char *in_data, + unsigned char *wrk_buf, char *out_data, size_t max_len); + +#define NT_CLOUD_INSERT_LINES_FILE_PHP "nc_insert_lines_file.php" +#define NT_CLOUD_DELETE_LINES_FILE_PHP "nc_delete_lines_file.php" +#define NT_CLOUD_WRITE_FILE_PHP "nc_write_file.php" +#define NT_CLOUD_UPDATE_READ_CNT_PHP "nc_update_readcnt_db.php" +#define NT_CLOUD_QUERY_ATTRIBUTES_PHP "nc_query_attributes_db.php" +#define NT_CLOUD_QUERY_BOARD_ATTRIBUTES_PHP "nc_query_board_attributes_db.php" +#define NT_CLOUD_DELETE_READ_CNT_PHP "nc_delete_readcnt_db.php" + +#endif /*NT_CLOUD_PRIVATE*/ + #endif /*NT_CLOUD*/ #endif /*_NT_CLOUD_H_*/ diff --git a/src/inc/config.h b/src/inc/config.h index 9fe9b3b..2777958 100644 --- a/src/inc/config.h +++ b/src/inc/config.h @@ -141,7 +141,7 @@ #define PACKAGE_NAME "ntch" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "ntch 1.0.2.2" +#define PACKAGE_STRING "ntch 1.0.2.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "ntch" @@ -150,7 +150,7 @@ #define PACKAGE_URL "https://sourceforge.jp/projects/ntch/" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.0.2.2" +#define PACKAGE_VERSION "1.0.2.3" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 diff --git a/src/inc/env.h b/src/inc/env.h index dce62df..cee539f 100644 --- a/src/inc/env.h +++ b/src/inc/env.h @@ -33,6 +33,7 @@ extern char *AES256_PASS; extern char *NCE_AUTH_URL; extern char *NCE_ID; extern char *NCE_PASS; +extern char CA_FILE_PATH[]; extern int FORCE_REFRESH; extern int THREAD_SORT_TYPE; @@ -74,6 +75,7 @@ extern char *MARU_PW; #define NT_KEY_COMMAND3 '?' #define NT_KEY_CMD_BOARD_UPDATE (65536 + 1) #define NT_KEY_CMD_AUTO_SCROLL (65536 + 2) +#define NT_KEY_CMD_FAVORITE_UPDATE (65536 + 3) #define NT_COMMAND1_WRITE_MSG_1 "write" #define NT_COMMAND1_WRITE_MSG_2 "w" diff --git a/src/inc/usr/usr_db_t.h b/src/inc/usr/usr_db_t.h index 85c08d4..768c15f 100644 --- a/src/inc/usr/usr_db_t.h +++ b/src/inc/usr/usr_db_t.h @@ -38,7 +38,8 @@ extern void nt_usr_db_finish_lib(nt_usr_db_handle db_handle); extern BOOL nt_usr_db_open(nt_usr_db_handle db_handle); extern void nt_usr_db_close(nt_usr_db_handle db_handle); extern int nt_usr_db_update_read_count(nt_usr_db_handle db_handle, - const wchar_t *board_name, const wchar_t *dat_name, int prev_read); + const wchar_t *board_name, const wchar_t *dat_name, int prev_read, + const char *date_time); extern nt_link_tp nt_usr_db_query_read_count_list(nt_usr_db_handle db_handle, const wchar_t *board_name); extern BOOL nt_usr_db_delete_board_log(nt_usr_db_handle db_handle, @@ -46,6 +47,8 @@ extern BOOL nt_usr_db_delete_board_log(nt_usr_db_handle db_handle, extern BOOL nt_usr_db_delete_thread_log(nt_usr_db_handle db_handle, const wchar_t *board_name, const wchar_t *dat_name, nt_link_tp *thread_data_list); +extern char* nt_usr_db_board_last_query(nt_usr_db_handle db_handle, + const wchar_t *board_name); #endif /* __USR_DB_T_H_ */ diff --git a/src/inc/utils/nt_pthread.h b/src/inc/utils/nt_pthread.h index 30f9654..9fcf3ee 100644 --- a/src/inc/utils/nt_pthread.h +++ b/src/inc/utils/nt_pthread.h @@ -23,6 +23,7 @@ #define NT_PTHREAD_RESULT_NONE 0 #define NT_PTHREAD_RESULT_UPDATE_BOARD 1 +#define NT_PTHREAD_RESULT_UPDATE_FAVORITE 2 typedef struct tag_nt_pthread_handle *nt_pthread_handle; typedef struct tag_nt_pthread_handle{ diff --git a/src/main.c b/src/main.c index fdeb504..7743c7c 100644 --- a/src/main.c +++ b/src/main.c @@ -176,6 +176,8 @@ int main(int argc, char *argv[]) #ifdef NT_CLOUD if(h_cloud){ text_linkp = nt_cloud_download_file(h_cloud, "ft.txt"); + nt_cloud_query_favorite_attributes_async(h_cloud, usr_db_handle); + //nt_cloud_query_attributes(h_cloud, usr_db_handle, 0); } #endif if(!text_linkp) @@ -801,6 +803,9 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, if(async_data.code == NT_PTHREAD_RESULT_UPDATE_BOARD){ ch = NT_KEY_CMD_BOARD_UPDATE; //fprintf(stderr, "Async result recieved.!\n"); + }else if(async_data.code == NT_PTHREAD_RESULT_UPDATE_FAVORITE){ + ch = NT_KEY_CMD_FAVORITE_UPDATE; + //fprintf(stderr, "Async result recieved.!\n"); }else{ h_timer = nt_timer_ring_a_bell(); if(h_timer){ diff --git a/src/net/nt_http.c b/src/net/nt_http.c index b776566..7429640 100644 --- a/src/net/nt_http.c +++ b/src/net/nt_http.c @@ -27,6 +27,7 @@ #include #include +#include "env.h" #include "utils/nt_std_t.h" #include "utils/text.h" #include "utils/zip.h" @@ -138,7 +139,7 @@ int nt_http_post2(const char *url, const char *post_data, if(IS_SET_FLAG(headerp,SSL_FLAG)){ data_len = strlen(data); sprintf(ssl_connect, "%s:443", headerp->host); - if(!nt_ssl_connect(ssl_connect, "cacert.pem", FALSE, + if(!nt_ssl_connect(ssl_connect, CA_FILE_PATH, FALSE, data, &data_len, sizeof(data))){ nt_http_free_header(headerp); return result; @@ -224,7 +225,7 @@ int nt_http_post2(const char *url, const char *post_data, result = 0; }else if(IS_SET_FLAG(responsep, CHUNKED_FLAG)){ p3 = p1 = out_buf; - while(0 < (nread = strtol(p1, &p2, 10))){ + while(0 < (nread = strtol(p1, &p2, 16))){ memcpy(p3, p2+2, nread); p3 += nread; p1 = p2 + nread + 4; @@ -316,7 +317,7 @@ BOOL nt_http_get(const char *url, const char *out_path, if(IS_SET_FLAG(headerp,SSL_FLAG)){ data_len = strlen(data); sprintf(ssl_connect, "%s:443", headerp->host); - if(!nt_ssl_connect(ssl_connect, "cacert.pem", FALSE, + if(!nt_ssl_connect(ssl_connect, CA_FILE_PATH, FALSE, data, &data_len, sizeof(data))){ nt_http_free_header(headerp); return FALSE; diff --git a/src/ui/disp_favorite.c b/src/ui/disp_favorite.c index dcd0e90..dc43550 100644 --- a/src/ui/disp_favorite.c +++ b/src/ui/disp_favorite.c @@ -99,9 +99,14 @@ int disp_favorite(nt_window_tp wp, } switch(wp->key){ + case NT_KEY_CMD_FAVORITE_UPDATE: + if(!nt_favorite_set_read_count(h_favorite, h_usr_db)){ + fputs("Couldn't open user_db handle", stderr); + } + break; case NT_KEY_CMD_BOARD_UPDATE: if(!nt_favorite_set_num_res(h_model, h_favorite)){ - fputs("Couldn't open user_db handle", stderr); + fputs("Couldn't set res count into favorite thread", stderr); } break; case NT_KEY_REFRESH: diff --git a/src/ui/disp_reslist.c b/src/ui/disp_reslist.c index 5e62ebf..26f160a 100644 --- a/src/ui/disp_reslist.c +++ b/src/ui/disp_reslist.c @@ -234,6 +234,7 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_ switch(ch){ case NT_KEY_CMD_BOARD_UPDATE: + case NT_KEY_CMD_FAVORITE_UPDATE: if(auto_scroll_state != AUTO_SCROLL_NONE){ result_state |= DISP_CMD_AUTO_SCROLL; ctxp->auto_scroll = auto_scroll_state; @@ -972,7 +973,7 @@ static ctx_reslist_tp init_context(nt_2ch_selected_item_handle h_select, ctxp->prev_read_cnt = nt_usr_db_update_read_count(usr_db_handle, board_name, dat_name, - ctxp->res_num); + ctxp->res_num, NULL); if(ctxp->prev_read_cnt < 0) ctxp->prev_read_cnt = 0; if(ctxp->prev_read_cnt > 0){ diff --git a/src/ui/disp_threadlist.c b/src/ui/disp_threadlist.c index c7e1659..93a555c 100644 --- a/src/ui/disp_threadlist.c +++ b/src/ui/disp_threadlist.c @@ -33,6 +33,7 @@ #include "utils/text.h" #include "ui/disp.h" #include "ui/disp_string.h" +#include "cloud/nt_cloud.h" typedef struct tag_ctx_threadlist_t *ctx_threadlist_tp; typedef struct tag_ctx_threadlist_t @@ -131,6 +132,8 @@ int disp_threadlist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle const char *start, *end; char *cptr; int result_state; + nt_cloud_handle h_cloud; + BOOL b_ret; result_state = DISP_STATE_THREADTITLE; sort = FALSE; @@ -151,6 +154,14 @@ int disp_threadlist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle board_name = nt_board_get_name(h_board); if(!ctxp->thread_data_list){ + h_cloud = nt_cloud_get_handle(); + if(h_cloud){ + if(nt_cloud_query_board_attributes(h_cloud, + board_name, db_handle, 0)){ + + } + nt_cloud_release_ref(h_cloud); + } ctxp->thread_data_list = nt_usr_db_query_read_count_list( db_handle, board_name); @@ -254,6 +265,15 @@ int disp_threadlist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle if(!nt_usr_db_delete_board_log(db_handle, board_name)) break; + h_cloud = nt_cloud_get_handle(); + if(h_cloud){ + if(!nt_cloud_delete_read_count(h_cloud, + board_name, NULL, 0)){ + nt_cloud_release_ref(h_cloud); + break; + } + nt_cloud_release_ref(h_cloud); + } result_state = DISP_STATE_REFRESH; goto ERROR_TRAP; } @@ -263,6 +283,7 @@ int disp_threadlist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle break; clistp = linkp; num = -1; + h_cloud = nt_cloud_get_handle(); do{ threadp = get_thread_by_seq_no( ctxp->thread_disp_list, linkp->n_data); @@ -270,14 +291,20 @@ int disp_threadlist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle break; if(linkp->n_data != num){ - nt_usr_db_delete_thread_log(db_handle, + b_ret = nt_usr_db_delete_thread_log(db_handle, board_name, threadp->dat_name, &ctxp->thread_data_list); + if(b_ret && h_cloud){ + (void)nt_cloud_delete_read_count(h_cloud, + board_name, threadp->dat_name, 0); + } num = linkp->n_data; } linkp = linkp->next; }while(clistp != linkp); + if(h_cloud) + nt_cloud_release_ref(h_cloud); nt_all_link_free(linkp, NULL); result_state = DISP_STATE_REFRESH; goto ERROR_TRAP; @@ -457,7 +484,7 @@ int disp_threadlist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle } }else{ if(-1 < swprintf( - buf, sizeof(buf)-1, L"(%d) 未読:%d ", + buf, sizeof(buf)/sizeof(wchar_t)-1, L"(%d) 未読:%d ", threadp->num_res, threadp->num_res - read_count)){ } diff --git a/src/usr/favorite_t.c b/src/usr/favorite_t.c index a6a9a71..606ba16 100644 --- a/src/usr/favorite_t.c +++ b/src/usr/favorite_t.c @@ -1166,7 +1166,8 @@ BOOL nt_favorite_set_read_count(nt_favorite_handle h_favorite, nt_usr_db_handle read_count = nt_usr_db_get_read_count_by_dat_name( linkp, dat_name); if(read_count == -1) - continue; + read_count = 0; + //continue; nt_favorite_thread_set_read_count(h_thread, read_count); } diff --git a/src/usr/usr_db_t.c b/src/usr/usr_db_t.c index a0c747e..310c200 100644 --- a/src/usr/usr_db_t.c +++ b/src/usr/usr_db_t.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "env.h" #include "utils/nt_std_t.h" @@ -49,7 +50,7 @@ static const char *NT_SQL_CREATE_USR_TBL = "CREATE TABLE usr_log (id INTEGER PRIMARY KEY AUTOINCREMENT, " "rec_type INTEGER NOT NULL, res_no INTEGER NOT NULL, " "board_name TEXT NOT NULL, dat_name TEXT NOT NULL, " - "date_time REAL)"; + "date_time TEXT)"; static const char *NT_SQL_QUERY_READ_CNT_LIST = "SELECT dat_name, res_no FROM usr_log WHERE " @@ -61,7 +62,7 @@ static const char *NT_SQL_QUERY_READ_CNT = static const char *NT_SQL_UPDATE_READ_CNT = "UPDATE usr_log SET res_no = :res_no, " - "date_time = julianday(\'now\') WHERE " + "date_time = :date_time WHERE " "rec_type = 1 AND board_name = :board_name AND " "dat_name = :dat_name "; @@ -69,7 +70,7 @@ static const char *NT_SQL_INSERT_READ_CNT = "INSERT INTO usr_log (rec_type, res_no, board_name, " "dat_name, date_time) " "VALUES (1, :res_no, :board_name, :dat_name, " - "julianday(\'now\') )"; + " :date_time )"; static const char *NT_SQL_DELETE_BOARD_LOG = "DELETE FROM usr_log WHERE " @@ -79,6 +80,11 @@ static const char *NT_SQL_DELETE_THREAD_LOG = "DELETE FROM usr_log WHERE " "board_name = :board_name AND dat_name = :dat_name "; +static const char *NT_SQL_QUERY_BOARD_LAST_QUERY = + "SELECT date_time FROM usr_log WHERE rec_type = 1 " + "AND board_name = :board_name AND dat_name = 'query_time' "; + + static BOOL usr_tbl_create(sqlite3 *dbp); static int usr_tbl_validate(sqlite3 *dbp); @@ -227,9 +233,9 @@ nt_link_tp nt_usr_db_query_read_count_list(nt_usr_db_handle db_handle, ctxp = (ctx_usr_db_tp)db_handle; len = wcstombs(board_nm_buf, board_name, sizeof(board_nm_buf)); - if(len <= 0) + if(len <= 0){ return NULL; - + } if(!nt_usr_db_open(db_handle)){ return NULL; } @@ -296,14 +302,17 @@ ERROR_TRAP: int nt_usr_db_update_read_count(nt_usr_db_handle db_handle, const wchar_t *board_name, const wchar_t *dat_name, - int new_read_cnt) + int new_read_cnt, const char *date_time) { int len, result; int rc , idx; ctx_usr_db_tp ctxp; char board_nm_buf[256]; char dat_nm_buf[256]; + char date_time_buf[256]; sqlite3_stmt *stmt; + struct tm tm; + time_t ti; assert(db_handle); assert(db_handle->chk_sum == NT_USR_DB_CHK_SUM); @@ -344,6 +353,7 @@ int nt_usr_db_update_read_count(nt_usr_db_handle db_handle, dat_nm_buf, -1, SQLITE_STATIC)){ goto ERROR_TRAP; } + rc = sqlite3_step(stmt); if(rc == SQLITE_ROW){ result = sqlite3_column_int(stmt, 0); @@ -383,6 +393,26 @@ int nt_usr_db_update_read_count(nt_usr_db_handle db_handle, SQLITE_OK != sqlite3_bind_int(stmt, idx, new_read_cnt)){ goto ERROR_TRAP; } + idx = sqlite3_bind_parameter_index(stmt, ":date_time"); + if(idx == 0){ + goto ERROR_TRAP; + } + if(!date_time){ + //strcpy(date_time_buf, "now"); + if(((time_t) -1) == time(&ti)) + goto ERROR_TRAP; + if(!localtime_r(&ti, &tm)) + goto ERROR_TRAP; + strftime(date_time_buf, sizeof(date_time_buf), + "%Y-%m-%d %H:%M:%S", &tm); + }else{ + strcpy(date_time_buf, date_time); + } + + if(SQLITE_OK != sqlite3_bind_text(stmt, idx, + date_time_buf, -1, SQLITE_STATIC)){ + goto ERROR_TRAP; + } rc = sqlite3_step(stmt); if(rc != SQLITE_DONE){ goto ERROR_TRAP; @@ -395,6 +425,68 @@ ERROR_TRAP: return result; } +char* nt_usr_db_board_last_query(nt_usr_db_handle db_handle, + const wchar_t *board_name) +{ + int len; + int rc , idx; + ctx_usr_db_tp ctxp; + char board_nm_buf[256]; + sqlite3_stmt *stmt; + char* result; + const unsigned char *last_query; + + assert(db_handle); + assert(db_handle->chk_sum == NT_USR_DB_CHK_SUM); + assert(board_name); + + stmt = NULL; + result = NULL; + + ctxp = (ctx_usr_db_tp)db_handle; + + len = wcstombs(board_nm_buf, board_name, sizeof(board_nm_buf)); + if(len <= 0) + return NULL; + + if(!nt_usr_db_open(db_handle)){ + return NULL; + } + + rc = sqlite3_prepare_v2(ctxp->dbp, + NT_SQL_QUERY_BOARD_LAST_QUERY, -1, + &stmt, NULL); + if(rc != SQLITE_OK){ + fputs(sqlite3_errmsg(ctxp->dbp), stderr); + goto ERROR_TRAP; + } + idx = sqlite3_bind_parameter_index(stmt, ":board_name"); + if(idx == 0 || + SQLITE_OK != sqlite3_bind_text(stmt, idx, + board_nm_buf, -1, SQLITE_STATIC)){ + goto ERROR_TRAP; + } + + if(SQLITE_ROW != (rc = sqlite3_step(stmt))){ + goto ERROR_TRAP; + } + last_query = sqlite3_column_text(stmt, 0); + if(last_query == NULL) + goto ERROR_TRAP; + result = nt_str_clone((const char*)last_query); + rc = sqlite3_step(stmt); + if(rc != SQLITE_DONE){ + free(result); + goto ERROR_TRAP; + } +ERROR_TRAP: + if(stmt) + sqlite3_finalize(stmt); + nt_usr_db_close(db_handle); + return result; +} + + BOOL nt_usr_db_delete_board_log(nt_usr_db_handle db_handle, const wchar_t *board_name) { diff --git a/src/utils/text.c b/src/utils/text.c index 803ca67..c3b60ca 100644 --- a/src/utils/text.c +++ b/src/utils/text.c @@ -31,7 +31,7 @@ wchar_t* nt_w_str_resize(wchar_t *old_src, size_t old_size, size_t new_size) assert(old_size < new_size && new_size > 0); - wrk_buf = malloc(sizeof(wchar_t) * (new_size)); + wrk_buf = malloc(sizeof(wchar_t) * (new_size+1)); if(!wrk_buf){ return NULL; } @@ -136,7 +136,7 @@ wchar_t *nt_w_trim(const wchar_t *source) }/* end for */ assert(i <= j); len = j - i + 1; - cptr = malloc(sizeof(wchar_t)*(len + 1)); + cptr = malloc(sizeof(wchar_t)*(len + 2)); if(cptr != NULL){ memcpy(cptr, source+i, len*sizeof(wchar_t)); cptr[len] = '\0'; @@ -152,6 +152,7 @@ wchar_t *nt_w_trim_quotes(const wchar_t *source) wchar_t *cptr; BOOL dquote = FALSE; BOOL squote = FALSE; + size_t buf_len; for(i=0; i= 0); assert(start <= end); len = end - start; - cptr = malloc(len + 1); + buf_len = len + 1; + if(buf_len % 8) + buf_len += 8 - (buf_len % 8); + cptr = malloc(buf_len); if(!cptr) return NULL; @@ -339,12 +361,17 @@ wchar_t* nt_w_substr(const wchar_t* src, int start, int end) { wchar_t *cptr; int len; + size_t buf_len; assert(start >= 0); assert(start <= end); len = end - start; - cptr = malloc((len + 1)*sizeof(wchar_t)); + buf_len = len + 1; + buf_len *= sizeof(wchar_t); + if(buf_len % 8) + buf_len += 8 - (buf_len % 8); + cptr = malloc(buf_len); if(!cptr) return NULL; -- 2.11.0