Добавил:
korayakov
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
/*******************************************************************************
* file: dm_core.h *
* version: 0.9.1 *
* author: d-evil [tmd] (mailto:d-evil.tmd@mail.ru) *
* description: not available *
*******************************************************************************/
#ifndef DM_CORE_INCLUDED
#define DM_CORE_INCLUDED
////////////////////////////////////////////////////////////////////////////////
// headers
#include <malloc.h>
#include <time.h>
#include <afxwin.h>
#include <winsock2.h>
namespace dm_core {
////////////////////////////////////////////////////////////////////////////////
// global options
static const int DEFAULT_DATAGRAM_SIZE = 0xFFF*2;
////////////////////////////////////////////////////////////////////////////////
// datagrams description
static const int DTGM_TYPE_REQUEST = 0x1; // ask server to recv file
static const int DTGM_TYPE_DATA = 0x2; // data
static const int DTGM_TYPE_APPEAL = 0x4; // ask client to send file block
static const int DTGM_TYPE_DISCARD = 0x8; // cancel send/recv
////////////////////////////////////////////////////////////////////////////////
// discard types
static const int DISCARD_TYPE_CANCEL = 0x1; // cancel
// data[int]:
// -1 - discard all (close connection)
// 0 - discard requests (connection accepted)
// >0 - discard a number of blocks, successfully received number of info blocks (success)
// param: not used
static const int DISCARD_TYPE_DONE = 0x2; // done
// data[int]: total parts done
// param: not used
static const int DISCARD_TYPE_CONFIRM = 0x3; // confirm
// data: not used
// param: not used
struct sdm_dtgm {
int type;
int session_id; // session id
};
struct sdm_dtgm_request {
int type;
int session_id; // session id
int pckt_sz;
unsigned int file_sz;
int fn_len;
char fname[1];
};
struct sdm_dtgm_data {
int type; // type of datagram
int session_id; // session id
int ss_id; // id of sub system
int num; // number of datablock
int data_sz; // actual data size
char data[1];
};
struct sdm_dtgm_appeal {
int type;
int session_id; // session id
int ss_id;
int pckt_sz;
int done_parts;
int count;
int nums[1];
};
////////////////////////////////////////////////////////////////////////////////
// sfx_data declaration
union sfx_data {
short s;
unsigned short us;
int i;
unsigned int ui;
void *p;
sfx_data(): p(NULL) {}
sfx_data(short sv) { s = sv; }
sfx_data(unsigned short usv) { us = usv; }
sfx_data(int iv) { i = iv; }
sfx_data(unsigned int uiv) { ui = uiv; }
sfx_data(void *pv) { p = pv; }
operator short() const { return s; }
operator unsigned short() const { return us; }
operator int() const { return i; }
operator unsigned int() const { return ui; }
operator void *() const { return p; }
template<class T> operator T *() const { return (T *)p; }
};
struct sdm_dtgm_discard {
int type;
int session_id; // session id
int ss_id; // -1 if not used
int dtype; // discard type
sfx_data data;
sfx_data param;
};
////////////////////////////////////////////////////////////////////////////////
// cdm_dl_item declaration
class cdm_dl_item {
public:
cdm_dl_item(const int refc = 1): _refc(refc) {}
cdm_dl_item(cdm_dl_item *const next,
cdm_dl_item *const prev,
const int refc = 1)
{
_next = next;
_prev = prev;
_refc = refc;
}
int refc() const { return _refc; }
void set_refc(const int refc) { _refc = refc; }
int inc_refc() { return ++_refc;}
int dec_refc() { return --_refc;}
void set(cdm_dl_item *const next, cdm_dl_item *const prev = NULL) {
_next = next; _prev = prev;
}
void set_next(cdm_dl_item *const next) { _next = next; }
void set_prev(cdm_dl_item *const prev) { _prev = prev; }
cdm_dl_item *next() const { return _next; }
cdm_dl_item *prev() const { return _prev; }
private:
int _refc;
cdm_dl_item *_next;
cdm_dl_item *_prev;
};
////////////////////////////////////////////////////////////////////////////////
// cdm_dl_list declaration
class cdm_dls_list {
public:
cdm_dls_list();
~cdm_dls_list();
cdm_dl_item *first() const { return _first; }
int count() const { return _inum; }
int add(cdm_dl_item *const item, const int timeout = INFINITE);
int del(cdm_dl_item *const item, const int timeout = INFINITE);
int lock(const int timeout = -1);
int ulock();
private:
int _inum;
cdm_dl_item *_first;
HANDLE _mutex;
};
////////////////////////////////////////////////////////////////////////////////
// cdm_addr_info declaration
class cdm_addr_info {
public:
////////////////////////////////////////////////////////////////////////////
// error codes [-5000...-5099]
static const int ERC_CANTRESOLVE = -5005;
static const int ERC_NOMEM = -5010;
static const int ERC_WSA = -5066;
cdm_addr_info();
cdm_addr_info(const char *const host, const unsigned short port);
~cdm_addr_info();
in_addr ip() const { return _saddr_in.sin_addr; }
unsigned short port() const { return _saddr_in.sin_port; }
int afam() const { return _saddr_in.sin_family; }
char *ip_str() const { return _ip_str; }
char *port_str() const { return _port_str; }
char *host() const { return _host; }
sockaddr *saddr() { return (sockaddr *)&_saddr_in; }
sockaddr_in *saddrin() { return &_saddr_in; }
int saddr_sz() const { return sizeof(_saddr_in); }
int set(const sockaddr_in *const saddrin);
int set(const char *const host, const unsigned short port);
int set_port(const unsigned short port);
int set_host(const char *const host);
// return 0 on success and -1 on error
static int resolve_host(const char *const host, in_addr *const addr);
protected:
int _set_ip(const in_addr ip);
int _updt_host();
private:
static const int MX_PORTLEN = 8;
sockaddr_in _saddr_in;
char *_ip_str;
char *_port_str;
char *_host;
};
////////////////////////////////////////////////////////////////////////////////
// cdm_file_info declaration
class cdm_file_info {
public:
cdm_file_info();
cdm_file_info(const cdm_file_info &ifile);
cdm_file_info(const char *const path, const bool ch_name);
cdm_file_info(const char *const name);
~cdm_file_info();
char *name() const { return _name; }
char *path() const { return _path; }
int name_len() const { return _name_len; }
int path_len() const { return _path_len; }
int set_name(const char *const name);
int set_path(const char *const path, const bool ch_name = true);
unsigned int sz() const { return _sz; }
void set_sz(const unsigned int sz) { _sz = sz; }
static int extract_filename(const char *const path, const int len = 0);
protected:
void _init();
private:
char *_name;
int _name_len;
char *_path;
int _path_len;
unsigned int _sz;
};
////////////////////////////////////////////////////////////////////////////////
// cdm_fwriter declaration
class cdm_fwriter {
public:
cdm_fwriter();
~cdm_fwriter();
int id() const { return _id; }
void set_id(const int id) { _id = id; }
int next_num() const { return _next_num; }
int inc_next_num() { return ++_next_num; }
int open(const char *const mode);
int close();
int write(const char *const buf, const int len);
cdm_addr_info *addr_info() { return &_addr_info; }
cdm_file_info *file_info() { return &_file_info; }
protected:
private:
int _id;
int _next_num;
FILE *_file;
cdm_addr_info _addr_info;
cdm_file_info _file_info;
};
////////////////////////////////////////////////////////////////////////////////
// cdm_socket declaration
class cdm_socket {
public:
////////////////////////////////////////////////////////////////////////////
// public cdm_socket states [5100..5199]
static const int STATE_NONE = 5100;
static const int STATE_ZOMBIE = 5190;
static const int EXTSTATE_NONE = 6100;
cdm_socket();
~cdm_socket();
SOCKET sock() const { return _sock; }
char *dtgm() const { return _buf; }
void *ui_data() const { return _ui_data; }
void set_ui_data(void *const ui_data) { _ui_data = ui_data; }
int pckt_sz() const { return _pckt_sz; }
int set_pckt_sz(const int pckt_sz);
sockaddr_in *saddrin() { return &_saddrin; }
int saddrin_sz() const { return _saddrin_sz; }
int state() const { return _state; }
int ext_state() const { return _ext_state; }
cdm_addr_info *addr_info() { return &_addr_info; }
int bind();
int can_read();
int can_write();
int can_read_size();
int recv_dtgm();
int send_dtgm();
int send_dtgm(char *const dtgm);
int send_dtgm(sockaddr_in *const saddrin, const int saddrin_sz);
int send_dtgm(const char *const dtgm, const int dtgm_size,
sockaddr_in *const saddrin, const int saddrin_sz);
int dtgm_type() { return ((sdm_dtgm *)_buf)->type; }
protected:
void _set_state(const int state) { _state = state; }
void _set_ext_state(const int ext_state) { _ext_state = ext_state; }
private:
SOCKET _sock;
int _state;
int _ext_state;
int _pckt_sz;
cdm_addr_info _addr_info;
sockaddr_in _saddrin;
int _saddrin_sz;
char *_buf;
void *_ui_data;
static const int _DEF_PCKT_SZ = DEFAULT_DATAGRAM_SIZE;
static const int _PCKT_MNSZ = sizeof(int);
};
////////////////////////////////////////////////////////////////////////////////
// cdm_frecv_subs declaration
class cdm_frecver;
class cdm_frecv_subs {
public:
////////////////////////////////////////////////////////////////////////////
// cdm_frecv_subs public constants
static const int STATE_NONE = 5400;
static const int STATE_STOPED = 5405;
static const int STATE_RUNNING = 5410;
static const int STATE_PAUSED = 5415;
static const int STATE_LAUNCHED = 5420;
static const int EXTSTATE_NONE = 6400;
static const int EXTSTATE_ACCEPTING = 6405;
static const int EXTSTATE_RECVING = 6410;
static const int EXTSTATE_TERMINATING = 6415;
static const int EXTSTATE_FINALIZING = 6420;
static const int EXTSTATE_ABORTED = 6425;
static const int EXTSTATE_DONE = 6430;
cdm_frecv_subs();
~cdm_frecv_subs();
cdm_addr_info *iaddr() { return &_iaddr; }
cdm_file_info *ifile() { return &_ifile; }
int id() const { return _id; }
void set_id(const int id) { _id = id; }
int session_id() const { return _session_id; }
void set_session_id(const int session_id) { _session_id = session_id; }
int state() const { return _state; }
int ext_state() const { return _ext_state; }
int init();
int start(const bool delayed = false); // open file, fill appeals buffer
int stop(const int ext_state = EXTSTATE_NONE); // close file
int add_dtgm(sdm_dtgm_data *const dtgm);
int terminate(const int ext_state = EXTSTATE_FINALIZING);
bool can_appeal();
bool need_appeal();
sdm_dtgm_appeal *get_appeal(const bool will_send = true);
int send_discard(const int dtype, const int data = 0, const int param = 0);
int dtgm_size() const { return _dtgm_size; }
int set_dtgm_size(const int dtgm_size);
int dtgms_count() const { return _dtgms_count; }
int set_dtgms_count(const int dtgms_count);
int appeals_count() const { return _appeals_count; }
int set_appeals_count(const int appeals_count);
int reappeal_timeout() const { return _reappeal_timeout; }
void set_reappeal_timeout(const int t) { _reappeal_timeout = t; }
cdm_frecver *parent() const { return _parent; }
void set_parent(cdm_frecver *const parent) { _parent = parent; }
void *ui_data() const { return _ui_data; }
void set_ui_data(void *const ui_data) { _ui_data = ui_data; }
int total_parts() const { return _total_parts; }
int done_parts() const { return _done_parts; }
void set_done_parts(const int done_parts) { _done_parts = done_parts; }
bool total_done() const { return _total_parts == _done_parts; }
void pause() {
if (STATE_RUNNING == _state) _state = STATE_PAUSED;
}
void resume() {
if (STATE_PAUSED == _state) _state = STATE_RUNNING;
}
bool must_die() { _dying = true; }
bool is_dying() const { return _dying; }
int die(const bool delayed = false);
clock_t up_time() const { return _run_time; }
void update_time() { clock_t t = clock(); _run_time += (t - _last_time); _last_time = t; }
protected:
void _init();
void _alloc_dtgms();
void _free_dtgms();
void _realloc_free_tbl();
void _realloc_bufs();
void _realloc_appeal();
void _free_appeal();
void _set_state(const int state) { _state = state; }
void _set_ext_state(const int ext_state) { _ext_state = ext_state; }
private:
char **_dtgms;
int *_free_tbl;
int _free_i;
int _dtgms_count;
int _dtgm_size;
int _data_size;
sdm_dtgm_appeal *_appeal;
int _appeals_count;
clock_t _last_time;
clock_t _run_time;
int _appeal_max;
int _appeal_next;
clock_t _last_appeal_time;
int _reappeal_timeout;
int _appeals_need_ahead;
int _appeals_changed;
HANDLE _hfile;
int _done_parts;
int _total_parts;
cdm_addr_info _iaddr;
cdm_file_info _ifile;
int _id;
int _state;
int _ext_state;
int _session_id;
cdm_frecver *_parent;
void *_ui_data;
bool _dying;
static const int _DEF_DTGMS_COUNT = 32;
static const int _DEF_APEALS_COUNT = 4;
static const int _DEF_DTGM_SIZE = DEFAULT_DATAGRAM_SIZE;
static const int _DEF_REAPPEAL_TIMEOUT = 200; // in mseconds
static const int _DEF_APPEALS_NEEDAHEAD = _DEF_APEALS_COUNT * 2/3;
};
////////////////////////////////////////////////////////////////////////////////
// cdm_frecver declaration
class cdm_frecver: public cdm_socket {
public:
////////////////////////////////////////////////////////////////////////////
// public cdm_frecver sates [5200..5399]
static const int STATE_RUNNING = 5305;
static const int STATE_PAUSED = 5310;
static const int STATE_STOPED = 5315;
static const int STATE_LAUNCHED = 5320;
static const int EXTSTATE_LISTENING = 6305;
static const int EXTSTATE_ACCEPTING = 6310;
static const int EXTSTATE_TERMINATING = 6315;
cdm_frecver();
~cdm_frecver();
cdm_frecv_subs *new_subs() const { return new _cdm_frecv_subs; }
void del_subs(cdm_frecv_subs *const subs) { delete (_cdm_frecv_subs *)subs; }
void add_subs(cdm_frecv_subs *const subs);
void remove_subs(cdm_frecv_subs *const subs);
int subs_count() const { return _subs.count(); }
cdm_frecv_subs *get_subs(const int id);
cdm_frecv_subs *get_session(const int session_id);
cdm_frecv_subs *subs_first() const { return (_cdm_frecv_subs *)_subs.first(); }
cdm_frecv_subs *subs_next(cdm_frecv_subs *const subs) const {
return (_cdm_frecv_subs *)(((_cdm_frecv_subs *)subs)->next());
}
int start(const bool delayed = false);
int stop();
void pause() {
if (STATE_RUNNING == state()) _set_state(STATE_PAUSED);
}
void resume() {
if (STATE_PAUSED == state()) _set_state(STATE_RUNNING);
}
bool must_die() { _dying = true; }
bool is_dying() const { return _dying; }
int die(const bool delayed = false);
int kill_subs(cdm_frecv_subs *const subs);
protected:
class _cdm_frecv_subs: public cdm_frecv_subs, public cdm_dl_item {};
private:
cdm_dls_list _subs;
bool _binded;
bool _dying;
};
////////////////////////////////////////////////////////////////////////////////
// cdm_fsender declaration
class cdm_fsender: public cdm_socket {
public:
////////////////////////////////////////////////////////////////////////////
// public cdm_fsender sates [5200..5399]
static const int STATE_RUNNING = 5205;
static const int STATE_PAUSED = 5210;
static const int STATE_STOPED = 5215;
static const int STATE_LAUNCHED = 5220;
static const int EXTSTATE_REQUESTING = 6205;
static const int EXTSTATE_SENDING = 6210;
static const int EXTSTATE_TERMINATING = 6215;
static const int EXTSTATE_CANCELED = 6220;
static const int EXTSTATE_DONE = 6225;
cdm_fsender();
~cdm_fsender();
cdm_file_info *ifile() { return &_ifile; }
cdm_addr_info *iaddr() { return &_iaddr; }
int session_id() const { return _session_id; }
void set_session_id(const int session_id) { _session_id = session_id; }
int start(const bool delayed = false);
int stop(const int ext_state = EXTSTATE_NONE);
bool need_request();
int send_request();
void accepted() { _set_ext_state(EXTSTATE_SENDING); }
int send_data(const int id, int *const appeals, const int count);
int send_discard(const int ss_id, const int dtype, const int data = 0, const int param = 0);
int total_parts() const { return _total_parts; }
int done_parts() const { return _done_parts; }
int add_parts(const int num);
void set_done_parts(const int done_parts) { _done_parts = done_parts; }
void pause() {
if (STATE_RUNNING == state()) _set_state(STATE_PAUSED);
}
void resume() {
if (STATE_PAUSED == state()) _set_state(STATE_RUNNING);
}
bool must_die() { _dying = true; }
bool is_dying() const { return _dying; }
int die(const bool delayed = false);
clock_t up_time() const { return _run_time; }
void update_time() { clock_t t = clock(); _run_time += (t - _last_time); _last_time = t; }
protected:
// int _realloc_dtgm(const int new_pckt_sz = 0);
// int _free_dtgm();
private:
int _data_sz;
sdm_dtgm_data *_send_dtgm;
int _session_id;
bool _dying;
HANDLE _hfile;
int _total_parts;
int _done_parts;
clock_t _last_request_time;
int _rerequest_timeout; // in milliseconds
clock_t _run_time;
clock_t _last_time;
cdm_file_info _ifile;
cdm_addr_info _iaddr;
static const int _DEF_REREQUEST_TIMEOUT = 2000;
};
////////////////////////////////////////////////////////////////////////////////
// cdm_uiproto declaration
class cdm_uiproto {
public:
////////////////////////////////////////////////////////////////////////////
// cdm_uiproto public constants
static const int FSENDER_CH_STATE = 0x1;
// static const int FSENDER_CH_EXTSTATE = 0x2;
static const int FSENDER_CH_IADDR = 0x4;
static const int FSENDER_CH_IFILE = 0x8;
static const int FSENDER_CH_PROGRESS = 0x10;
static const int FSENDER_CH_ALL = 0xFFFFFFFF;
static const int FRECVER_CH_STATE = 0x1;
// static const int FRECVER_CH_EXTSTATE = 0x2;
static const int FRECVER_CH_IADDR = 0x4;
// static const int FRECVER_CH_IFILE = 0x8;
// static const int FRECVER_CH_PROGRESS = 0x10;
static const int FRECVER_CH_ALL = 0xFFFFFFFF;
static const int FSUBS_CH_STATE = 0x1;
static const int FSUBS_CH_EXTSTATE = 0x2;
static const int FSUBS_CH_IADDR = 0x4;
static const int FSUBS_CH_IFILE = 0x8;
static const int FSUBS_CH_PROGRESS = 0x10;
static const int FSUBS_CH_PARENT = 0x20;
static const int FSUBS_CH_ALL = 0xFFFFFFFF;
virtual int on_pure_dm_error(const int dm_error) = 0;
virtual int on_error(const int dm_error, const int os_error) = 0;
virtual int on_ext_error(void *const error) = 0;
virtual int on_frecver_ch(cdm_frecver *const frecver, const int ch_mask) = 0;
virtual int on_fsender_ch(cdm_fsender *const fsender, const int ch_mask) = 0;
virtual int on_subs_ch(cdm_frecv_subs *const subs, const int ch_mask) = 0;
virtual int on_frecver_rm(cdm_frecver *const frecver) = 0;
virtual int on_fsender_rm(cdm_fsender *const fsender) = 0;
virtual int on_subs_rm(cdm_frecv_subs *const subs) = 0;
virtual int on_accept(cdm_frecv_subs *const frecv_subs) = 0;
virtual int on_quit() = 0;
};
////////////////////////////////////////////////////////////////////////////////
// cdm_core declaration
class cdm_core {
public:
////////////////////////////////////////////////////////////////////////////
// dm error codes [-1..-4999]
// common errors
static const int ERC_ERROR = -1;
// threads and synchronization errors
static const int ERC_CRTHREAD = -1001;
static const int ERC_THRSUSPEND = -1002;
static const int ERC_THRRESUME = -1003;
static const int ERC_PAUSEMAIN = -1004;
// sockets errors
static const int ERC_SOCKSINIT = -1101;
static const int ERC_SOCKSBIND = -1102;
static const int ERC_SOCKSRESOLVE = -1103;
// memory errors
// static const int ERC_NOMEM = -1201;
// other errors
static const int ERC_ADDFSENDER = -4101;
static const int ERC_ADDFRECVER = -4102;
static const int ERC_STARTFSENDER = -4105;
static const int ERC_STARTFRECVER = -4106;
static const int ERC_STARTFSUBS = -4107;
static const int ERC_FSENDER_SPIT = -4110;
static const int ERC_FSENDER_FSIZE = -4210;
////////////////////////////////////////////////////////////////////////////
// dm frecver changes
static const int FRECV_CH_HOST = 0x1;
static const int FRECV_CH_IP = 0x2;
static const int FRECV_CH_PORT = 0x4;
static const int FRECV_CH_COUNT = 0x8;
static const int FRECV_CH_STATE = 0x10;
cdm_core();
~cdm_core();
int last_dm_error() { int tmp = _last_dm_error; _last_dm_error = 0; return tmp;}
int last_error() { int tmp = _last_error; _last_error = 0; return tmp; }
cdm_uiproto *get_ui() const { return _ui; }
int attach_ui(cdm_uiproto *const ui);
int nulljob_delay() const { return _nulljob_delay; }
int set_nulljob_delay(const int njd) { _nulljob_delay = njd; }
int init();
int run(const bool nt = true); // run in new thread if (nt==true)
int pause();
int upause();
int quit();
int swallow(cdm_frecver *const recver, int *const ch_mask);
int spit(cdm_fsender *const sender, int *const ch_mask);
int accept(cdm_frecver *const recver, int *const ch_mask);
int get_data(cdm_frecver *const recver, int *const ch_mask);
int discard(cdm_frecver *const recver, int *const ch_mask);
int appeal(cdm_fsender *const sender, int *const ch_mask);
int discard(cdm_fsender *const sender, int *const ch_mask);
cdm_frecver *new_frecver(const char *const host = NULL, const unsigned short port = 0);
cdm_fsender *new_fsender(const char *const host = NULL, const unsigned short port = 0);
int add_frecver(cdm_frecver *const recver);
int add_fsender(cdm_fsender *const sender);
int start_frecver(cdm_frecver *const recver, const bool delayed = false);
int start_fsender(cdm_fsender *const sender, const bool delayed = false);
int del_frecver(cdm_frecver *const recver);
int del_fsender(cdm_fsender *const sender);
int free_frecver(cdm_frecver *const recver);
int free_fsender(cdm_fsender *const sender);
char *get_hostname() const { return _hostname; }
unsigned short get_defport() const { return _def_port; }
int speeed() const { return _speeed; }
void reset_speeed() {_speeed = 0; }
static bool use_bugs() { return _use_bugs; }
static void set_use_bugs(const bool use_bugs = false) { _use_bugs = use_bugs; }
char *def_dir() const { return _def_dir; }
protected:
////////////////////////////////////////////////////////////////////////////
// protected types
class _cdm_frecver: public cdm_dl_item, public cdm_frecver {};
class _cdm_fsender: public cdm_dl_item, public cdm_fsender {};
int _run();
static inline int __stdcall _run_helper(cdm_core *const core) {
return core->_run();
}
int _parse_frecvers(int *const num = NULL);
int _parse_fsenders(int *const num = NULL);
////////////////////////////////////////////////////////////////////////////
// protected error loggers
int _pure_dm_error(const int dm_error = -1) {
return (_last_dm_error = dm_error);
}
int _error(const int dm_error = 0) {
_last_error = GetLastError();
return (_last_dm_error = dm_error);
}
int _sock_error(const int dm_error = 0) {
_last_error = WSAGetLastError();
return (_last_dm_error = dm_error);
}
int _ui_on_dm_error() {
int rev = _ui->on_pure_dm_error(_last_dm_error);
_last_dm_error = 0;
return rev;
}
int _ui_on_error() {
int rev = _ui->on_error(_last_dm_error, _last_error);
_last_dm_error = 0;
_last_error = 0;
return rev;
}
private:
HANDLE _thread_h;
DWORD _thread_id;
HANDLE _running_mtx;
bool volatile _must_stop;
cdm_uiproto *_ui;
cdm_dls_list _frecvers;
cdm_dls_list _fsenders;
////////////////////////////////////////////////////////////////////////////
// event handlers
// edm_event _ev_ne
WSADATA _wsa_data;
int _last_error;
int _last_dm_error;
int _nulljob_delay;
static const int _DEF_NULLJOB_DELAY = 200;
char *_hostname;
static const int _HOSTNAME_MXLEN = 256;
static const unsigned short _def_port = 0xDEAD;
int volatile _speeed;
int _speeed_prev;
static bool _use_bugs;
char *_def_dir;
};
} // end of namespace "dm_core"
#endif