| 1 |
/*******************************************************/ |
/*******************************************************/ |
| 2 |
/* */ |
/* */ |
| 3 |
/* LeafOK Innd */ |
/* LeafOK Innbbsd */ |
|
/* Copyright (C) LeafOK.com, 2003-2004 */ |
|
| 4 |
/* */ |
/* */ |
| 5 |
/* Programmed by Leaf */ |
/* Copyright (C) LeafOK.com, 2003-2008 */ |
|
/* E-mail:leaf@leafok.com QQ:6049044 */ |
|
| 6 |
/* */ |
/* */ |
| 7 |
/* http://bbs.leafok.com */ |
/* http://www.leafok.com */ |
|
/* http://bbs.leafok.net */ |
|
|
/* http://bbs.fenglin.info */ |
|
| 8 |
/* */ |
/* */ |
| 9 |
/*******************************************************/ |
/*******************************************************/ |
| 10 |
|
|
| 18 |
|
|
| 19 |
base::base(void) |
base::base(void) |
| 20 |
: p_ParentThread(NULL) |
: p_ParentThread(NULL) |
| 21 |
|
, p_ThreadPool(NULL) |
| 22 |
|
, ulMainThreadId(0) |
| 23 |
, innd_uid(0) |
, innd_uid(0) |
| 24 |
, isConnected(false) |
, isConnected(false) |
| 25 |
, running(false) |
, running(false) |
| 28 |
|
|
| 29 |
base::~base(void) |
base::~base(void) |
| 30 |
{ |
{ |
| 31 |
|
if (this->GetThreadPool() != NULL) |
| 32 |
|
delete (this->GetThreadPool()); |
| 33 |
} |
} |
| 34 |
|
|
| 35 |
int base::s_exec(const char* in_str, CString& out_str, const char* end_str) |
int base::s_exec(const char* in_str, CString& out_str, char end_str[]) |
| 36 |
{ |
{ |
| 37 |
try{ |
try{ |
| 38 |
if (in_str != NULL) |
if (in_str != NULL) |
| 42 |
} |
} |
| 43 |
catch(CException* e) |
catch(CException* e) |
| 44 |
{ |
{ |
| 45 |
syslog << logfile::log_head << "Error in s_exec()" << endl; |
char strErrMsg[1024]; |
| 46 |
|
e->GetErrorMessage(strErrMsg,1024); |
| 47 |
|
syslog << logfile::log_head << "Error in s_exec() [" << strErrMsg << "]" << endl; |
| 48 |
e->Delete(); |
e->Delete(); |
| 49 |
return -1; |
return -1; |
| 50 |
} |
} |
| 57 |
try |
try |
| 58 |
{ |
{ |
| 59 |
this->Db.Open("",0,0,conn_str,0); |
this->Db.Open("",0,0,conn_str,0); |
| 60 |
|
this->Db.ExecuteSQL("SET CHARACTER SET gb2312"); |
| 61 |
|
this->Db.ExecuteSQL("SET NAMES 'gb2312'"); |
| 62 |
} |
} |
| 63 |
catch(CException* e) |
catch(CException* e) |
| 64 |
{ |
{ |
| 65 |
syslog << logfile::log_head << "Open database failed in db_open()" << endl; |
char strErrMsg[1024]; |
| 66 |
|
e->GetErrorMessage(strErrMsg,1024); |
| 67 |
|
syslog << logfile::log_head << "Open database failed in db_open() [" << strErrMsg << "]" << endl; |
| 68 |
e->Delete(); |
e->Delete(); |
| 69 |
return -1; |
return -1; |
| 70 |
} |
} |
| 80 |
} |
} |
| 81 |
catch(CException* e) |
catch(CException* e) |
| 82 |
{ |
{ |
| 83 |
syslog << logfile::log_head << "Close database failed in db_close()" << endl; |
char strErrMsg[1024]; |
| 84 |
|
e->GetErrorMessage(strErrMsg,1024); |
| 85 |
|
syslog << logfile::log_head << "Close database failed in db_close() [" << strErrMsg << "]" << endl; |
| 86 |
e->Delete(); |
e->Delete(); |
| 87 |
return -1; |
return -1; |
| 88 |
} |
} |
| 109 |
bool head_find; |
bool head_find; |
| 110 |
CString head_name,head_value,path,from,subject,newsgroups,organization,date,msg_id; //Head |
CString head_name,head_value,path,from,subject,newsgroups,organization,date,msg_id; //Head |
| 111 |
DateTimeConvert sub_dt; |
DateTimeConvert sub_dt; |
| 112 |
CString ptitle,nickname,dt_str,content,msg_content,sql; |
CString ptitle,username,nickname,dt_str,content,msg_content,sql; |
| 113 |
int length; |
int length; |
| 114 |
long id,aid,cid,rid; |
long id,aid,cid; |
| 115 |
|
|
| 116 |
try |
try |
| 117 |
{ |
{ |
| 201 |
if (subject.GetLength() > 80) |
if (subject.GetLength() > 80) |
| 202 |
subject = subject.Left(75) + " ……"; |
subject = subject.Left(75) + " ……"; |
| 203 |
|
|
| 204 |
//Get nickname |
//Get username |
| 205 |
nickname = "cn.bbs"; |
username = "cn.bbs."; |
| 206 |
for (int i=0;i<from.GetLength();i++) |
for (int i=0;i<from.GetLength();i++) |
| 207 |
{ |
{ |
| 208 |
if (from[i] == '.' || from[i] == '@') |
if (from[i] == '.' || from[i] == '@') |
| 213 |
if (from[j] == ' ' || from[j] == '<') |
if (from[j] == ' ' || from[j] == '<') |
| 214 |
break; |
break; |
| 215 |
} |
} |
| 216 |
nickname = from.Mid(j+1,i-j-1) + "."; |
username = from.Mid(j+1,i-j-1) + "."; |
| 217 |
|
break; |
| 218 |
|
} |
| 219 |
|
} |
| 220 |
|
if (username.GetLength() > 12) |
| 221 |
|
username = username.Left(12) + "."; |
| 222 |
|
|
| 223 |
|
//Get nickname |
| 224 |
|
nickname = "cn.bbs"; |
| 225 |
|
for (int i=0;i<from.GetLength();i++) |
| 226 |
|
{ |
| 227 |
|
if (from[i] == '(') |
| 228 |
|
{ |
| 229 |
|
int j; |
| 230 |
|
for (j=i+1;j<from.GetLength();j++) |
| 231 |
|
{ |
| 232 |
|
if (from[j] == ')') |
| 233 |
|
break; |
| 234 |
|
} |
| 235 |
|
nickname = from.Mid(i+1,j-i-1); |
| 236 |
break; |
break; |
| 237 |
} |
} |
| 238 |
} |
} |
| 239 |
if (nickname.GetLength() > 20) |
if (nickname.GetLength() > 20) |
| 240 |
nickname = nickname.Left(19) + "."; |
nickname = nickname.Left(19) + " "; |
| 241 |
|
|
| 242 |
//Reference /bbs/add_sub.php |
//Reference /bbs/add_sub.php |
| 243 |
|
|
| 246 |
this->Db.ExecuteSQL(sql); |
this->Db.ExecuteSQL(sql); |
| 247 |
cid = this->last_insert_id(); |
cid = this->last_insert_id(); |
| 248 |
|
|
| 249 |
sql.Format("insert into bbs(SID,TID,UID,nickname,title,CID,sub_dt," |
sql.Format("insert into bbs(SID,TID,UID,username,nickname,title,CID,sub_dt," |
| 250 |
"sub_ip,last_reply_dt,icon,length,transship)" |
"sub_ip,last_reply_dt,icon,length,transship)" |
| 251 |
"values(%d,%ld,%ld,'%s','%s',%ld,adddate('%s',interval '8' hour)," |
"values(%d,%ld,%ld,'%s','%s','%s',%ld,adddate('%s',interval '8' hour)," |
| 252 |
"'%s',adddate('%s',interval '8' hour),1,%d,1)", |
"'%s',adddate('%s',interval '8' hour),1,%d,1)", |
| 253 |
sid,id,this->innd_uid,addslashes(nickname),addslashes(subject), |
sid,id,this->innd_uid,addslashes(username),addslashes(nickname),addslashes(subject), |
| 254 |
cid,dt_str,this->hostaddr,dt_str,length); |
cid,dt_str,this->hostaddr,dt_str,length); |
| 255 |
this->Db.ExecuteSQL(sql); |
this->Db.ExecuteSQL(sql); |
| 256 |
aid = this->last_insert_id(); |
aid = this->last_insert_id(); |
| 259 |
this->Db.ExecuteSQL(sql); //7671 |
this->Db.ExecuteSQL(sql); //7671 |
| 260 |
|
|
| 261 |
//Add logfile |
//Add logfile |
| 262 |
sql.Format("insert delayed into bbs_article_op(AID,UID,type,op_dt,op_ip,complete)" |
sql.Format("insert delayed into bbs_article_op(AID,UID,type,op_dt,op_ip)" |
| 263 |
" values(%ld,%ld,'I',now(),'%s',1)", |
" values(%ld,%ld,'I',now(),'%s')", |
| 264 |
aid,this->innd_uid,this->hostaddr); |
aid,this->innd_uid,this->hostaddr); |
| 265 |
this->Db.ExecuteSQL(sql); |
this->Db.ExecuteSQL(sql); |
| 266 |
|
|
| 269 |
{ |
{ |
| 270 |
sql.Format("update bbs set cached=0, reply_count=reply_count+1," |
sql.Format("update bbs set cached=0, reply_count=reply_count+1," |
| 271 |
"last_reply_dt=adddate('%s',interval '8' hour),last_reply_UID=%ld," |
"last_reply_dt=adddate('%s',interval '8' hour),last_reply_UID=%ld," |
| 272 |
"last_reply_nickname='%s' where aid=%ld", |
"last_reply_username='%s',last_reply_nickname='%s' where aid=%ld", |
| 273 |
dt_str,this->innd_uid,nickname,id); |
dt_str,this->innd_uid,username,nickname,id); |
| 274 |
this->Db.ExecuteSQL(sql); |
this->Db.ExecuteSQL(sql); |
| 275 |
} |
} |
| 276 |
|
|
| 277 |
//Notify the author of the artile which is replyed. |
//Notify the author of the artile which is replyed. |
| 278 |
if (id != 0) |
if (id != 0) |
| 279 |
{ |
{ |
| 280 |
sql.Format("select user_pubinfo.UID,user_pubinfo.nickname," |
sql.Format("select distinct UID from bbs where (AID=%ld or TID=%ld)" |
| 281 |
"user_pubinfo.email from bbs left join user_pubinfo on" |
" and visible and reply_note and UID<>%ld",id,id,this->innd_uid); |
|
" bbs.UID=user_pubinfo.UID where AID=%ld and reply_note", |
|
|
id); |
|
| 282 |
RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly); |
RS.Open(CRecordset::snapshot,sql,CRecordset::forwardOnly | CRecordset::readOnly); |
| 283 |
|
|
| 284 |
if (!RS.IsEOF()) |
while (!RS.IsEOF()) |
| 285 |
{ |
{ |
| 286 |
RS.GetFieldValue("UID",dbVar),SQL_C_SLONG; |
//Send notication message |
| 287 |
if (dbVar.m_lVal != innd_uid) |
|
| 288 |
{ |
msg_content.Format("[hide]SYS_R_Reply_Article[/hide]" |
| 289 |
sql.Format("update user_pubinfo set exp=exp+1 where UID=%ld", |
"有人回复了您所发表的文章,快来[article %ld#%ld" |
| 290 |
dbVar.m_lVal); |
"]看看[/article]《%s》吧!\n",id,aid,addslashes(subject)); |
| 291 |
this->Db.ExecuteSQL(sql); |
|
| 292 |
|
RS.GetFieldValue("UID",dbVar,SQL_C_SLONG); |
| 293 |
RS.GetFieldValue("email",dbVar,SQL_C_CHAR); |
|
| 294 |
sql.Format("insert into bbs_recommend(UID,TID,type,dt,email,ip)" |
sql.Format("insert into bbs_msg(fromUID,toUID,content,send_dt,send_ip)" |
| 295 |
" values(%ld,%ld,'D',now(),'%s','%s')", |
" values(%ld,%ld,'%s',now(),'%s')", |
| 296 |
this->innd_uid,aid,dbVar.m_pstring,this->hostaddr); |
this->innd_uid,dbVar.m_lVal,addslashes(msg_content),this->hostaddr); |
| 297 |
this->Db.ExecuteSQL(sql); |
this->Db.ExecuteSQL(sql); |
| 298 |
rid = this->last_insert_id(); |
} |
|
|
|
|
//Send notification message |
|
|
|
|
|
msg_content.Format("[hi]SYS_R_Reply_Article[/hide]" |
|
|
"有人回复了您所发表的文章,快来[url recommend_view.php?id=%ld" |
|
|
"]看看[/url]《%s》吧!\n",rid,addslashes(subject)); |
|
|
|
|
|
RS.GetFieldValue("UID",dbVar,SQL_C_SLONG); |
|
|
sql.Format("insert into bbs_msg(fromUID,toUID,ntent,send_dt,send_ip)" |
|
|
" valulues(%ld,%ld,'%s',now(),'%s')", |
|
|
this->innd_uid,dbVar.m_lVal,addslashes(msg_connt),ththis->hostaddr); |
|
|
this->Db.ExecuteSQL(sql); |
|
|
} |
|
|
} |
|
| 299 |
RS.Close(); |
RS.Close(); |
| 300 |
} |
} |
| 301 |
|
|
| 302 |
sql.Format("insert delayed into innd_logfile(AID,art_id,msg_id,op) values" |
sql.Format("insert delayed into innd_log(AID,art_id,msg_id,op) values" |
| 303 |
"(%ld,%ld,'%s','I')", |
"(%ld,%ld,'%s','I')", |
| 304 |
aid,art_id,addslashes(msg_id)); |
aid,art_id,addslashes(msg_id)); |
| 305 |
this->Db.ExecuteSQL(sql); |
this->Db.ExecuteSQL(sql); |
| 311 |
} |
} |
| 312 |
catch(CException* e) |
catch(CException* e) |
| 313 |
{ |
{ |
| 314 |
syslog << logfile::log_head << "Error in bbs_post()" << endl; |
char strErrMsg[1024]; |
| 315 |
|
e->GetErrorMessage(strErrMsg,1024); |
| 316 |
|
syslog << logfile::log_head << "Error in bbs_post() [" << strErrMsg << "]" << endl; |
| 317 |
e->Delete(); |
e->Delete(); |
| 318 |
return -1; |
return -1; |
| 319 |
} |
} |
| 355 |
} |
} |
| 356 |
catch(CException* e) |
catch(CException* e) |
| 357 |
{ |
{ |
| 358 |
syslog << logfile::log_head << "Error in last_insert_id()" << endl; |
char strErrMsg[1024]; |
| 359 |
|
e->GetErrorMessage(strErrMsg,1024); |
| 360 |
|
syslog << logfile::log_head << "Error in last_insert_id() [" << strErrMsg << "]" << endl; |
| 361 |
e->Delete(); |
e->Delete(); |
| 362 |
return 0; |
return 0; |
| 363 |
} |
} |
| 388 |
this->Db.ExecuteSQL(sql); |
this->Db.ExecuteSQL(sql); |
| 389 |
|
|
| 390 |
//Add logfile |
//Add logfile |
| 391 |
sql.Format("insert delayed into bbs_article_op(AID,UID,type,op_dt," |
sql.Format("insert delayed into bbs_article_op(AID,UID,type,op_dt,op_ip)" |
| 392 |
"op_ip,complete) values(%ld,%ld,'C',now(),'%s',1)", |
" values(%ld,%ld,'C',now(),'%s')", |
| 393 |
id,innd_uid,this->hostaddr); |
id,innd_uid,this->hostaddr); |
| 394 |
this->Db.ExecuteSQL(sql); |
this->Db.ExecuteSQL(sql); |
| 395 |
|
|
| 400 |
this->Db.ExecuteSQL(sql); |
this->Db.ExecuteSQL(sql); |
| 401 |
} |
} |
| 402 |
|
|
| 403 |
sql.Format("update innd_logfile set cancel=1 where AID=%ld",id); |
sql.Format("update innd_log set cancel=1 where AID=%ld",id); |
| 404 |
this->Db.ExecuteSQL(sql); |
this->Db.ExecuteSQL(sql); |
| 405 |
} |
} |
| 406 |
RS.Close(); |
RS.Close(); |
| 407 |
} |
} |
| 408 |
catch(CException* e) |
catch(CException* e) |
| 409 |
{ |
{ |
| 410 |
syslog << logfile::log_head << "Getting article error in bbs_delete()" << endl; |
char strErrMsg[1024]; |
| 411 |
|
e->GetErrorMessage(strErrMsg,1024); |
| 412 |
|
syslog << logfile::log_head << "Getting article error in bbs_delete() [" << strErrMsg << "]" << endl; |
| 413 |
e->Delete(); |
e->Delete(); |
| 414 |
return -1; |
return -1; |
| 415 |
} |
} |
| 431 |
} |
} |
| 432 |
catch(CException* e) |
catch(CException* e) |
| 433 |
{ |
{ |
| 434 |
syslog << logfile::log_head << "Error in s_send()" << endl; |
char strErrMsg[1024]; |
| 435 |
|
e->GetErrorMessage(strErrMsg,1024); |
| 436 |
|
syslog << logfile::log_head << "Error in s_send() [" << strErrMsg << "]" << endl; |
| 437 |
e->Delete(); |
e->Delete(); |
| 438 |
return -1; |
return -1; |
| 439 |
} |
} |
| 441 |
return 0; |
return 0; |
| 442 |
} |
} |
| 443 |
|
|
| 444 |
int base::s_receive(CString& out_str, const char* end_str) |
int base::s_receive(CString& out_str, char end_str[]) |
| 445 |
{ |
{ |
| 446 |
char buf_str[2048]; |
char buf_str[2048]; |
| 447 |
int buf_read,total_read; |
int buf_read,total_read; |
| 460 |
out_str += buf_str; |
out_str += buf_str; |
| 461 |
if (out_str.Right((int)strlen(end_str)) == end_str) |
if (out_str.Right((int)strlen(end_str)) == end_str) |
| 462 |
break; |
break; |
| 463 |
|
//different line-end symbol in different OS |
| 464 |
|
if (strcmp(end_str,"\r") == 0) |
| 465 |
|
{ |
| 466 |
|
if (out_str.Right(2) == "\r\n") |
| 467 |
|
break; |
| 468 |
|
} |
| 469 |
} |
} |
| 470 |
} |
} |
| 471 |
catch(CException* e) |
catch(CException* e) |
| 472 |
{ |
{ |
| 473 |
syslog << logfile::log_head << "Error in s_receive()" << endl; |
char strErrMsg[1024]; |
| 474 |
|
e->GetErrorMessage(strErrMsg,1024); |
| 475 |
|
syslog << logfile::log_head << "Error in s_receive() [" << strErrMsg << "]" << endl; |
| 476 |
e->Delete(); |
e->Delete(); |
| 477 |
return -1; |
return -1; |
| 478 |
} |
} |
| 482 |
|
|
| 483 |
int base::begin(void) |
int base::begin(void) |
| 484 |
{ |
{ |
| 485 |
|
HANDLE hThread; |
| 486 |
ULONG ulThreadId; |
ULONG ulThreadId; |
| 487 |
unsigned int time_wait = 0; |
unsigned int time_wait = 0; |
| 488 |
|
|
| 489 |
if (!this->IsShutdown()) |
if (!this->IsShutdown()) |
| 490 |
return 1; |
return 0; |
| 491 |
|
|
| 492 |
if (this->hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)base::Thread,(LPVOID)this,0,&ulThreadId)) |
if (hThread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)base::Thread,(LPVOID)this,0,&ulThreadId)) |
| 493 |
{ |
{ |
| 494 |
|
CloseHandle(hThread); |
| 495 |
syslog << logfile::log_head << "Create thread ... OK" << endl; |
syslog << logfile::log_head << "Create thread ... OK" << endl; |
| 496 |
} |
} |
| 497 |
else |
else |
| 504 |
{ |
{ |
| 505 |
Sleep(100); |
Sleep(100); |
| 506 |
time_wait += 100; |
time_wait += 100; |
| 507 |
if (time_wait > 10000) //Wait 10 seconds |
if (time_wait > 30000) //Wait 30 seconds |
| 508 |
{ |
{ |
| 509 |
syslog << logfile::log_head << "Module timeout in begin()" << endl; |
syslog << logfile::log_head << "Module timeout in begin()" << endl; |
| 510 |
this->end(); |
this->end(); |
| 518 |
|
|
| 519 |
DWORD base::Thread(LPVOID pParam) |
DWORD base::Thread(LPVOID pParam) |
| 520 |
{ |
{ |
|
HANDLE hThreadCurrent; |
|
| 521 |
base* p; |
base* p; |
| 522 |
|
|
| 523 |
syslog << logfile::log_head << "Thread started." << endl; |
syslog << logfile::log_head << "Thread started." << endl; |
| 524 |
|
|
| 525 |
p = (base*)pParam; |
p = (base*)pParam; |
|
hThreadCurrent = GetCurrentThread(); |
|
| 526 |
|
|
| 527 |
if (p->GetParentThread()->GetThreadPool()->AddThread(hThreadCurrent, CLOCKS_PER_SEC * 30) != 0) |
p->ulMainThreadId = GetCurrentThreadId(); |
| 528 |
|
|
| 529 |
|
if (p->GetParentThread()->GetThreadPool()->AddThread(GetCurrentThreadId(), CLOCKS_PER_SEC * 60) != 0) |
| 530 |
{ |
{ |
| 531 |
syslog << logfile::log_head << "Register thread ... Failed" << endl; |
syslog << logfile::log_head << "Register thread ... Failed" << endl; |
| 532 |
} |
} |
| 533 |
p->GetParentThread()->GetThreadPool()->SetThreadStatus(hThreadCurrent,thread_pool::S_WORKING); |
p->GetParentThread()->GetThreadPool()->SetThreadStatus(GetCurrentThreadId(),thread_pool::S_WORKING); |
| 534 |
|
|
| 535 |
p->w_call(); |
p->w_call(); |
| 536 |
|
|
| 537 |
if (p->GetParentThread()->GetThreadPool()->RemoveThread(hThreadCurrent) != 0) |
if (p->GetParentThread()->GetThreadPool()->RemoveThread(GetCurrentThreadId()) != 0) |
| 538 |
{ |
{ |
| 539 |
syslog << logfile::log_head << "Unregister thread ... Failed" << endl; |
syslog << logfile::log_head << "Unregister thread ... Failed" << endl; |
| 540 |
} |
} |
| 578 |
{ |
{ |
| 579 |
return 0; |
return 0; |
| 580 |
} |
} |
| 581 |
|
|
| 582 |
|
bool base::IsThreadActive(void) |
| 583 |
|
{ |
| 584 |
|
bool bIsActive = false; |
| 585 |
|
|
| 586 |
|
switch (this->GetParentThread()->GetThreadPool()->GetThreadStatus(this->ulMainThreadId)) |
| 587 |
|
{ |
| 588 |
|
case thread_pool::S_WAITING: |
| 589 |
|
case thread_pool::S_WORKING: |
| 590 |
|
bIsActive = true; |
| 591 |
|
break; |
| 592 |
|
default: |
| 593 |
|
bIsActive = false; |
| 594 |
|
} |
| 595 |
|
|
| 596 |
|
return bIsActive; |
| 597 |
|
} |