#include "StdAfx.h" #include "global/global.h" #include "global/passwd_crypt.h" #include "net_store.h" net_store::net_store(const char* smtp_addr, int smtp_port, const char* pop3_addr, int pop3_port, const char* user, const char* pass, const char* recipients, net_store_callback* callback, bool store /* = false */) : smtp_addr_(smtp_addr) , smtp_port_(smtp_port) , pop3_addr_(pop3_addr) , pop3_port_(pop3_port) , user_(user) , pass_(pass) , recipients_(recipients) , callback_(callback) , store_(store) { } net_store::~net_store() { } ////////////////////////////////////////////////////////////////////////// bool create_option_tbl(acl::db_handle& db, const char* tbl_name, const char* sql_create) { if (db.tbl_exists(tbl_name)) { logger("table(%s) exist", tbl_name); return (true); } else if (db.sql_update(sql_create) == false) { logger_error("sql(%s) error", sql_create); return (false); } else { logger("create table %s ok", tbl_name); return (true); } } ////////////////////////////////////////////////////////////////////////// static const char* CREATE_OPT_TBL = "create table option_tbl" "(\r\n" "name varchar(128) not null default '',\r\n" "value varchar(256) not null default '',\r\n" "PRIMARY KEY(name)" ")"; static acl::db_handle* open_option_tbl() { const char* path = global::get_instance().get_path(); acl::string dbpath; dbpath.format("%s/net_store.db", path); acl::db_handle* db = new acl::db_sqlite(dbpath.c_str()); if (db->open() == false) { logger_error("open db: %s failed", dbpath.c_str()); delete db; return NULL; } else if (create_option_tbl(*db, "option_tbl", CREATE_OPT_TBL) == false) { delete db; return NULL; } else return db; } bool net_store::get_key(const char* name, acl::string& out) { acl::db_handle* db = open_option_tbl(); if (db == NULL) return false; acl::string sql; sql.format("select value from option_tbl where name='%s'", name); if (db->sql_select(sql.c_str()) == false) { delete db; return false; } const acl::db_row* row = db->get_first_row(); if (row == NULL) { delete db; return false; } const char* value = (*row)["value"]; if (value == NULL) { db->free_result(); delete db; return false; } out = value; return true; } bool net_store::set_key(const char* name, const char* value) { acl::db_handle* db = open_option_tbl(); if (db == NULL) return false; acl::string sql; sql.format("insert into option_tbl(name, value) values('%s', '%s')", name, value); if (db->sql_update(sql.c_str()) == false) { sql.format("update option_tbl set value='%s' where name='%s'", value, name); db->sql_update(sql.c_str()); delete db; return false; } else { delete db; return true; } } ////////////////////////////////////////////////////////////////////////// // 主线程中运行 void net_store::rpc_onover() { callback_->load_db_callback(smtp_addr_.c_str(), smtp_port_, pop3_addr_.c_str(), pop3_port_, user_.c_str(), pass_.c_str(), recipients_.c_str(), store_); delete this; } ////////////////////////////////////////////////////////////////////////// // 子线程中运行 static const char* CREATE_MAIL_TBL = "create table mail_tbl\r\n" "(\r\n" "smtp_addr varchar(128) not null,\r\n" "smtp_port int not null,\r\n" "pop3_addr varchar(128) not null default '',\r\n" "pop3_port int not null,\r\n" "user varchar(128) not null default '',\r\n" "pass varchar(128) not null default '',\r\n" "recipients varchar(256) not null default '',\r\n" "PRIMARY KEY(user)" ")"; void net_store::rpc_run() { const char* path = global::get_instance().get_path(); dbpath_.format("%s/net_store.db", path); acl::db_sqlite db(dbpath_.c_str()); if (db.open() == false) logger_error("open db: %s failed", dbpath_.c_str()); else if (create_mail_tbl(db, "mail_tbl", CREATE_MAIL_TBL) == false) logger_error("create table failed for %s", dbpath_.c_str()); else if (store_) save_mail_db(db); else load_mail_db(db); } bool net_store::create_mail_tbl(acl::db_handle& db, const char* tbl_name, const char* sql_create) { if (db.tbl_exists(tbl_name)) { logger("table(%s) exist", tbl_name); return (true); } else if (db.sql_update(sql_create) == false) { logger_error("sql(%s) error", sql_create); return (false); } else { save_mail_db(db); logger("create table %s ok", tbl_name); return (true); } } void net_store::save_mail_db(acl::db_handle& db) { acl::string sql; // 先删除原来所有的记录 sql.format("delete from mail_tbl"); db.sql_update(sql.c_str()); acl::string smtp_addr, pop3_addr, user, pass, recipients; db.escape_string(smtp_addr_.c_str(), smtp_addr_.length(), smtp_addr); db.escape_string(pop3_addr_.c_str(), pop3_addr_.length(), pop3_addr); db.escape_string(user_.c_str(), user_.length(), user); db.escape_string(pass_.c_str(), pass_.length(), pass); ACL_ARGV* tokens = acl_argv_split(recipients_.c_str(), "\t,;\r\n"); ACL_ITER iter; acl::string buf; acl_foreach(iter, tokens) { if (iter.i > 0) buf << ","; buf << (char*) iter.data; } acl_argv_free(tokens); db.escape_string(buf.c_str(), recipients_.length(), recipients); // 密码需要加密存储 char* pass_crypted = passwd_crypt(pass.c_str()); sql.format("insert into mail_tbl(smtp_addr, smtp_port, pop3_addr," " pop3_port, user, pass, recipients)" " values('%s', %d, '%s', %d, '%s', '%s', '%s')", smtp_addr.c_str(), smtp_port_, pop3_addr.c_str(), pop3_port_, user.c_str(), pass_crypted, recipients.c_str()); acl_myfree(pass_crypted); const char* ptr = sql.c_str(); ptr = pop3_addr.c_str(); if (db.sql_update(sql.c_str()) == false) logger_error("sql(%s) error", sql.c_str()); } void net_store::load_mail_db(acl::db_handle& db) { acl::string sql; sql.format("select smtp_addr, smtp_port, pop3_addr, pop3_port, user, pass, recipients from mail_tbl"); if (db.sql_select(sql.c_str()) == false) { logger_error("sql(%s) error", sql.c_str()); return; } const acl::db_row* first_row = db.get_first_row(); if (first_row == NULL) return; const char* ptr = (*first_row)["smtp_addr"]; if (ptr) smtp_addr_ = ptr; ptr = (*first_row)["smtp_port"]; int n; if (ptr && (n = atoi(ptr)) > 0) smtp_port_ = n; ptr = (*first_row)["pop3_addr"]; if (ptr) pop3_addr_ = ptr; ptr = (*first_row)["pop3_port"]; if (ptr && (n = atoi(ptr)) > 0) pop3_port_ = n; ptr = (*first_row)["user"]; if (ptr) user_ = ptr; ptr = (*first_row)["pass"]; if (ptr) { // 对加密的密码需要先解密 char* pass_plain = passwd_decrypt(ptr); if (pass_plain) { pass_ = pass_plain; acl_myfree(pass_plain); } } ptr = (*first_row)["recipients"]; if (ptr) recipients_ = ptr; }