Добавил:
korayakov
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабы / 2 / lab.05.by mice / spice / src / csp_life
.cpp/*******************************************************************************
* file: csp_life.cpp *
* version: 0.0.1 *
* author: d-evil [tmd] (mailto:d-evil.tmd@mail.ru) *
* description: not available *
*******************************************************************************/
////////////////////////////////////////////////////////////////////////////////
// headers
#include "csp_life.h"
////////////////////////////////////////////////////////////////////////////////
// csp_life public definitions
csp_life::csp_life(): CDialog(IDD_SP_WND) {
_thread_h = NULL;
_thread_id = -1;
_running = false;
_paused = false;
_opened = false;
_must_stop = false;
_can_quit = false;
_need_csp_flush = false;
_waiting_csp_flush = false;
_html_file_corrupted = false;
_list_closing = false;
// net part
_sock = INVALID_SOCKET;
_file = NULL;
_html_file = NULL;
_buf = NULL;
// find css file
char buf[MAX_PATH];
char *fp;
if (0 != GetFullPathName(_DEF_CSS_FILE_NAME, MAX_PATH, buf, &fp)) {
_css_file_name = buf;
} else _css_file_name = _DEF_CSS_FILE_NAME;
GetCurrentDirectory(MAX_PATH, buf);
_app_path = CString(buf) + '/';
// gui part
_csp_list = NULL;
_tmp_list = NULL;
_state_btns_open = _STATE_UNKNOWN;
_state_btns_run = _STATE_UNKNOWN;
_state_btns_opts = _STATE_UNKNOWN;
}
csp_life::~csp_life() {
_buf_ctl(false);
}
BOOL csp_life::OnInitDialog() {
// getting controls
_btn_open = (CButton *)GetDlgItem(IDC_BTN_OPEN);
_btn_browse = (CButton *)GetDlgItem(IDC_BTN_BROWSE);
_stt_file = (CStatic *)GetDlgItem(IDC_STT_FILE);
_btn_run = (CButton *)GetDlgItem(IDC_BTN_RUN);
_btn_pause = (CButton *)GetDlgItem(IDC_BTN_PAUSE);
_edit_file = (CEdit *)GetDlgItem(IDC_EDIT_FILE);
_edit_host = (CEdit *)GetDlgItem(IDC_EDIT_HOST);
_stt_host = (CStatic *)GetDlgItem(IDC_STT_HOST);
_btn_clr_file = (CButton *)GetDlgItem(IDC_BTN_CLR_FILE);
_btn_cr_new_html = (CButton *)GetDlgItem(IDC_BTN_CR_NHTML);
_btn_write_html = (CButton *)GetDlgItem(IDC_BTN_WRITE_HTML);
_btn_view_html = (CButton *)GetDlgItem(IDC_BTN_VIEW_HTML);
_btn_rw_html = (CButton *)GetDlgItem(IDC_BTN_RW_HTML);
_btn_filter = (CButton *)GetDlgItem(IDC_BTN_FILTER);
_btn_show_list = (CButton *)GetDlgItem(IDC_BTN_SHOW_LIST);
_edit_html_file = (CEdit *)GetDlgItem(IDC_EDIT_HTML_FILE);
_stt_html = (CStatic *)GetDlgItem(IDC_STT_HTML);
_stt_info = (CStatic *)GetDlgItem(IDC_STT_INFO);
_edit_info = (CEdit *)GetDlgItem(IDC_EDIT_INFO);
_btn_exit = (CButton *)GetDlgItem(IDC_BTN_EXIT);
// precreating windows
_csp_filter.set_icon(_icon);
if (0 !=_csp_filter.create(this)) {
show_error_msg("Can't load filters", 0, this);
_btn_filter->EnableWindow(FALSE);
} else {
_btn_filter->EnableWindow(TRUE);
}
// setting defaults
_set_state_btns_open(_STATE_BTNS_OPEN_CANOPEN);
_set_state_btns_run(_STATE_BTNS_RUN_DISABLED);
_set_state_btns_opts(_STATE_BTNS_OPTS_DISABLED);
_set_state_btn_write_html(false);
_show_file_info(false, true);
SetIcon(_icon, TRUE);
_btn_clr_file->SetCheck(BST_UNCHECKED);
_btn_cr_new_html->SetCheck(BST_CHECKED);
_edit_file->SetWindowText(_app_path + "logs/log.spf");
cdm_addr_info ai;
ai.set_to_local();
_edit_host->SetWindowText(ai.host());
// loading configs
_csp_filter.load_from_file(_app_path + _DEF_FILTER_FILE_NAME);
return TRUE;
}
void csp_life::OnClose() {
_btn_exit->EnableWindow(FALSE);
if (_running) {
stop();
PostMessage(WM_CLOSE);
return;
}
if (NULL != _csp_list) PostMessage(csp_list::SPM_LST_CLOSE_ME);
_csp_list = NULL;
if (NULL != _tmp_list) {
PostMessage(WM_CLOSE);
return;
}
if (_opened) {
_close_file();
PostMessage(WM_CLOSE);
return;
}
_csp_filter.hide();
_csp_filter.save_to_file(_app_path + _DEF_FILTER_FILE_NAME);
// we need this just to be shure, that all previous messages are processed
if (!_can_quit) {
PostMessage(_WM_CAN_QUIT);
return;
}
EndDialog(0);
}
int csp_life::open_file() {
_set_state_btns_open(_STATE_BTNS_OPEN_DISABLED);
_set_state_btns_run(_STATE_BTNS_RUN_DISABLED);
_set_state_btns_opts(_STATE_BTNS_OPTS_DISABLED);
if (0 != _open_file()) {
show_error_msg("Can't open file", 0, this);
_set_state_btns_open(_STATE_BTNS_OPEN_CANOPEN);
_set_state_btns_run(_STATE_BTNS_RUN_DISABLED);
_set_state_btns_opts(_STATE_BTNS_OPTS_DISABLED);
return -1;
}
_set_state_btns_open(_STATE_BTNS_OPEN_CANCLOSE);
_set_state_btns_run(_STATE_BTNS_RUN_CANRUN);
_set_state_btns_opts(_STATE_BTNS_OPTS_ENABLED);
return 0;
}
int csp_life::close_file() {
_set_state_btns_open(_STATE_BTNS_OPEN_DISABLED);
_set_state_btns_run(_STATE_BTNS_RUN_DISABLED);
_set_state_btns_opts(_STATE_BTNS_OPTS_DISABLED);
if (0 != _close_file()) {
show_error_msg("Error occurred while closing file", 0, this);
}
_set_state_btns_open(_STATE_BTNS_OPEN_CANOPEN);
_set_state_btns_run(_STATE_BTNS_RUN_DISABLED);
_set_state_btns_opts(_STATE_BTNS_OPTS_DISABLED);
return 0;
}
int csp_life::run() {
int _old_state_btns_run = _state_btns_run;
_set_state_btns_run(_STATE_BTNS_RUN_DISABLED);
_set_state_btns_open(_STATE_BTNS_OPEN_DISABLED);
if (_running) {
show_error_msg("Stop it, before run again", 0, this);
_set_state_btns_run(_old_state_btns_run);
_set_state_btns_open(_STATE_BTNS_OPEN_CANCLOSE);
return -1;
}
_thread_h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)_run_proc_helper,
this, 0, &_thread_id);
if (NULL == _thread_h) {
show_error_msg("Can't create new thread", 0, this);
_set_state_btns_run(_STATE_BTNS_RUN_CANRUN);
_set_state_btns_open(_STATE_BTNS_OPEN_CANCLOSE);
return -1;
}
return 0;
}
int csp_life::stop() {
_set_state_btns_run(_STATE_BTNS_RUN_DISABLED);
_set_state_btns_open(_STATE_BTNS_OPEN_DISABLED);
_must_stop = true;
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// csp_life protected definitions
const char *csp_life::_DEF_CSS_FILE_NAME = "files/style.css";
const char *csp_life::_DEF_FILTER_FILE_NAME = "files/filter.txt";
const char *csp_life::_html_intro = "<html><head>"
"<link rel=\"StyleSheet\" href=\"style.css\" type=\"text/css\">"
"<title>Spice generated html file</title>"
"</head><body>";
const char *csp_life::_html_outtro = "</body></html>";
BEGIN_MESSAGE_MAP(csp_life, CDialog)
ON_WM_CLOSE()
ON_MESSAGE(_WM_CAN_QUIT, _on_can_quit)
ON_MESSAGE(_WM_DO_CLOSE, _on_do_close)
ON_MESSAGE(_WM_DO_OPEN, _on_do_open)
ON_MESSAGE(_WM_DO_CSP_FLUSH, _on_do_csp_flush)
ON_MESSAGE(csp_list::SPM_LST_CLOSE_ME, _on_close_list)
ON_MESSAGE(csp_filter::SPM_FLT_CLOSE_ME, _on_close_filter)
ON_COMMAND(IDC_BTN_RUN, _on_btn_run)
ON_COMMAND(IDC_BTN_PAUSE, _on_btn_pause)
ON_COMMAND(IDC_BTN_BROWSE, _on_btn_browse)
ON_COMMAND(IDC_BTN_OPEN, _on_btn_open)
ON_COMMAND(IDC_BTN_VIEW_HTML, _on_btn_show_html)
ON_COMMAND(IDC_BTN_WRITE_HTML, _on_btn_write_html)
ON_COMMAND(IDC_BTN_RW_HTML, _on_btn_rw_html)
ON_COMMAND(IDC_BTN_FILTER, _on_btn_filter)
ON_COMMAND(IDC_BTN_SHOW_LIST, _on_btn_show_list)
ON_COMMAND(IDC_BTN_HELP, _on_btn_help)
ON_COMMAND(IDC_BTN_ABOUT, _on_btn_about)
ON_COMMAND(IDC_BTN_EXIT, _on_btn_exit)
END_MESSAGE_MAP()
void csp_life::_on_btn_browse() {
CString fname;
_edit_file->GetWindowText(fname);
CString filter = "Spice file (*.spf)|*.spf|All Files (*.*)|*.*||";
CFileDialog fdlg(FALSE, ".spf", NULL,
OFN_DONTADDTORECENT|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_NOTESTFILECREATE,
filter, this, 0
);
if (IDOK != fdlg.DoModal()) return;
fname = fdlg.GetPathName();
_edit_file->SetWindowText(fname);
}
void csp_life::_on_btn_open() {
switch (_state_btns_open) {
case _STATE_BTNS_OPEN_CANOPEN:
PostMessage(_WM_DO_OPEN);
break;
case _STATE_BTNS_OPEN_CANCLOSE:
PostMessage(_WM_DO_CLOSE);
break;
default:
show_error_msg("You are not allowed to push this button now :^)", 0, this);
}
}
void csp_life::_on_btn_run() {
switch(_state_btns_run) {
case _STATE_BTNS_RUN_CANRUN:
run();
break;
case _STATE_BTNS_RUN_CANSTOPR:
case _STATE_BTNS_RUN_CANSTOPP:
stop();
break;
default:
show_error_msg("Мальчик, ты чей?", 0, this);
break;
}
}
void csp_life::_on_btn_pause() {
_set_state_btns_run(_STATE_BTNS_RUN_DISABLED);
if (_paused) {
_set_state_btns_run(_STATE_BTNS_RUN_CANSTOPR);
_paused = false;
} else {
_set_state_btns_run(_STATE_BTNS_RUN_CANSTOPP);
_paused = true;
}
}
void csp_life::_on_btn_show_html() {
CString fn;
_edit_html_file->GetWindowText(fn);
if (0 >= fn.GetLength()) return;
int rev = (sfx_data)ShellExecute(GetSafeHwnd(), NULL, fn, NULL, NULL, SW_SHOWNORMAL);
if (32 > rev) {
show_error_msg("Can't open this file (if it is a file at all)", rev, this);
}
}
void csp_life::_on_btn_write_html() {
if (BST_CHECKED == _btn_write_html->GetCheck())
_set_state_btn_write_html(false);
else
_set_state_btn_write_html(true);
}
void csp_life::_on_btn_rw_html() {
// flush csp file
if (!_waiting_csp_flush) {
_btn_rw_html->EnableWindow(FALSE);
_waiting_csp_flush = true;
_need_csp_flush = true;
PostMessage(_WM_DO_CSP_FLUSH);
}
if (_need_csp_flush) {
PostMessage(WM_COMMAND, IDC_BTN_RW_HTML);
return;
}
_waiting_csp_flush = false;
// try top open csp file for reading
CString fn;
_edit_file->GetWindowText(fn);
HANDLE hf = CreateFile(fn, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hf) {
show_error_msg("Can't open file", 0, this);
_btn_rw_html->EnableWindow(TRUE);
return;
}
csp_file csp_file;
if (0 != csp_file.use_handle(hf, true)) {
show_error_msg("Can't use this file", 0, this);
CloseHandle(hf);
_btn_rw_html->EnableWindow(TRUE);
return;
}
// copy css file
_copy_css(fn);
// disable run-time writing
_set_state_btn_write_html(false);
_btn_write_html->EnableWindow(FALSE);
_html_file_corrupted = true;
// cut existing file
SetFilePointer(_html_file, 0, NULL, FILE_BEGIN);
SetEndOfFile(_html_file);
DWORD wr;
// write intro
WriteFile(_html_file, _html_intro, (int)strlen(_html_intro), &wr, NULL);
char dtgm[_DTGM_MAX_LENGTH];
csp_file::ssp_arch *arch = csp_file.load_first_arch();
while (NULL != arch) {
int num = csp_file.arch_used(arch);
for (int i = 0; i < num; ++i) {
csp_file.load_dtgm(arch, i, dtgm);
_parser.parse(dtgm, arch->items[i].length);
WriteFile(_html_file, _parser.html(), _parser.html_len(), &wr, NULL);
}
arch = csp_file.load_next_arch(arch, true);
}
WriteFile(_html_file, _html_outtro, (int)strlen(_html_outtro), &wr, NULL);
csp_file.finish_using();
CloseHandle(hf);
_btn_rw_html->EnableWindow(TRUE);
_btn_write_html->EnableWindow(TRUE);
}
void csp_life::_on_btn_filter() {
if (_csp_filter.is_visible()) _csp_filter.hide();
else _csp_filter.show();
}
void csp_life::_on_btn_show_list() {
// flush csp file
if (!_waiting_csp_flush) {
_btn_show_list->EnableWindow(FALSE);
_btn_show_list->SetWindowText("N/A");
_waiting_csp_flush = true;
_need_csp_flush = true;
PostMessage(_WM_DO_CSP_FLUSH);
}
if (_need_csp_flush) {
PostMessage(WM_COMMAND, IDC_BTN_SHOW_LIST);
return;
}
_waiting_csp_flush = false;
// close list
if (NULL != _csp_list) {
PostMessage(csp_list::SPM_LST_CLOSE_ME);
return;
}
// show list
_list_closing = false;
_tmp_list = new csp_list();
_tmp_list->set_icon(_icon);
_tmp_list->set_app_path(_app_path);
_tmp_list->create(this);
_tmp_list->ShowWindow(SW_SHOW);
_tmp_list->use_csp_file(_file);
_tmp_list->update();
_csp_list = _tmp_list;
_btn_show_list->SetWindowText("Hide list");
_btn_show_list->EnableWindow(TRUE);
}
void csp_life::_on_btn_help() {
CString fn = _app_path + "docs/help.html";
int rev = (sfx_data)ShellExecute(GetSafeHwnd(), NULL, fn, NULL, NULL, SW_SHOWNORMAL);
if (32 > rev) {
show_error_msg("Can't open this file (if it is a file at all)", rev, this);
}
}
void csp_life::_on_btn_about() {
CString fn = _app_path + "docs/about.html";
int rev = (sfx_data)ShellExecute(GetSafeHwnd(), NULL, fn, NULL, NULL, SW_SHOWNORMAL);
if (32 > rev) {
show_error_msg("Can't open this file (if it is a file at all)", rev, this);
}
}
void csp_life::_on_btn_exit() {
PostMessage(WM_CLOSE, 0, 0);
}
LRESULT csp_life::_on_can_quit(WPARAM pch, LPARAM hz) {
_can_quit = true;
PostMessage(WM_CLOSE);
return 0;
}
LRESULT csp_life::_on_do_open(WPARAM pch, LPARAM hz) {
if (_running) {
stop();
PostMessage(_WM_DO_OPEN);
return 0;
}
if (_opened) {
close_file();
PostMessage(_WM_DO_OPEN);
return 0;
}
return open_file();
}
LRESULT csp_life::_on_do_close(WPARAM pch, LPARAM hz) {
if (_running) {
stop();
PostMessage(_WM_DO_CLOSE);
return 0;
}
if (NULL != _csp_list) PostMessage(csp_list::SPM_LST_CLOSE_ME);
_csp_list = NULL;
if (NULL != _tmp_list) {
PostMessage(_WM_DO_CLOSE);
return 0;
}
return close_file();
}
LRESULT csp_life::_on_close_list(WPARAM pch, LPARAM hz) {
if (!_list_closing) {
_list_closing = true;
if (!_running) _csp_list = NULL;
}
if (NULL != _csp_list) {
PostMessage(csp_list::SPM_LST_CLOSE_ME);
return 0;
}
_tmp_list->DestroyWindow();
delete _tmp_list;
_tmp_list = NULL;
_btn_show_list->SetWindowText("Show list");
if (_STATE_BTNS_OPTS_ENABLED == _state_btns_opts)
_btn_show_list->EnableWindow(TRUE);
return 0;
}
LRESULT csp_life::_on_close_filter(WPARAM pch, LPARAM hz) {
_csp_filter.hide();
return 0;
}
LRESULT csp_life::_on_do_csp_flush(WPARAM pch, LPARAM hz) {
if (!_need_csp_flush) return 0;
if (!_running) {
_need_csp_flush = false;
return 0;
}
PostMessage(_WM_DO_CSP_FLUSH);
return 0;
}
void csp_life::_set_state_btns_open(const int state) {
if (state == _state_btns_open) return;
_state_btns_open = state;
switch (state) {
case _STATE_BTNS_OPEN_DISABLED:
_btn_open->EnableWindow(FALSE);
_btn_open->SetWindowText("N/A");
_btn_browse->EnableWindow(FALSE);
edit_set_readonly(_edit_file->GetSafeHwnd(), true);
_btn_clr_file->EnableWindow(FALSE);
_btn_cr_new_html->EnableWindow(FALSE);
_stt_file->EnableWindow(FALSE);
_edit_file->EnableWindow(FALSE);
_edit_info->EnableWindow(FALSE);
_stt_info->EnableWindow(FALSE);
break;
case _STATE_BTNS_OPEN_CANOPEN:
_btn_open->EnableWindow(TRUE);
_btn_open->SetWindowText("Open");
_btn_browse->EnableWindow(TRUE);
edit_set_readonly(_edit_file->GetSafeHwnd(), false);
_btn_clr_file->EnableWindow(TRUE);
_btn_cr_new_html->EnableWindow(TRUE);
_stt_file->EnableWindow(TRUE);
_edit_file->EnableWindow(TRUE);
_edit_info->EnableWindow(FALSE);
_stt_info->EnableWindow(FALSE);
break;
case _STATE_BTNS_OPEN_CANCLOSE:
_btn_open->EnableWindow(TRUE);
_btn_open->SetWindowText("Close");
_btn_browse->EnableWindow(FALSE);
edit_set_readonly(_edit_file->GetSafeHwnd(), true);
_btn_clr_file->EnableWindow(FALSE);
_btn_cr_new_html->EnableWindow(FALSE);
_stt_file->EnableWindow(TRUE);
_edit_file->EnableWindow(TRUE);
_edit_info->EnableWindow(TRUE);
_stt_info->EnableWindow(TRUE);
break;
default:
show_error_msg("Unknown open buttons state.", 0, this);
}
}
void csp_life::_set_state_btns_run(const int state) {
if (state == _state_btns_run) return;
_state_btns_run = state;
switch (state) {
case _STATE_BTNS_RUN_DISABLED:
_btn_run->EnableWindow(FALSE);
_btn_run->SetWindowText("N/A");
_btn_pause->EnableWindow(FALSE);
_btn_pause->SetWindowText("N/A");
edit_set_readonly(_edit_host->GetSafeHwnd(), true);
_edit_host->EnableWindow(FALSE);
_stt_host->EnableWindow(FALSE);
break;
case _STATE_BTNS_RUN_CANRUN:
_btn_run->EnableWindow(TRUE);
_btn_run->SetWindowText("Run");
_btn_pause->EnableWindow(FALSE);
_btn_pause->SetWindowText("N/A");
edit_set_readonly(_edit_host->GetSafeHwnd(), false);
_edit_host->EnableWindow(TRUE);
_stt_host->EnableWindow(TRUE);
break;
case _STATE_BTNS_RUN_CANSTOPR: // running
_btn_run->EnableWindow(TRUE);
_btn_run->SetWindowText("Stop");
_btn_pause->EnableWindow(TRUE);
_btn_pause->SetWindowText("Pause");
edit_set_readonly(_edit_host->GetSafeHwnd(), true);
_edit_host->EnableWindow(TRUE);
_stt_host->EnableWindow(TRUE);
break;
case _STATE_BTNS_RUN_CANSTOPP: // paused
_btn_run->EnableWindow(TRUE);
_btn_run->SetWindowText("Stop");
_btn_pause->EnableWindow(TRUE);
_btn_pause->SetWindowText("Resume");
edit_set_readonly(_edit_host->GetSafeHwnd(), true);
_edit_host->EnableWindow(TRUE);
_stt_host->EnableWindow(TRUE);
break;
default:
show_error_msg("Unknown run buttons state.", 0, this);
}
}
void csp_life::_set_state_btns_opts(const int state) {
if (state == _state_btns_opts) return;
_state_btns_opts = state;
switch (state) {
case _STATE_BTNS_OPTS_ENABLED:
_btn_view_html->EnableWindow(TRUE);
_btn_rw_html->EnableWindow(TRUE);
_btn_show_list->EnableWindow(TRUE);
_btn_write_html->EnableWindow(TRUE);
_stt_html->EnableWindow(TRUE);
break;
case _STATE_BTNS_OPTS_DISABLED:
_btn_view_html->EnableWindow(FALSE);
_btn_rw_html->EnableWindow(FALSE);
_btn_show_list->EnableWindow(FALSE);
_btn_write_html->EnableWindow(FALSE);
_stt_html->EnableWindow(FALSE);
break;
default:
show_error_msg("Unknown options buttons state.", 0, this);
}
}
void csp_life::_set_state_btn_write_html(const bool is_active) {
_write_html = is_active;
if (is_active) _btn_write_html->SetCheck(BST_CHECKED);
else _btn_write_html->SetCheck(BST_UNCHECKED);
}
void csp_life::_show_file_info(const bool running, const bool clear) {
if (clear) {
_edit_info->SetWindowText("no file");
return;
}
CString str;
if (running) {
str.Format("%u (now: %u) dtgms in %u arches",
_csp_file.total_datagrams(),
_total_dtgms,
_csp_file.total_arches()
);
} else {
str.Format("%u dtgms in %u arches",
_csp_file.total_datagrams(),
_csp_file.total_arches()
);
}
_edit_info->SetWindowText(str);
}
int csp_life::_run_proc_helper(csp_life *const life) {
life->_must_stop = false;
life->_running = true;
int rev = life->_run_proc();
life->_set_state_btns_open(_STATE_BTNS_OPEN_CANCLOSE);
life->_set_state_btns_run(_STATE_BTNS_RUN_CANRUN);
life->_paused = false;
life->_running = false;
return rev;
}
int csp_life::_run_proc() {
if (0 != _make_socket()) {
show_error_msg("Can't create socket", 0, this);
goto exit_level_0;
}
_set_state_btns_open(_STATE_BTNS_OPEN_CANCLOSE);
_set_state_btns_run(_STATE_BTNS_RUN_CANSTOPR);
_total_dtgms = 0;
_show_file_info();
while (!_must_stop) {
if (_need_csp_flush) { // i really don't remember for what this stuff %)
_csp_file.flush(); // heh:) now it's only for html-rewrite function
_need_csp_flush = false;
}
if (_list_closing) _csp_list = NULL;
if (_paused) {
Sleep(500);
continue;
}
int rev = _can_read(_sock);
if (0 == rev) continue;
if (1 != rev) {
show_error_msg("Can't select() from socket", 0, this);
goto exit_level_1;
}
const int _total_dtgms_old = _total_dtgms;
// read data from socket
if (0 != _swallow(_sock)) {
show_error_msg("Can't perform \"swallow\" action (while working with datagram)", 0, this);
goto exit_level_1;
}
if (_total_dtgms_old != _total_dtgms) {
_show_file_info();
if (NULL != _csp_list) {
_csp_file.flush(csp_file::FLUSH_ARCHES);
_csp_list->update();
}
}
}
exit_level_1:
_kill_socket();
exit_level_0:
_csp_file.flush();
return 0;
}
int csp_life::_open_file() {
_close_file();
// open bin file
CString fn;
_edit_file->GetWindowText(fn);
DWORD dwCreationDisposition;
if (BST_CHECKED == _btn_clr_file->GetCheck()) dwCreationDisposition = CREATE_ALWAYS;
else dwCreationDisposition = OPEN_ALWAYS;
_file = CreateFile(fn, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL,
dwCreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == _file) {
_file = NULL;
return -1;
}
if (0 != _csp_file.use_handle(_file)) {
_close_file();
return -1;
}
// open html file (funny, but it was swap in previous version :^) )
CString sn;
if (BST_CHECKED == _btn_cr_new_html->GetCheck()) {
sn.Format("%s.html", fn);
_html_file = CreateFile(sn, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
} else {
int n = 0;
do {
sn.Format("%s.%03i.html", fn, n);
_html_file = CreateFile(sn, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == _html_file) {
_html_file = NULL;
++n;
}
} while (NULL == _html_file && n < 999);
}
if (NULL == _html_file) {
_close_file();
return -1;
}
_edit_html_file->SetWindowText(sn);
DWORD wr;
WriteFile(_html_file, _html_intro, (int)strlen(_html_intro), &wr, NULL);
if (strlen(_html_intro) != wr) {
show_error_msg("Can't write to html file", 0, this);
}
// copy css file
if (0 != _copy_css(sn)) {
show_error_msg("Can't copy CSS file", 0, this);
}
_show_file_info(false);
_opened = true;
return 0;
}
int csp_life::_close_file() {
if (NULL != _file) {
_csp_file.finish_using();
CloseHandle(_file);
_file = NULL;
}
if (NULL != _html_file) {
DWORD wr;
if (!_html_file_corrupted) {
WriteFile(_html_file, _html_outtro, (int)strlen(_html_outtro), &wr, NULL);
} else _html_file_corrupted = false;
CloseHandle(_html_file);
_html_file = NULL;
}
_edit_html_file->SetWindowText("");
_show_file_info(false, true);
_opened = false;
return 0;
}
int csp_life::_copy_css(CString &html_fn) {
char buf[MAX_PATH];
char *fp;
GetFullPathName(html_fn, MAX_PATH, buf, &fp);
*fp = '\0';
CString css_fn;
css_fn.Format("%sstyle.css", buf);
if (FALSE != PathFileExists(css_fn)) return 0;
if (FALSE == CopyFile(_css_file_name, css_fn, TRUE)) return -1;
return 0;
}
int csp_life::_make_socket() {
_kill_socket();
_sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (INVALID_SOCKET == _sock) return -1;
CString host;
_edit_host->GetWindowText(host);
cdm_addr_info ai;
ai.set_host(host);
if (0 != bind(_sock, ai.saddr(), ai.saddr_sz())) return -1;
unsigned long arg = 1;
if (0 != ioctlsocket(_sock, SIO_RCVALL, &arg)) return -1;
return 0;
}
int csp_life::_kill_socket() {
if (INVALID_SOCKET == _sock) return 0;
if (0 != closesocket(_sock)) return -1;
_sock = INVALID_SOCKET;
return 0;
}
int csp_life::_can_read(const SOCKET sock, const int timeout_ms) {
fd_set set;
set.fd_count = 1;
set.fd_array[0] = sock;
timeval to;
to.tv_sec = 0;
to.tv_usec = timeout_ms * 1000;
int rev = select(0, &set, NULL, NULL, &to);
switch (rev) {
case SOCKET_ERROR: return -1;
case 0: return 0;
default: return 1;
}
return -1; // dummy return
}
int csp_life::_can_read_sz(const SOCKET sock) {
unsigned long arg;
ioctlsocket(sock, FIONREAD, &arg);
return arg;
}
int csp_life::_buf_ctl(const bool alloc) {
if (alloc) {
if (NULL != _buf) return 0;
_buf = (char *)malloc(_NET_BUF_SZ * sizeof(char));
if (NULL == _buf) return -1;
return 0;
}
free(_buf);
_buf = NULL;
return 0;
}
int csp_life::_read_datagram(const SOCKET sock) {
if (0 != _buf_ctl()) return -1;
_saddr_sz_gived = sizeof(_saddr_gived);
int rev = recvfrom(sock, _buf, _NET_BUF_SZ, 0, &_saddr_gived, &_saddr_sz_gived);
if (SOCKET_ERROR == rev) return -1;
_dtgm = _buf;
_dtgm_sz = rev;
return 0;
}
int csp_life::_swallow(const SOCKET sock) {
while (0 < _can_read_sz(sock) && !_must_stop) {
_read_datagram(sock);
if (!_csp_filter.test((header_ip *)_dtgm)) continue;
if (0 != _csp_file.add_dtgm(_dtgm, _dtgm_sz)) return -1;
++_total_dtgms;
if (_write_html) {
if (_html_file_corrupted) {
SetFilePointer(_html_file, 0, NULL, FILE_BEGIN);
SetEndOfFile(_html_file);
DWORD wr;
WriteFile(_html_file, _html_intro, (int)strlen(_html_intro), &wr, NULL);
_html_file_corrupted = false;
}
_parser.parse(_dtgm, _dtgm_sz);
DWORD wr;
WriteFile(_html_file, _parser.html(), _parser.html_len(), &wr, NULL);
}
}
return 0;
}
Соседние файлы в папке src