author | Michael Krelin <hacker@klever.net> | 2004-07-05 01:53:09 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2004-07-05 01:53:09 (UTC) |
commit | fb8b43dbce8bc310718614384297aeaabb9a3cbb (patch) (unidiff) | |
tree | af9d2c2b71ddffff93a97a02fe26611096b78645 /BigBrotherDoc.cpp | |
download | bigbrother-fb8b43dbce8bc310718614384297aeaabb9a3cbb.zip bigbrother-fb8b43dbce8bc310718614384297aeaabb9a3cbb.tar.gz bigbrother-fb8b43dbce8bc310718614384297aeaabb9a3cbb.tar.bz2 |
initial commit into svn repository
git-svn-id: http://svn.klever.net/kin/bigbrother/trunk@1 fe716a7a-6dde-0310-88d9-d003556173a8
-rw-r--r-- | BigBrotherDoc.cpp | 1039 |
1 files changed, 1039 insertions, 0 deletions
diff --git a/BigBrotherDoc.cpp b/BigBrotherDoc.cpp new file mode 100644 index 0000000..4a5328e --- a/dev/null +++ b/BigBrotherDoc.cpp | |||
@@ -0,0 +1,1039 @@ | |||
1 | // BigBrotherDoc.cpp : implementation of the CBigBrotherDoc class | ||
2 | // | ||
3 | |||
4 | #include "stdafx.h" | ||
5 | #include "BigBrother.h" | ||
6 | |||
7 | #include "BigBrotherDoc.h" | ||
8 | #include "BigBrotherView.h" | ||
9 | #include "ActivityView.h" | ||
10 | #include "HostPropertyPages.h" | ||
11 | #include "MainFrm.h" | ||
12 | #include "Preferences.h" | ||
13 | |||
14 | #ifdef _DEBUG | ||
15 | #define new DEBUG_NEW | ||
16 | #undef THIS_FILE | ||
17 | static char THIS_FILE[] = __FILE__; | ||
18 | #endif | ||
19 | |||
20 | ///////////////////////////////////////////////////////////////////////////// | ||
21 | // CBigBrotherDoc | ||
22 | |||
23 | IMPLEMENT_SERIAL(CBigBrotherDoc, CDocument, VERSIONABLE_SCHEMA | 3 ) | ||
24 | IMPLEMENT_SERIAL(CBrother, CObject, VERSIONABLE_SCHEMA | 2 ) | ||
25 | IMPLEMENT_SERIAL(CAction, CObject, VERSIONABLE_SCHEMA | 1 ) | ||
26 | IMPLEMENT_SERIAL(CLogEntry, CObject, VERSIONABLE_SCHEMA | 2 ) | ||
27 | |||
28 | BEGIN_MESSAGE_MAP(CBigBrotherDoc, CDocument) | ||
29 | //{{AFX_MSG_MAP(CBigBrotherDoc) | ||
30 | ON_COMMAND(ID_BROTHERS_NEW, OnBrothersNew) | ||
31 | ON_UPDATE_COMMAND_UI(ID_BROTHERS_ADDBROTHER, OnUpdateBrothersAddbrother) | ||
32 | ON_COMMAND(ID_BROTHERS_ADDBROTHER, OnBrothersAddbrother) | ||
33 | ON_UPDATE_COMMAND_UI(ID_BROTHERS_DELETE, OnUpdateBrothersDelete) | ||
34 | ON_COMMAND(ID_BROTHERS_DELETE, OnBrothersDelete) | ||
35 | ON_COMMAND(ID_FILE_PREFERENCES, OnFilePreferences) | ||
36 | ON_UPDATE_COMMAND_UI(ID_FILE_PAUSE, OnUpdateFilePause) | ||
37 | ON_COMMAND(ID_FILE_PAUSE, OnFilePause) | ||
38 | ON_UPDATE_COMMAND_UI(ID_VIEW_HOSTPROPERTIES, OnUpdateViewHostproperties) | ||
39 | ON_COMMAND(ID_VIEW_HOSTPROPERTIES, OnViewHostproperties) | ||
40 | //}}AFX_MSG_MAP | ||
41 | END_MESSAGE_MAP() | ||
42 | |||
43 | ///////////////////////////////////////////////////////////////////////////// | ||
44 | // CBigBrotherDoc construction/destruction | ||
45 | |||
46 | CBigBrotherDoc::CBigBrotherDoc() | ||
47 | : m_MaxLogTime(0,1,0,0), m_Threads(0), m_MaxThreads(10), m_PingSize(32), m_RootBrother(NULL), | ||
48 | m_bSaveOnShutdown(TRUE), m_AutoSave(0,0,30,0), m_bStoreLastActivity(FALSE) | ||
49 | { | ||
50 | m_BBView = NULL; | ||
51 | m_AView = NULL; | ||
52 | } | ||
53 | |||
54 | CBigBrotherDoc::~CBigBrotherDoc() | ||
55 | { | ||
56 | CleanUp(); | ||
57 | } | ||
58 | |||
59 | BOOL CBigBrotherDoc::OnNewDocument() | ||
60 | { | ||
61 | if (!CDocument::OnNewDocument()) | ||
62 | return FALSE; | ||
63 | |||
64 | CleanUp(); | ||
65 | m_RootBrother=new CBrother(); | ||
66 | |||
67 | return TRUE; | ||
68 | } | ||
69 | |||
70 | ///////////////////////////////////////////////////////////////////////////// | ||
71 | // CBigBrotherDoc serialization | ||
72 | |||
73 | void CBigBrotherDoc::Serialize(CArchive& ar) | ||
74 | { | ||
75 | ASSERT_VALID(this); | ||
76 | |||
77 | CDocument::Serialize(ar); | ||
78 | |||
79 | ar.MapObject(this); | ||
80 | ar.SerializeClass(RUNTIME_CLASS(CBigBrotherDoc)); | ||
81 | |||
82 | if (ar.IsStoring()) | ||
83 | { | ||
84 | // Store to archive | ||
85 | ar << m_PingSize; | ||
86 | ar << m_MaxThreads; | ||
87 | ar << m_MaxLogTime; | ||
88 | ar << m_bSaveOnShutdown; | ||
89 | ar << m_AutoSave; | ||
90 | ar << m_LogFile; | ||
91 | ar << m_bStoreLastActivity; | ||
92 | ar << m_RootBrother; | ||
93 | m_Brotherhood.Serialize(ar); | ||
94 | } | ||
95 | else | ||
96 | { | ||
97 | UINTschema = ar.GetObjectSchema(); | ||
98 | #ifndefNDEBUG | ||
99 | { | ||
100 | CString tmp; | ||
101 | tmp.Format("Doc-OSchema: %u\n",schema); | ||
102 | TRACE0(tmp); | ||
103 | } | ||
104 | #endif | ||
105 | CleanUp(); | ||
106 | m_ThisMap.RemoveAll(); | ||
107 | // Read from archive | ||
108 | ar >> m_PingSize; | ||
109 | ar >> m_MaxThreads; | ||
110 | ar >> m_MaxLogTime; | ||
111 | if(schema>=2){ | ||
112 | ar >> m_bSaveOnShutdown; | ||
113 | ar >> m_AutoSave; | ||
114 | } | ||
115 | ar >> m_LogFile; | ||
116 | if(schema>=3) | ||
117 | ar >> m_bStoreLastActivity; | ||
118 | ar >> m_RootBrother; | ||
119 | m_Brotherhood.Serialize(ar); | ||
120 | // Read from archive | ||
121 | m_ThisMap.RemoveAll(); | ||
122 | // Log loading | ||
123 | CString logLine; | ||
124 | logLine.Format(IDS_LOG_LOADFILE,(LPCTSTR)GetTitle()); | ||
125 | logLine=CTime::GetCurrentTime().Format(IDS_LOG_DATEFORMAT)+" "+logLine; | ||
126 | LogLine(logLine); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | ///////////////////////////////////////////////////////////////////////////// | ||
131 | // CBigBrotherDoc diagnostics | ||
132 | |||
133 | #ifdef _DEBUG | ||
134 | void CBigBrotherDoc::AssertValid() const | ||
135 | { | ||
136 | CDocument::AssertValid(); | ||
137 | } | ||
138 | |||
139 | void CBigBrotherDoc::Dump(CDumpContext& dc) const | ||
140 | { | ||
141 | CDocument::Dump(dc); | ||
142 | } | ||
143 | #endif //_DEBUG | ||
144 | |||
145 | ///////////////////////////////////////////////////////////////////////////// | ||
146 | // CBigBrotherDoc commands | ||
147 | |||
148 | CBrother::CBrother(CBrother *daddy) | ||
149 | { | ||
150 | CleanUp(); | ||
151 | m_Daddy=daddy; | ||
152 | ParentalAdjust(TRUE); | ||
153 | } | ||
154 | |||
155 | void CBrother::CleanUp() | ||
156 | { | ||
157 | m_Item=NULL; | ||
158 | flags=0; | ||
159 | m_bLog=TRUE; | ||
160 | m_Daddy=NULL; | ||
161 | m_Desc.Empty(); | ||
162 | m_Down.CleanUp(); | ||
163 | m_Host.Empty(); | ||
164 | m_IntervalBad=30; | ||
165 | m_IntervalGood=30; | ||
166 | m_Retries=3; | ||
167 | m_TimeOut=5000; | ||
168 | m_Up.CleanUp(); | ||
169 | m_bPinged=FALSE; | ||
170 | m_bPending=FALSE; | ||
171 | m_bIsUp=TRUE; | ||
172 | m_bPinging=FALSE; | ||
173 | m_bUp=TRUE; | ||
174 | m_bToKill=FALSE; | ||
175 | m_Doc=NULL; | ||
176 | } | ||
177 | |||
178 | CAction::CAction() | ||
179 | { | ||
180 | CleanUp(); | ||
181 | } | ||
182 | |||
183 | void CAction::CleanUp() | ||
184 | { | ||
185 | flags=0; | ||
186 | m_Custom.Empty(); | ||
187 | m_Sound.Empty(); | ||
188 | } | ||
189 | |||
190 | CAction& CAction::operator=(CAction& src) | ||
191 | { | ||
192 | flags=src.flags; | ||
193 | m_Custom=src.m_Custom; | ||
194 | m_Sound=src.m_Sound; | ||
195 | return *this; | ||
196 | } | ||
197 | |||
198 | void CBrother::ParentalAdjust(BOOL cleanUp) | ||
199 | { | ||
200 | if(!m_Daddy){ | ||
201 | flags|=flagsOverrideIntervals|flagsOverrideTimeout|flagsOverrideRetries|flagsOverrideActions|flagsOverrideLogging; | ||
202 | if(cleanUp){ | ||
203 | m_Desc.LoadString(IDS_ROOTNODENAME); | ||
204 | m_IntervalBad=30, m_IntervalGood=30; | ||
205 | m_TimeOut=5000; | ||
206 | m_Retries=3; | ||
207 | { | ||
208 | m_Up.CleanUp(); | ||
209 | m_Down.CleanUp(); | ||
210 | m_Up.flags=m_Down.flags=CAction::flagsPlayASound; | ||
211 | m_Up.m_Sound.LoadString(IDS_ACTION_HOST_UP); | ||
212 | m_Down.m_Sound.LoadString(IDS_ACTION_HOST_DOWN); | ||
213 | } | ||
214 | m_bLog=TRUE; | ||
215 | } | ||
216 | }else{ | ||
217 | if(!(flags&flagsOverrideIntervals)){ | ||
218 | CBrother *parent = m_Daddy; | ||
219 | while(!(parent->flags&flagsOverrideIntervals)){ | ||
220 | ASSERT(parent->m_Daddy); | ||
221 | parent=parent->m_Daddy; | ||
222 | } | ||
223 | m_IntervalBad=parent->m_IntervalBad; | ||
224 | m_IntervalGood=parent->m_IntervalGood; | ||
225 | } | ||
226 | if(!(flags&flagsOverrideTimeout)){ | ||
227 | CBrother *parent = m_Daddy; | ||
228 | while(!(parent->flags&flagsOverrideTimeout)){ | ||
229 | ASSERT(parent->m_Daddy); | ||
230 | parent=parent->m_Daddy; | ||
231 | } | ||
232 | m_TimeOut=parent->m_TimeOut; | ||
233 | } | ||
234 | if(!(flags&flagsOverrideRetries)){ | ||
235 | CBrother *parent = m_Daddy; | ||
236 | while(!(parent->flags&flagsOverrideRetries)){ | ||
237 | ASSERT(parent->m_Daddy); | ||
238 | parent=parent->m_Daddy; | ||
239 | } | ||
240 | m_Retries=parent->m_Retries; | ||
241 | } | ||
242 | if(!(flags&flagsOverrideActions)){ | ||
243 | CBrother *parent = m_Daddy; | ||
244 | while(!(parent->flags&flagsOverrideActions)){ | ||
245 | ASSERT(parent->m_Daddy); | ||
246 | parent=parent->m_Daddy; | ||
247 | } | ||
248 | m_Up=parent->m_Up; | ||
249 | m_Down=parent->m_Down; | ||
250 | } | ||
251 | if(!(flags&flagsOverrideLogging)){ | ||
252 | CBrother *parent = m_Daddy; | ||
253 | while(!(parent->flags&flagsOverrideLogging)){ | ||
254 | ASSERT(parent->m_Daddy); | ||
255 | parent=parent->m_Daddy; | ||
256 | } | ||
257 | m_bLog=parent->m_bLog; | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | |||
262 | void CBigBrotherDoc::OnChangedViewList() | ||
263 | { | ||
264 | m_BBView=NULL; | ||
265 | m_AView=NULL; | ||
266 | POSITION p = GetFirstViewPosition(); | ||
267 | while(p){ | ||
268 | CView* v = GetNextView(p); | ||
269 | if(v->IsKindOf(RUNTIME_CLASS(CBigBrotherView))){ | ||
270 | ASSERT(!m_BBView); | ||
271 | m_BBView=(CBigBrotherView*)v; | ||
272 | }else if(v->IsKindOf(RUNTIME_CLASS(CActivityView))){ | ||
273 | ASSERT(!m_AView); | ||
274 | m_AView=(CActivityView*)v; | ||
275 | } | ||
276 | } | ||
277 | |||
278 | CDocument::OnChangedViewList(); | ||
279 | } | ||
280 | |||
281 | void CBigBrotherDoc::OnBrothersNew() | ||
282 | { | ||
283 | ASSERT(m_BBView); | ||
284 | CBrother *bro = m_BBView->GetCurrentBrother(); | ||
285 | ASSERT(bro); | ||
286 | CBrother *lb = new CBrother(bro); | ||
287 | m_Brotherhood.AddTail(lb); | ||
288 | SetModifiedFlag(); | ||
289 | m_BBView->AddBrother(lb); | ||
290 | m_BBView->GotoBrother(lb); | ||
291 | } | ||
292 | |||
293 | void CBigBrotherDoc::CheckPendingQueue() | ||
294 | { | ||
295 | if(flags&flagsSuspended) | ||
296 | return; | ||
297 | CTime currentTime = CTime::GetCurrentTime(); | ||
298 | CTime nearestCheck; | ||
299 | BOOL nearested = CheckPendingBrother(m_RootBrother,currentTime,nearestCheck,FALSE); | ||
300 | POSITION p = m_Brotherhood.GetHeadPosition(); | ||
301 | while(p){ | ||
302 | CBrother *b = (CBrother*)m_Brotherhood.GetNext(p); | ||
303 | ASSERT(b); | ||
304 | nearested|=CheckPendingBrother(b,currentTime,nearestCheck,nearested); | ||
305 | } | ||
306 | if(m_AutoSave.GetTotalMinutes()){ | ||
307 | CTime nc = m_AutoSaved+m_AutoSave; | ||
308 | if(nc<=currentTime){ | ||
309 | if(IsModified()) | ||
310 | DoFileSave(); | ||
311 | m_AutoSaved=currentTime; | ||
312 | while(nc<=currentTime) | ||
313 | nc=nc+m_AutoSave; | ||
314 | } | ||
315 | if((!nearested) || nc<nearestCheck){ | ||
316 | nearestCheck=nc; | ||
317 | nearested=TRUE; | ||
318 | } | ||
319 | } | ||
320 | if(!nearested) | ||
321 | return; | ||
322 | currentTime = CTime::GetCurrentTime(); | ||
323 | CTimeSpan nextto = nearestCheck-currentTime; | ||
324 | UINTtimer = 60000; | ||
325 | if(nextto.GetTotalSeconds()<60) | ||
326 | timer=nextto.GetTotalSeconds()*1000; | ||
327 | if(m_BBView)// In case we're destroying.. | ||
328 | m_BBView->SetTimer(TM_CHECK,timer,NULL); | ||
329 | } | ||
330 | |||
331 | BOOL CBigBrotherDoc::CheckPendingBrother(CBrother* b,CTime& currentTime,CTime& nearestCheck,BOOL nearested) | ||
332 | { | ||
333 | if(!b) | ||
334 | return FALSE; | ||
335 | if(b->m_Host.IsEmpty() || b->m_bPinging){ | ||
336 | b->m_bPending=FALSE; | ||
337 | return FALSE; | ||
338 | } | ||
339 | if(b->m_bPending){ | ||
340 | TryBrother(b); | ||
341 | return FALSE; | ||
342 | } | ||
343 | CTime nextCheck = b->m_Pinged+CTimeSpan(b->m_bIsUp?b->m_IntervalGood:b->m_IntervalBad); | ||
344 | if(nextCheck<=currentTime){ | ||
345 | TryBrother(b); | ||
346 | return FALSE; | ||
347 | } | ||
348 | if((!nearested) || nextCheck<nearestCheck){ | ||
349 | nearestCheck=nextCheck; | ||
350 | return TRUE; | ||
351 | } | ||
352 | return FALSE; | ||
353 | } | ||
354 | |||
355 | void CBigBrotherDoc::TryBrother(CBrother *b) | ||
356 | { | ||
357 | ASSERT(!b->m_Host.IsEmpty()); | ||
358 | if(!(m_Threads<m_MaxThreads)){ | ||
359 | b->m_bPending=TRUE; | ||
360 | return; | ||
361 | } | ||
362 | if(!m_BBView) | ||
363 | return;// In case we're dying | ||
364 | m_BBView->SendMessage(WM_ACTIVITYCOUNT,1,0); | ||
365 | b->m_Doc=this; | ||
366 | b->m_bPinging=TRUE; | ||
367 | VERIFY(AfxBeginThread(CBrother::DoCheck,(LPVOID)b)); | ||
368 | } | ||
369 | |||
370 | UINT CBrother::DoCheck(LPVOID pParam) | ||
371 | { | ||
372 | CBrother *b = (CBrother*)pParam; | ||
373 | ASSERT(b); | ||
374 | return b->Check(); | ||
375 | } | ||
376 | |||
377 | UINT CBrother::Check() | ||
378 | { | ||
379 | CBigBrotherDoc *m_Doc = (CBigBrotherDoc*)CBrother::m_Doc; | ||
380 | |||
381 | if(!m_bToKill){ | ||
382 | ASSERT(m_Doc); | ||
383 | ASSERT(m_Doc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc))); | ||
384 | ASSERT(m_Doc->m_BBView); | ||
385 | m_Doc->m_BBView->PostMessage(WM_UPDATETREEBROTHER,0,(LPARAM)this); | ||
386 | } | ||
387 | |||
388 | CICMP *pICMP = NULL; | ||
389 | UINT dataSize = m_bToKill?32:m_Doc->m_PingSize; | ||
390 | in_addr ip; | ||
391 | ip.s_addr = inet_addr(m_Host); | ||
392 | CLogEntry le; | ||
393 | if(ip.s_addr==INADDR_NONE){ | ||
394 | hostent *he = gethostbyname(m_Host); | ||
395 | if(!he){ | ||
396 | le.m_Status.LoadString(IDS_PS_FAILEDTORESOLVE); | ||
397 | goto goBye; | ||
398 | } | ||
399 | memmove(&ip.s_addr,he->h_addr,sizeof(ip.s_addr)); | ||
400 | } | ||
401 | pICMP = CICMP::CreateICMP(); | ||
402 | if(!(pICMP && pICMP->Initialize())) { | ||
403 | le.m_Status.LoadString(IDS_PS_UNABLETOICMP); | ||
404 | goto goBye; | ||
405 | } | ||
406 | INT status; | ||
407 | LONG rtt; | ||
408 | rtt=pICMP->Ping(ip,dataSize,m_TimeOut,&status); | ||
409 | switch(status){ | ||
410 | case CICMP::ipSuccess: | ||
411 | le.m_bReached=TRUE; | ||
412 | le.m_RTT=rtt; | ||
413 | le.m_Status.Empty(); | ||
414 | break; | ||
415 | case CICMP::ipBuffTooSmall: | ||
416 | le.m_Status.LoadString(IDS_PS_INTERNALERROR); | ||
417 | break; | ||
418 | case CICMP::ipDestNetUnreachable: | ||
419 | le.m_Status.LoadString(IDS_PS_NETUNREACHABLE); | ||
420 | break; | ||
421 | case CICMP::ipDestHostUnreachable: | ||
422 | le.m_Status.LoadString(IDS_PS_HOSTUNREACHABLE); | ||
423 | break; | ||
424 | case CICMP::ipDestProtUnreachable: | ||
425 | le.m_Status.LoadString(IDS_PS_PROTUNREACHABLE); | ||
426 | break; | ||
427 | case CICMP::ipDestPortUnreachable: | ||
428 | le.m_Status.LoadString(IDS_PS_PORTUNREACHABLE); | ||
429 | case CICMP::ipNoResources: | ||
430 | le.m_Status.LoadString(IDS_PS_NORESOURCES); | ||
431 | break; | ||
432 | case CICMP::ipBadOption: | ||
433 | le.m_Status.LoadString(IDS_PS_INTERNALERROR); | ||
434 | break; | ||
435 | case CICMP::ipHWError: | ||
436 | le.m_Status.LoadString(IDS_PS_HWERROR); | ||
437 | break; | ||
438 | case CICMP::ipPacketTooBig: | ||
439 | le.m_Status.LoadString(IDS_PS_BIGPACKET); | ||
440 | break; | ||
441 | case CICMP::ipTimeOut: | ||
442 | le.m_Status.LoadString(IDS_PS_TIMEOUT); | ||
443 | break; | ||
444 | case CICMP::ipBadRequest: | ||
445 | le.m_Status.LoadString(IDS_PS_INTERNALERROR); | ||
446 | break; | ||
447 | case CICMP::ipBadRoute: | ||
448 | le.m_Status.LoadString(IDS_PS_BADROUTE); | ||
449 | break; | ||
450 | case CICMP::ipTTLExpiredInTransit: | ||
451 | le.m_Status.LoadString(IDS_PS_TTLEXPTRANSIT); | ||
452 | break; | ||
453 | case CICMP::ipTTLExpiredInReasm: | ||
454 | le.m_Status.LoadString(IDS_PS_TTLEXPREASM); | ||
455 | break; | ||
456 | case CICMP::ipParamProblem: | ||
457 | le.m_Status.LoadString(IDS_PS_IPARAMP); | ||
458 | break; | ||
459 | case CICMP::ipSourceQuench: | ||
460 | le.m_Status.LoadString(IDS_PS_SOURCEQUENCH); | ||
461 | break; | ||
462 | case CICMP::ipOptionTooBig: | ||
463 | le.m_Status.LoadString(IDS_PS_BIGOPTION); | ||
464 | break; | ||
465 | case CICMP::ipBadDest: | ||
466 | le.m_Status.LoadString(IDS_PS_BADDEST); | ||
467 | break; | ||
468 | default: | ||
469 | le.m_Status.Format(IDS_PS_UNKNOWNERROR,status); | ||
470 | break; | ||
471 | } | ||
472 | goBye: | ||
473 | if(pICMP) { | ||
474 | pICMP->Deinitialize(); | ||
475 | delete pICMP; | ||
476 | } | ||
477 | if(le.m_bReached) | ||
478 | m_bIsUp=TRUE; | ||
479 | else{ | ||
480 | if(m_bIsUp) | ||
481 | m_HowDown=0; | ||
482 | m_bIsUp=FALSE; | ||
483 | m_HowDown++; | ||
484 | } | ||
485 | |||
486 | le.m_Time=CTime::GetCurrentTime(); | ||
487 | |||
488 | CLogEntry *newLE = NULL; | ||
489 | if(!m_Log.IsEmpty()){ | ||
490 | CLogEntry *head = m_Log.GetHead(); | ||
491 | while(head && (m_bToKill?FALSE:(m_Doc->m_MaxLogTime<(le.m_Time-head->m_Time)))){ | ||
492 | m_Log.RemoveHead(); | ||
493 | if(newLE) | ||
494 | delete head; | ||
495 | else | ||
496 | newLE=head; | ||
497 | if(m_Log.IsEmpty()) | ||
498 | head=NULL; | ||
499 | else | ||
500 | head = m_Log.GetHead(); | ||
501 | } | ||
502 | } | ||
503 | if(newLE) | ||
504 | (*newLE)=le; | ||
505 | else | ||
506 | newLE=new CLogEntry(le); | ||
507 | m_Log.AddTail(newLE); | ||
508 | |||
509 | if(m_bToKill) | ||
510 | delete this; | ||
511 | else{ | ||
512 | m_bPinged=TRUE; | ||
513 | m_Pinged = CTime::GetCurrentTime(); | ||
514 | if(m_Doc) | ||
515 | m_Doc->m_BBView->SendMessage(WM_ACTIVITYCOUNT,(WPARAM)-1,0); | ||
516 | if(m_Doc) | ||
517 | m_Doc->SetModifiedFlag(); | ||
518 | if(m_Doc) | ||
519 | m_Doc->m_BBView->SendMessage(WM_UPDATETREEBROTHER,TRUE,(LPARAM)this); | ||
520 | } | ||
521 | return 0; | ||
522 | } | ||
523 | |||
524 | CLogEntry::CLogEntry() | ||
525 | { | ||
526 | flags=0; | ||
527 | m_bReached=FALSE; | ||
528 | m_Status.Empty(); | ||
529 | m_Time=CTime::GetCurrentTime(); | ||
530 | } | ||
531 | |||
532 | CBrother::~CBrother() | ||
533 | { | ||
534 | POSITION p = m_Log.GetHeadPosition(); | ||
535 | while(p){ | ||
536 | CLogEntry *le = m_Log.GetNext(p); | ||
537 | delete le; | ||
538 | } | ||
539 | m_Log.RemoveAll(); | ||
540 | } | ||
541 | |||
542 | void CBigBrotherDoc::CleanUp() | ||
543 | { | ||
544 | if(m_BBView && m_BBView->m_Pages){ | ||
545 | m_BBView->m_Pages->SetBrother(NULL); | ||
546 | } | ||
547 | if(m_RootBrother){ | ||
548 | while(!m_Brotherhood.IsEmpty()){ | ||
549 | CBrother *b = m_Brotherhood.GetHead(); | ||
550 | ASSERT(b); | ||
551 | b->m_Doc=this; | ||
552 | b->Suicide(); | ||
553 | } | ||
554 | m_RootBrother->m_Doc=this; | ||
555 | m_RootBrother->Suicide(); | ||
556 | m_RootBrother=NULL; | ||
557 | } | ||
558 | m_MaxLogTime = CTimeSpan(0,1,0,0); | ||
559 | m_MaxThreads = 5; | ||
560 | m_PingSize = 32; | ||
561 | m_bSaveOnShutdown = TRUE; | ||
562 | m_AutoSave = CTimeSpan(0,0,30,0); | ||
563 | m_AutoSaved = CTime::GetCurrentTime(); | ||
564 | flags=0; | ||
565 | } | ||
566 | |||
567 | CBrother* CBigBrotherDoc::GetCurrentBrother() | ||
568 | { | ||
569 | if(m_BBView); | ||
570 | return m_BBView->GetCurrentBrother(); | ||
571 | return NULL; | ||
572 | } | ||
573 | |||
574 | BOOL CBrother::IsValuable() | ||
575 | { | ||
576 | return !m_Host.IsEmpty(); | ||
577 | } | ||
578 | |||
579 | void CBigBrotherDoc::GetFamily(CBrother *b,CBrotherList *bh) | ||
580 | { | ||
581 | ASSERT(b); | ||
582 | ASSERT(bh); | ||
583 | ASSERT(m_BBView); | ||
584 | m_BBView->GetFamily(b,bh); | ||
585 | } | ||
586 | |||
587 | void CBigBrotherDoc::OnUpdateBrothersAddbrother(CCmdUI* pCmdUI) | ||
588 | { | ||
589 | ASSERT(m_BBView); | ||
590 | CBrother *bro = m_BBView->GetCurrentBrother(); | ||
591 | if(bro) | ||
592 | pCmdUI->Enable(bro->m_Daddy!=NULL); | ||
593 | else | ||
594 | pCmdUI->Enable(FALSE); | ||
595 | } | ||
596 | |||
597 | void CBigBrotherDoc::OnBrothersAddbrother() | ||
598 | { | ||
599 | ASSERT(m_BBView); | ||
600 | CBrother *bro = m_BBView->GetCurrentBrother(); | ||
601 | ASSERT(bro); | ||
602 | bro = bro->m_Daddy; | ||
603 | ASSERT(bro); | ||
604 | CBrother *lb = new CBrother(bro); | ||
605 | m_Brotherhood.AddTail(lb); | ||
606 | SetModifiedFlag(); | ||
607 | m_BBView->AddBrother(lb); | ||
608 | m_BBView->GotoBrother(lb); | ||
609 | } | ||
610 | |||
611 | BOOL CAction::PlayASound(LPCTSTR sound) | ||
612 | { | ||
613 | CString str; | ||
614 | str.LoadString(IDS_ACTION_HOST_UP); | ||
615 | if(!str.CompareNoCase(sound)) | ||
616 | return ::PlaySound((LPCTSTR)IDW_HOST_UP,AfxGetApp()->m_hInstance,SND_ASYNC|SND_NODEFAULT|SND_NOSTOP|SND_NOWAIT|SND_RESOURCE); | ||
617 | str.LoadString(IDS_ACTION_HOST_DOWN); | ||
618 | if(!str.CompareNoCase(sound)) | ||
619 | return ::PlaySound((LPCTSTR)IDW_HOST_DOWN,AfxGetApp()->m_hInstance,SND_ASYNC|SND_NODEFAULT|SND_NOSTOP|SND_NOWAIT|SND_RESOURCE); | ||
620 | str.LoadString(IDS_ACTION_SYSTEM_OK); | ||
621 | if(!str.CompareNoCase(sound)) | ||
622 | return MessageBeep(MB_ICONASTERISK); | ||
623 | str.LoadString(IDS_ACTION_SYSTEM_CRITICAL); | ||
624 | if(!str.CompareNoCase(sound)) | ||
625 | return MessageBeep(MB_ICONHAND); | ||
626 | return ::PlaySound(sound,AfxGetApp()->m_hInstance,SND_ASYNC|SND_NODEFAULT|SND_NOSTOP|SND_NOWAIT|SND_FILENAME); | ||
627 | } | ||
628 | |||
629 | CLogEntry& CLogEntry::operator=(CLogEntry& src) | ||
630 | { | ||
631 | m_bReached=src.m_bReached; | ||
632 | m_RTT=src.m_RTT; | ||
633 | m_Status=src.m_Status; | ||
634 | m_Time=src.m_Time; | ||
635 | flags=src.flags; | ||
636 | return *this; | ||
637 | } | ||
638 | |||
639 | CLogEntry::CLogEntry(CLogEntry& src) | ||
640 | { | ||
641 | (*this)=src; | ||
642 | } | ||
643 | |||
644 | void CAction::PerformAction(CBrother *b) | ||
645 | { | ||
646 | if(flags&flagsPlayASound) | ||
647 | PlayASound(m_Sound); | ||
648 | if(flags&flagsRunCustom){ | ||
649 | CString cmd = FormatLine(m_Custom,b); | ||
650 | system(cmd); | ||
651 | } | ||
652 | } | ||
653 | |||
654 | void CBrother::Serialize(CArchive& ar) | ||
655 | { | ||
656 | ASSERT_VALID(this); | ||
657 | |||
658 | CObject::Serialize(ar); | ||
659 | |||
660 | CBigBrotherDoc *pDoc = (CBigBrotherDoc*)ar.m_pDocument; | ||
661 | ASSERT(pDoc); | ||
662 | ASSERT(pDoc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc))); | ||
663 | |||
664 | if (ar.IsStoring()) | ||
665 | { | ||
666 | if(pDoc->m_BBView && (pDoc->m_BBView->GetTreeCtrl().GetItemState(m_Item,TVIS_EXPANDED)&TVIS_EXPANDED)) | ||
667 | flags|=flagsExpandedTree; | ||
668 | else | ||
669 | flags&=~flagsExpandedTree; | ||
670 | if(pDoc->GetCurrentBrother()==this) | ||
671 | flags|=flagsCurrentBrother; | ||
672 | else | ||
673 | flags&=~flagsCurrentBrother; | ||
674 | // Store to archive | ||
675 | ar << (DWORD)this; | ||
676 | ar << (DWORD)m_Daddy; | ||
677 | ar << flags; | ||
678 | ar << m_bLog; | ||
679 | ar << m_Host; | ||
680 | ar << m_Desc; | ||
681 | ar << m_IntervalGood; | ||
682 | ar << m_IntervalBad; | ||
683 | ar << m_TimeOut; | ||
684 | ar << m_Retries; | ||
685 | ar << &m_Up; | ||
686 | ar << &m_Down; | ||
687 | if(pDoc->m_bStoreLastActivity) | ||
688 | m_Log.Serialize(ar); | ||
689 | else{ | ||
690 | CLogList tmp; | ||
691 | tmp.Serialize(ar); | ||
692 | } | ||
693 | }else{ | ||
694 | #ifndefNDEBUG | ||
695 | { | ||
696 | CString tmp; | ||
697 | tmp.Format("Bro-OSchema: %u\n",ar.GetObjectSchema()); | ||
698 | TRACE0(tmp); | ||
699 | } | ||
700 | #endif | ||
701 | // Read from archive | ||
702 | DWORD dw; | ||
703 | ar >> dw; | ||
704 | pDoc->m_ThisMap[dw]=this; | ||
705 | ar >> dw; | ||
706 | if(dw){ | ||
707 | VERIFY(pDoc->m_ThisMap.Lookup(dw,m_Daddy)); | ||
708 | }else | ||
709 | m_Daddy=NULL; | ||
710 | ar >> flags; | ||
711 | ar >> m_bLog; | ||
712 | ar >> m_Host; | ||
713 | ar >> m_Desc; | ||
714 | ar >> m_IntervalGood; | ||
715 | ar >> m_IntervalBad; | ||
716 | ar >> m_TimeOut; | ||
717 | ar >> m_Retries; | ||
718 | CAction *act = NULL; | ||
719 | ar >> act; | ||
720 | m_Up = *act; | ||
721 | delete act; | ||
722 | act = NULL; | ||
723 | ar >> act; | ||
724 | m_Down = *act; | ||
725 | delete act; | ||
726 | m_Log.Serialize(ar); | ||
727 | ParentalAdjust(); | ||
728 | } | ||
729 | } | ||
730 | |||
731 | void CAction::Serialize(CArchive& ar) | ||
732 | { | ||
733 | ASSERT_VALID(this); | ||
734 | |||
735 | CObject::Serialize(ar); | ||
736 | |||
737 | if (ar.IsStoring()) | ||
738 | { | ||
739 | // Store to archive | ||
740 | ar << flags; | ||
741 | ar << m_Sound; | ||
742 | ar << m_Custom; | ||
743 | }else{ | ||
744 | #ifndefNDEBUG | ||
745 | { | ||
746 | CString tmp; | ||
747 | tmp.Format("Act-OSchema: %u\n",ar.GetObjectSchema()); | ||
748 | TRACE0(tmp); | ||
749 | } | ||
750 | #endif | ||
751 | // Read from archive | ||
752 | ar >> flags; | ||
753 | ar >> m_Sound; | ||
754 | ar >> m_Custom; | ||
755 | } | ||
756 | } | ||
757 | |||
758 | void CLogEntry::Serialize(CArchive& ar) | ||
759 | { | ||
760 | ASSERT_VALID(this); | ||
761 | |||
762 | CObject::Serialize(ar); | ||
763 | |||
764 | if (ar.IsStoring()) | ||
765 | { | ||
766 | // Store to archive | ||
767 | ar << flags; | ||
768 | ar << m_Time; | ||
769 | ar << m_bReached; | ||
770 | ar << m_RTT; | ||
771 | ar << m_Status; | ||
772 | }else{ | ||
773 | UINT schema = ar.GetObjectSchema(); | ||
774 | /* | ||
775 | #ifndefNDEBUG | ||
776 | { | ||
777 | CString tmp; | ||
778 | tmp.Format("Log-OSchema: %u\n",schema); | ||
779 | TRACE0(tmp); | ||
780 | } | ||
781 | #endif | ||
782 | */ | ||
783 | // Read from archive | ||
784 | if(schema>=2){ | ||
785 | ar >> flags; | ||
786 | } | ||
787 | ar >> m_Time; | ||
788 | ar >> m_bReached; | ||
789 | ar >> m_RTT; | ||
790 | ar >> m_Status; | ||
791 | } | ||
792 | } | ||
793 | |||
794 | CBrother::CBrother() | ||
795 | { | ||
796 | CleanUp(); | ||
797 | ParentalAdjust(TRUE); | ||
798 | } | ||
799 | |||
800 | void CBigBrotherDoc::OnUpdateBrothersDelete(CCmdUI* pCmdUI) | ||
801 | { | ||
802 | pCmdUI->Enable(GetCurrentBrother()!=NULL); | ||
803 | } | ||
804 | |||
805 | void CBigBrotherDoc::OnBrothersDelete() | ||
806 | { | ||
807 | ASSERT(m_BBView); | ||
808 | CBrother *b = GetCurrentBrother(); | ||
809 | ASSERT(b); | ||
810 | m_BBView->KillBrother(b); | ||
811 | SetModifiedFlag(); | ||
812 | } | ||
813 | |||
814 | void CBrother::Suicide() | ||
815 | { | ||
816 | ASSERT(m_Doc); | ||
817 | ASSERT(m_Doc->IsKindOf(RUNTIME_CLASS(CBigBrotherDoc))); | ||
818 | CBigBrotherDoc *pDoc = (CBigBrotherDoc*)m_Doc; | ||
819 | if(pDoc->m_BBView && pDoc->m_BBView->m_Pages->m_Brother==this) | ||
820 | pDoc->m_BBView->m_Pages->m_Brother=NULL; | ||
821 | POSITION p = pDoc->m_Brotherhood.Find(this); | ||
822 | if(p) | ||
823 | pDoc->m_Brotherhood.RemoveAt(p); | ||
824 | #ifndefNDEBUG | ||
825 | else{ | ||
826 | ASSERT(!m_Daddy); | ||
827 | } | ||
828 | #endif | ||
829 | m_Item=NULL; | ||
830 | if(m_bPinging){ | ||
831 | m_bToKill=TRUE; | ||
832 | m_Daddy=NULL; | ||
833 | m_Doc=NULL; | ||
834 | }else | ||
835 | delete this; | ||
836 | } | ||
837 | |||
838 | BOOL CBrother::operator==(CBrother& b) | ||
839 | { | ||
840 | if(flags!=b.flags) | ||
841 | return FALSE; | ||
842 | if(m_bLog!=b.m_bLog) | ||
843 | return FALSE; | ||
844 | if(m_Desc.Compare(b.m_Desc)) | ||
845 | return FALSE; | ||
846 | if(m_Down!=b.m_Down) | ||
847 | return FALSE; | ||
848 | if(m_Host.Compare(b.m_Host)) | ||
849 | return FALSE; | ||
850 | if(m_IntervalGood!=b.m_IntervalGood || m_IntervalBad!=b.m_IntervalBad) | ||
851 | return FALSE; | ||
852 | if(m_Retries!=b.m_Retries) | ||
853 | return FALSE; | ||
854 | if(m_TimeOut!=b.m_TimeOut) | ||
855 | return FALSE; | ||
856 | if(m_Up!=b.m_Up) | ||
857 | return FALSE; | ||
858 | return TRUE; | ||
859 | } | ||
860 | |||
861 | BOOL CBrother::operator!=(CBrother& b) | ||
862 | { | ||
863 | return !((*this)==b); | ||
864 | } | ||
865 | |||
866 | BOOL CAction::operator==(CAction& a) | ||
867 | { | ||
868 | if(flags!=a.flags) | ||
869 | return FALSE; | ||
870 | if(m_Custom.Compare(a.m_Custom)) | ||
871 | return FALSE; | ||
872 | if(m_Sound.Compare(a.m_Sound)) | ||
873 | return FALSE; | ||
874 | return TRUE; | ||
875 | } | ||
876 | |||
877 | BOOL CAction::operator!=(CAction& a) | ||
878 | { | ||
879 | return !((*this)==a); | ||
880 | } | ||
881 | |||
882 | CBrother& CBrother::operator=(CBrother& b) | ||
883 | { | ||
884 | flags=b.flags; | ||
885 | m_bLog=b.m_bLog; | ||
886 | m_Desc=b.m_Desc; | ||
887 | m_Down=b.m_Down; | ||
888 | m_Host=b.m_Host; | ||
889 | m_IntervalGood=b.m_IntervalGood; | ||
890 | m_IntervalBad=b.m_IntervalBad; | ||
891 | m_Retries=b.m_Retries; | ||
892 | m_TimeOut=b.m_TimeOut; | ||
893 | m_Up=b.m_Up; | ||
894 | return *this; | ||
895 | } | ||
896 | |||
897 | BOOL CBigBrotherDoc::SaveModified() | ||
898 | { | ||
899 | if(((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_bShuttingDown && m_bSaveOnShutdown){ | ||
900 | DoFileSave(); | ||
901 | ((CMainFrame*)(AfxGetApp()->m_pMainWnd))->m_bShuttingDown = FALSE; | ||
902 | return TRUE; | ||
903 | } | ||
904 | return CDocument::SaveModified(); | ||
905 | } | ||
906 | |||
907 | void CBrother::AppendSeparator() | ||
908 | { | ||
909 | CLogEntry *le = new CLogEntry(); | ||
910 | le->flags=CLogEntry::flagsSeparator; | ||
911 | m_Log.AddTail(le); | ||
912 | } | ||
913 | |||
914 | void CBigBrotherDoc::OnFilePreferences() | ||
915 | { | ||
916 | CPreferences prefs(AfxGetApp()->m_pMainWnd); | ||
917 | prefs.m_AutosaveMinutes=m_AutoSave.GetTotalMinutes(); | ||
918 | prefs.m_LogFile=m_LogFile; | ||
919 | prefs.m_MaxThreads=m_MaxThreads; | ||
920 | prefs.m_PingSize=m_PingSize; | ||
921 | prefs.m_SaveOnShutdown=m_bSaveOnShutdown; | ||
922 | prefs.m_LogMins=m_MaxLogTime.GetTotalMinutes(); | ||
923 | prefs.m_bStoreLastActivity=m_bStoreLastActivity; | ||
924 | if(prefs.DoModal()==IDOK){ | ||
925 | m_AutoSave = CTimeSpan(0,prefs.m_AutosaveMinutes/60,prefs.m_AutosaveMinutes%60,0); | ||
926 | m_LogFile=prefs.m_LogFile; | ||
927 | m_MaxThreads=prefs.m_MaxThreads; | ||
928 | m_PingSize=prefs.m_PingSize; | ||
929 | m_bSaveOnShutdown=prefs.m_SaveOnShutdown; | ||
930 | m_MaxLogTime = CTimeSpan(0,prefs.m_LogMins/60,prefs.m_LogMins%60,0); | ||
931 | m_bStoreLastActivity=prefs.m_bStoreLastActivity; | ||
932 | } | ||
933 | } | ||
934 | |||
935 | void CBigBrotherDoc::LogLine(LPCTSTR str) | ||
936 | { | ||
937 | if(!m_LogFile.IsEmpty()){ | ||
938 | TRY{ | ||
939 | CFile file(m_LogFile,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite|CFile::shareDenyWrite|CFile::typeBinary); | ||
940 | file.SeekToEnd(); | ||
941 | file.Write(str,strlen(str)); | ||
942 | file.Write("\r\n",2); | ||
943 | file.Close(); | ||
944 | }CATCH(CFileException, e){ | ||
945 | #ifndefNDEBUG | ||
946 | afxDump << "Logging error: " << e->m_cause << "\n"; | ||
947 | #endif | ||
948 | }END_CATCH | ||
949 | } | ||
950 | } | ||
951 | |||
952 | CString CAction::FormatLine(LPCTSTR fmt,CBrother *b) | ||
953 | { | ||
954 | ASSERT(b); | ||
955 | CString str = fmt; | ||
956 | CString rv; | ||
957 | while(!str.IsEmpty()){ | ||
958 | int pe = str.Find('%'); | ||
959 | if(pe<0){ | ||
960 | rv+=str; | ||
961 | str.Empty(); | ||
962 | }else{ | ||
963 | rv+=str.Left(pe); | ||
964 | str = str.Mid(pe+1); | ||
965 | if(!str.IsEmpty()){ | ||
966 | switch(str[0]){ | ||
967 | case'%': | ||
968 | rv+="%"; | ||
969 | break; | ||
970 | case'h': | ||
971 | case'H': | ||
972 | rv+=b->m_Host; | ||
973 | break; | ||
974 | case'd': | ||
975 | case'D': | ||
976 | rv+=b->m_Desc; | ||
977 | break; | ||
978 | } | ||
979 | str=str.Mid(1); | ||
980 | }else{ | ||
981 | rv+="%"+str; | ||
982 | str.Empty(); | ||
983 | } | ||
984 | } | ||
985 | } | ||
986 | return rv; | ||
987 | } | ||
988 | |||
989 | void CBigBrotherDoc::OnUpdateFilePause(CCmdUI* pCmdUI) | ||
990 | { | ||
991 | pCmdUI->SetCheck((flags&flagsSuspended)?1:0); | ||
992 | } | ||
993 | |||
994 | void CBigBrotherDoc::OnFilePause() | ||
995 | { | ||
996 | flags^=flagsSuspended; | ||
997 | if(!(flags&flagsSuspended)){ | ||
998 | ASSERT(m_RootBrother); | ||
999 | m_RootBrother->AppendSeparator(); | ||
1000 | POSITION p = m_Brotherhood.GetHeadPosition(); | ||
1001 | while(p){ | ||
1002 | CBrother *b = m_Brotherhood.GetNext(p); | ||
1003 | ASSERT(b); | ||
1004 | b->AppendSeparator(); | ||
1005 | } | ||
1006 | CheckPendingQueue(); | ||
1007 | }else{ | ||
1008 | ASSERT(m_BBView); | ||
1009 | m_BBView->KillTimer(TM_CHECK); | ||
1010 | } | ||
1011 | } | ||
1012 | |||
1013 | void CBigBrotherDoc::DeleteContents() | ||
1014 | { | ||
1015 | CleanUp(); | ||
1016 | CDocument::DeleteContents(); | ||
1017 | } | ||
1018 | |||
1019 | void CBigBrotherDoc::OnCloseDocument() | ||
1020 | { | ||
1021 | CleanUp(); | ||
1022 | CDocument::OnCloseDocument(); | ||
1023 | } | ||
1024 | |||
1025 | void CBigBrotherDoc::OnUpdateViewHostproperties(CCmdUI* pCmdUI) | ||
1026 | { | ||
1027 | pCmdUI->SetCheck((flags&flagsShowProps)?1:0); | ||
1028 | } | ||
1029 | |||
1030 | void CBigBrotherDoc::OnViewHostproperties() | ||
1031 | { | ||
1032 | ASSERT(m_BBView); | ||
1033 | ASSERT(m_BBView->m_Pages); | ||
1034 | flags^=flagsShowProps; | ||
1035 | if(flags&flagsShowProps) | ||
1036 | m_BBView->m_Pages->ShowWindow(SW_SHOW); | ||
1037 | else | ||
1038 | m_BBView->m_Pages->ShowWindow(SW_HIDE); | ||
1039 | } | ||