TCP: Fixed RTO update and dup ACKs generation.
[haiku.git] / src / apps / poorman / PoorManWindow.cpp
blob1d15415b1702142110ed9715f2240fac13119bc1
1 /* PoorManWindow.cpp
3 * Philip Harrison
4 * Started: 4/25/2004
5 * Version: 0.1
6 */
8 #include "PoorManWindow.h"
10 #include <string.h>
11 #include <time.h>
12 #include <arpa/inet.h>
14 #include <Alert.h>
15 #include <Box.h>
16 #include <Catalog.h>
17 #include <DateTimeFormat.h>
18 #include <Directory.h>
19 #include <File.h>
20 #include <FindDirectory.h>
21 #include <LayoutBuilder.h>
22 #include <Locale.h>
23 #include <Menu.h>
24 #include <MenuBar.h>
25 #include <MenuItem.h>
26 #include <OS.h>
27 #include <Path.h>
28 #include <ScrollBar.h>
29 #include <ScrollView.h>
30 #include <StringView.h>
31 #include <TypeConstants.h>
33 #include "PoorManApplication.h"
34 #include "PoorManPreferencesWindow.h"
35 #include "PoorManView.h"
36 #include "PoorManServer.h"
37 #include "PoorManLogger.h"
38 #include "constants.h"
41 #undef B_TRANSLATION_CONTEXT
42 #define B_TRANSLATION_CONTEXT "PoorMan"
43 #define DATE_FORMAT B_SHORT_DATE_FORMAT
44 #define TIME_FORMAT B_MEDIUM_TIME_FORMAT
47 PoorManWindow::PoorManWindow(BRect frame)
49 BWindow(frame, STR_APP_NAME, B_TITLED_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS),
50 fStatus(false),
51 fHits(0),
52 fPrefWindow(NULL),
53 fLogFile(NULL),
54 fServer(NULL)
56 //preferences init
57 fWebDirectory.SetTo(STR_DEFAULT_WEB_DIRECTORY);
58 fIndexFileName.SetTo("index.html");
59 fDirListFlag = false;
61 fLogConsoleFlag = true;
62 fLogFileFlag = false;
63 fLogPath.SetTo("");
65 fMaxConnections = (int16)32;
67 fIsZoomed = true;
68 fLastWidth = 318.0f;
69 fLastHeight = 320.0f;
70 this->fFrame = frame;
71 fSetwindowFrame.Set(112.0f, 60.0f, 492.0f, 340.0f);
73 // PoorMan Window
74 SetSizeLimits(318, 1600, 53, 1200);
75 // limit the size of the size of the window
77 // -----------------------------------------------------------------
78 // Three Labels
80 // Status String
81 fStatusView = new BStringView("Status View", B_TRANSLATE("Status: Stopped"));
83 // Directory String
84 fDirView = new BStringView("Dir View", B_TRANSLATE("Directory: (none)"));
86 // Hits String
87 fHitsView = new BStringView("Hit View", B_TRANSLATE("Hits: 0"));
89 // -----------------------------------------------------------------
90 // Logging View
92 fLoggingView = new BTextView(STR_TXT_VIEW, B_WILL_DRAW );
94 fLoggingView->MakeEditable(false); // user cannot change the text
95 fLoggingView->MakeSelectable(true);
96 fLoggingView->SetViewColor(WHITE);
97 fLoggingView->SetStylable(true);
99 // create the scroll view
100 fScrollView = new BScrollView("Scroll View", fLoggingView,
101 B_WILL_DRAW | B_FRAME_EVENTS,
102 // Make sure articles on border do not occur when resizing
103 false, true);
104 fLoggingView->MakeFocus(true);
107 // -----------------------------------------------------------------
108 // menu bar
109 fFileMenuBar = new BMenuBar("File Menu Bar");
111 // menus
112 fFileMenu = BuildFileMenu();
113 if (fFileMenu)
114 fFileMenuBar->AddItem(fFileMenu);
116 fEditMenu = BuildEditMenu();
117 if (fEditMenu)
118 fFileMenuBar->AddItem(fEditMenu);
120 fControlsMenu = BuildControlsMenu();
121 if (fControlsMenu)
122 fFileMenuBar->AddItem(fControlsMenu);
124 // File Panels
125 BWindow* change_title;
127 fSaveConsoleFilePanel = new BFilePanel(B_SAVE_PANEL, new BMessenger(this),
128 NULL, B_FILE_NODE, false,
129 new BMessage(MSG_FILE_PANEL_SAVE_CONSOLE));
130 change_title = fSaveConsoleFilePanel->Window();
131 change_title->SetTitle(STR_FILEPANEL_SAVE_CONSOLE);
133 fSaveConsoleSelectionFilePanel = new BFilePanel(B_SAVE_PANEL,
134 new BMessenger(this), NULL, B_FILE_NODE, false,
135 new BMessage(MSG_FILE_PANEL_SAVE_CONSOLE_SELECTION));
136 change_title = fSaveConsoleSelectionFilePanel->Window();
137 change_title->SetTitle(STR_FILEPANEL_SAVE_CONSOLE_SELECTION);
139 BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
140 .SetInsets(0)
141 .Add(fFileMenuBar)
142 .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
143 .SetInsets(B_USE_WINDOW_INSETS)
144 .AddGroup(B_HORIZONTAL)
145 .Add(fStatusView)
146 .AddGlue()
147 .Add(fHitsView)
148 .End()
149 .AddGroup(B_HORIZONTAL)
150 .Add(fDirView)
151 .AddGlue()
152 .End()
153 .Add(fScrollView);
155 pthread_rwlock_init(&fLogFileLock, NULL);
159 PoorManWindow::~PoorManWindow()
161 delete fServer;
162 delete fLogFile;
163 pthread_rwlock_destroy(&fLogFileLock);
167 void
168 PoorManWindow::MessageReceived(BMessage* message)
170 switch (message->what) {
171 case MSG_MENU_FILE_SAVE_AS:
172 fSaveConsoleFilePanel->Show();
173 break;
174 case MSG_FILE_PANEL_SAVE_CONSOLE:
175 printf("FilePanel: Save console\n");
176 SaveConsole(message, false);
177 break;
178 case MSG_MENU_FILE_SAVE_SELECTION:
179 fSaveConsoleSelectionFilePanel->Show();
180 break;
181 case MSG_FILE_PANEL_SAVE_CONSOLE_SELECTION:
182 printf("FilePanel: Save console selection\n");
183 SaveConsole(message, true);
184 break;
185 case MSG_FILE_PANEL_SELECT_WEB_DIR:
186 fPrefWindow->MessageReceived(message);
187 break;
188 case MSG_MENU_EDIT_PREF:
189 fPrefWindow = new PoorManPreferencesWindow(fSetwindowFrame,
190 STR_WIN_NAME_PREF);
191 fPrefWindow->Show();
192 break;
193 case MSG_MENU_CTRL_RUN:
194 if (fStatus)
195 StopServer();
196 else
197 StartServer();
198 break;
199 case MSG_MENU_CTRL_CLEAR_HIT:
200 SetHits(0);
201 //UpdateHitsLabel();
202 break;
203 case MSG_MENU_CTRL_CLEAR_CONSOLE:
204 fLoggingView->SelectAll();
205 fLoggingView->Delete();
206 break;
207 case MSG_MENU_CTRL_CLEAR_LOG:
208 FILE* f;
209 f = fopen(fLogPath.String(), "w");
210 fclose(f);
211 break;
212 case MSG_LOG: {
213 if (!fLogConsoleFlag && !fLogFileFlag)
214 break;
216 time_t time;
217 in_addr_t address;
218 rgb_color color;
219 const void* pointer;
220 ssize_t size;
221 const char* msg;
222 BString line;
224 if (message->FindString("cstring", &msg) != B_OK)
225 break;
226 if (message->FindData("time_t", B_TIME_TYPE, &pointer, &size) != B_OK)
227 time = -1;
228 else
229 time = *static_cast<const time_t*>(pointer);
231 if (message->FindData("in_addr_t", B_ANY_TYPE, &pointer, &size) != B_OK)
232 address = INADDR_NONE;
233 else
234 address = *static_cast<const in_addr_t*>(pointer);
236 if (message->FindData("rgb_color", B_RGB_COLOR_TYPE, &pointer, &size) != B_OK)
237 color = BLACK;
238 else
239 color = *static_cast<const rgb_color*>(pointer);
241 if (time != -1) {
242 BString timeString;
243 if (BDateTimeFormat().Format(timeString, time, DATE_FORMAT,
244 TIME_FORMAT) == B_OK) {
245 line << '[' << timeString << "]: ";
249 if (address != INADDR_NONE) {
250 char addr[INET_ADDRSTRLEN];
251 struct in_addr sin_addr;
252 sin_addr.s_addr = address;
253 if (inet_ntop(AF_INET, &sin_addr, addr, sizeof(addr)) != NULL) {
254 addr[strlen(addr)] = '\0';
255 line << '(' << addr << ") ";
259 line << msg;
261 text_run run;
262 text_run_array runs;
264 run.offset = 0;
265 run.color = color;
267 runs.count = 1;
268 runs.runs[0] = run;
270 if (Lock()) {
271 if (fLogConsoleFlag) {
272 fLoggingView->Insert(fLoggingView->TextLength(),
273 line.String(), line.Length(), &runs);
274 fLoggingView->ScrollToOffset(fLoggingView->TextLength());
277 if (fLogFileFlag) {
278 if (pthread_rwlock_rdlock(&fLogFileLock) == 0) {
279 fLogFile->Write(line.String(), line.Length());
280 pthread_rwlock_unlock(&fLogFileLock);
284 Unlock();
287 break;
289 default:
290 BWindow::MessageReceived(message);
291 break;
296 void
297 PoorManWindow::FrameMoved(BPoint origin)
299 fFrame.left = origin.x;
300 fFrame.top = origin.y;
304 void
305 PoorManWindow::FrameResized(float width, float height)
307 if (fIsZoomed) {
308 fLastWidth = width;
309 fLastHeight = height;
314 bool
315 PoorManWindow::QuitRequested()
317 if (fStatus) {
318 time_t now = time(NULL);
319 BString timeString;
320 BDateTimeFormat().Format(timeString, now, DATE_FORMAT, TIME_FORMAT);
322 BString line;
323 line << "[" << timeString << "]: " << B_TRANSLATE("Shutting down.")
324 << "\n";
326 if (fLogConsoleFlag) {
327 fLoggingView->Insert(fLoggingView->TextLength(),
328 line, line.Length());
329 fLoggingView->ScrollToOffset(fLoggingView->TextLength());
332 if (fLogFileFlag) {
333 if (pthread_rwlock_rdlock(&fLogFileLock) == 0) {
334 fLogFile->Write(line, line.Length());
335 pthread_rwlock_unlock(&fLogFileLock);
339 fServer->Stop();
340 fStatus = false;
341 UpdateStatusLabelAndMenuItem();
344 SaveSettings();
345 be_app_messenger.SendMessage(B_QUIT_REQUESTED);
346 return true;
350 void
351 PoorManWindow::Zoom(BPoint origin, float width, float height)
353 if (fIsZoomed) {
354 // Change to the Minimal size
355 fIsZoomed = false;
356 ResizeTo(318, 53);
357 } else {
358 // Change to the Zoomed size
359 fIsZoomed = true;
360 ResizeTo(fLastWidth, fLastHeight);
365 void
366 PoorManWindow::SetHits(uint32 num)
368 fHits = num;
369 UpdateHitsLabel();
373 // Private: Methods ------------------------------------------
376 BMenu*
377 PoorManWindow::BuildFileMenu() const
379 BMenu* ptrFileMenu = new BMenu(STR_MNU_FILE);
381 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_SAVE_AS,
382 new BMessage(MSG_MENU_FILE_SAVE_AS), CMD_FILE_SAVE_AS));
384 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_SAVE_SELECTION,
385 new BMessage(MSG_MENU_FILE_SAVE_SELECTION)));
387 ptrFileMenu->AddSeparatorItem();
389 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_QUIT,
390 new BMessage(B_QUIT_REQUESTED), CMD_FILE_QUIT));
392 return ptrFileMenu;
396 BMenu*
397 PoorManWindow::BuildEditMenu() const
399 BMenu* ptrEditMenu = new BMenu(STR_MNU_EDIT);
401 BMenuItem* CopyMenuItem = new BMenuItem(STR_MNU_EDIT_COPY,
402 new BMessage(B_COPY), CMD_EDIT_COPY);
404 ptrEditMenu->AddItem(CopyMenuItem);
405 CopyMenuItem->SetTarget(fLoggingView, NULL);
407 ptrEditMenu->AddSeparatorItem();
409 BMenuItem* SelectAllMenuItem = new BMenuItem(STR_MNU_EDIT_SELECT_ALL,
410 new BMessage(B_SELECT_ALL), CMD_EDIT_SELECT_ALL);
412 ptrEditMenu->AddItem(SelectAllMenuItem);
413 SelectAllMenuItem->SetTarget(fLoggingView, NULL);
415 ptrEditMenu->AddSeparatorItem();
417 BMenuItem* PrefMenuItem = new BMenuItem(STR_MNU_EDIT_PREF,
418 new BMessage(MSG_MENU_EDIT_PREF));
419 ptrEditMenu->AddItem(PrefMenuItem);
421 return ptrEditMenu;
425 BMenu*
426 PoorManWindow::BuildControlsMenu() const
428 BMenu* ptrControlMenu = new BMenu(STR_MNU_CTRL);
430 BMenuItem* RunServerMenuItem = new BMenuItem(STR_MNU_CTRL_RUN_SERVER,
431 new BMessage(MSG_MENU_CTRL_RUN));
432 RunServerMenuItem->SetMarked(false);
433 ptrControlMenu->AddItem(RunServerMenuItem);
435 BMenuItem* ClearHitCounterMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_HIT_COUNTER,
436 new BMessage(MSG_MENU_CTRL_CLEAR_HIT));
437 ptrControlMenu->AddItem(ClearHitCounterMenuItem);
439 ptrControlMenu->AddSeparatorItem();
441 BMenuItem* ClearConsoleLogMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_CONSOLE,
442 new BMessage(MSG_MENU_CTRL_CLEAR_CONSOLE));
443 ptrControlMenu->AddItem(ClearConsoleLogMenuItem);
445 BMenuItem* ClearLogFileMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_LOG_FILE,
446 new BMessage(MSG_MENU_CTRL_CLEAR_LOG));
447 ptrControlMenu->AddItem(ClearLogFileMenuItem);
449 return ptrControlMenu;
453 void
454 PoorManWindow::SetDirLabel(const char* name)
456 BString dirPath(B_TRANSLATE("Directory: "));
457 dirPath.Append(name);
459 if (Lock()) {
460 fDirView->SetText(dirPath.String());
461 Unlock();
466 void
467 PoorManWindow::UpdateStatusLabelAndMenuItem()
469 if (Lock()) {
470 if (fStatus)
471 fStatusView->SetText(B_TRANSLATE("Status: Running"));
472 else
473 fStatusView->SetText(B_TRANSLATE("Status: Stopped"));
474 fControlsMenu->FindItem(STR_MNU_CTRL_RUN_SERVER)->SetMarked(fStatus);
475 Unlock();
480 void
481 PoorManWindow::UpdateHitsLabel()
483 if (Lock()) {
484 sprintf(fHitsLabel, B_TRANSLATE("Hits: %lu"), GetHits());
485 fHitsView->SetText(fHitsLabel);
487 Unlock();
492 status_t
493 PoorManWindow::SaveConsole(BMessage* message, bool selection)
495 entry_ref ref;
496 const char* name;
497 BPath path;
498 BEntry entry;
499 status_t err = B_OK;
500 FILE* f;
502 err = message->FindRef("directory", &ref);
503 if (err != B_OK)
504 return err;
506 err = message->FindString("name", &name);
507 if (err != B_OK)
508 return err;
510 err = entry.SetTo(&ref);
511 if (err != B_OK)
512 return err;
514 entry.GetPath(&path);
515 path.Append(name);
517 if (!(f = fopen(path.Path(), "w")))
518 return B_ERROR;
520 if (!selection) {
521 // write the data to the file
522 err = fwrite(fLoggingView->Text(), 1, fLoggingView->TextLength(), f);
523 } else {
524 // find the selected text and write it to a file
525 int32 start = 0, end = 0;
526 fLoggingView->GetSelection(&start, &end);
528 BString buffer;
529 char * buffData = buffer.LockBuffer(end - start + 1);
530 // copy the selected text from the TextView to the buffer
531 fLoggingView->GetText(start, end - start, buffData);
532 buffer.UnlockBuffer(end - start + 1);
534 err = fwrite(buffer.String(), 1, end - start + 1, f);
537 fclose(f);
539 return err;
543 void
544 PoorManWindow::DefaultSettings()
546 BAlert* serverAlert = new BAlert(B_TRANSLATE("Error Server"),
547 STR_ERR_CANT_START, B_TRANSLATE("OK"));
548 serverAlert->SetFlags(serverAlert->Flags() | B_CLOSE_ON_ESCAPE);
549 BAlert* dirAlert = new BAlert(B_TRANSLATE("Error Dir"),
550 STR_ERR_WEB_DIR, B_TRANSLATE("Cancel"), B_TRANSLATE("Select"),
551 B_TRANSLATE("Create public_html"), B_WIDTH_AS_USUAL, B_OFFSET_SPACING);
552 dirAlert->SetShortcut(0, B_ESCAPE);
553 int32 buttonIndex = dirAlert->Go();
555 switch (buttonIndex) {
556 case 0:
557 if (Lock())
558 Quit();
559 be_app_messenger.SendMessage(B_QUIT_REQUESTED);
560 break;
562 case 1:
563 fPrefWindow = new PoorManPreferencesWindow(
564 fSetwindowFrame,
565 STR_WIN_NAME_PREF);
566 fPrefWindow->ShowWebDirFilePanel();
567 break;
569 case 2:
570 if (create_directory(STR_DEFAULT_WEB_DIRECTORY, 0755) != B_OK) {
571 serverAlert->Go();
572 if (Lock())
573 Quit();
574 be_app_messenger.SendMessage(B_QUIT_REQUESTED);
575 break;
577 BAlert* dirCreatedAlert =
578 new BAlert(B_TRANSLATE("Dir Created"), STR_DIR_CREATED,
579 B_TRANSLATE("OK"));
580 dirCreatedAlert->SetFlags(dirCreatedAlert->Flags() | B_CLOSE_ON_ESCAPE);
581 dirCreatedAlert->Go();
582 SetWebDir(STR_DEFAULT_WEB_DIRECTORY);
583 be_app->PostMessage(kStartServer);
584 break;
589 status_t
590 PoorManWindow::ReadSettings()
592 BPath p;
593 BFile f;
594 BMessage m;
596 if (find_directory(B_USER_SETTINGS_DIRECTORY, &p) != B_OK)
597 return B_ERROR;
598 p.Append(STR_SETTINGS_FILE_NAME);
600 f.SetTo(p.Path(), B_READ_ONLY);
601 if (f.InitCheck() != B_OK)
602 return B_ERROR;
604 if (m.Unflatten(&f) != B_OK)
605 return B_ERROR;
607 if (MSG_PREF_FILE != m.what)
608 return B_ERROR;
610 //site tab
611 if (m.FindString("fWebDirectory", &fWebDirectory) != B_OK)
612 fWebDirectory.SetTo(STR_DEFAULT_WEB_DIRECTORY);
613 if (m.FindString("fIndexFileName", &fIndexFileName) != B_OK)
614 fIndexFileName.SetTo("index.html");
615 if (m.FindBool("fDirListFlag", &fDirListFlag) != B_OK)
616 fDirListFlag = false;
618 //logging tab
619 if (m.FindBool("fLogConsoleFlag", &fLogConsoleFlag) != B_OK)
620 fLogConsoleFlag = true;
621 if (m.FindBool("fLogFileFlag", &fLogFileFlag) != B_OK)
622 fLogFileFlag = false;
623 if (m.FindString("fLogPath", &fLogPath) != B_OK)
624 fLogPath.SetTo("");
626 //advance tab
627 if (m.FindInt16("fMaxConnections", &fMaxConnections) != B_OK)
628 fMaxConnections = (int16)32;
630 //windows' position and size
631 if (m.FindRect("frame", &fFrame) != B_OK)
632 fFrame.Set(82.0f, 30.0f, 400.0f, 350.0f);
633 if (m.FindRect("fSetwindowFrame", &fSetwindowFrame) != B_OK)
634 fSetwindowFrame.Set(112.0f, 60.0f, 492.0f, 340.0f);
635 if (m.FindBool("fIsZoomed", &fIsZoomed) != B_OK)
636 fIsZoomed = true;
637 if (m.FindFloat("fLastWidth", &fLastWidth) != B_OK)
638 fLastWidth = 318.0f;
639 if (m.FindFloat("fLastHeight", &fLastHeight) != B_OK)
640 fLastHeight = 320.0f;
642 fIsZoomed?ResizeTo(fLastWidth, fLastHeight):ResizeTo(318, 53);
643 MoveTo(fFrame.left, fFrame.top);
645 fLogFile = new BFile(fLogPath.String(), B_CREATE_FILE | B_WRITE_ONLY
646 | B_OPEN_AT_END);
647 if (fLogFile->InitCheck() != B_OK) {
648 fLogFileFlag = false;
649 //log it to console, "log to file unavailable."
650 return B_OK;
653 SetDirLabel(fWebDirectory.String());
655 return B_OK;
659 status_t
660 PoorManWindow::SaveSettings()
662 BPath p;
663 BFile f;
664 BMessage m(MSG_PREF_FILE);
666 //site tab
667 m.AddString("fWebDirectory", fWebDirectory);
668 m.AddString("fIndexFileName", fIndexFileName);
669 m.AddBool("fDirListFlag", fDirListFlag);
671 //logging tab
672 m.AddBool("fLogConsoleFlag", fLogConsoleFlag);
673 m.AddBool("fLogFileFlag", fLogFileFlag);
674 m.AddString("fLogPath", fLogPath);
676 //advance tab
677 m.AddInt16("fMaxConnections", fMaxConnections);
679 //windows' position and size
680 m.AddRect("frame", fFrame);
681 m.AddRect("fSetwindowFrame", fSetwindowFrame);
682 m.AddBool("fIsZoomed", fIsZoomed);
683 m.AddFloat("fLastWidth", fLastWidth);
684 m.AddFloat("fLastHeight", fLastHeight);
686 if (find_directory(B_USER_SETTINGS_DIRECTORY, &p) != B_OK)
687 return B_ERROR;
688 p.Append(STR_SETTINGS_FILE_NAME);
690 f.SetTo(p.Path(), B_WRITE_ONLY | B_ERASE_FILE | B_CREATE_FILE);
691 if (f.InitCheck() != B_OK)
692 return B_ERROR;
694 if (m.Flatten(&f) != B_OK)
695 return B_ERROR;
697 return B_OK;
701 status_t
702 PoorManWindow::StartServer()
704 if (fServer == NULL)
705 fServer = new PoorManServer(fWebDirectory.String(), fMaxConnections,
706 fDirListFlag, fIndexFileName.String());
708 poorman_log(B_TRANSLATE("Starting up... "));
709 if (fServer->Run() != B_OK) {
710 return B_ERROR;
713 fStatus = true;
714 UpdateStatusLabelAndMenuItem();
715 poorman_log(B_TRANSLATE("done.\n"), false, INADDR_NONE, GREEN);
717 return B_OK;
721 status_t
722 PoorManWindow::StopServer()
724 if (fServer == NULL)
725 return B_ERROR;
727 poorman_log(B_TRANSLATE("Shutting down.\n"));
728 fServer->Stop();
729 fStatus = false;
730 UpdateStatusLabelAndMenuItem();
731 return B_OK;
735 void
736 PoorManWindow::SetLogPath(const char* str)
738 if (!strcmp(fLogPath, str))
739 return;
741 BFile* temp = new BFile(str, B_CREATE_FILE | B_WRITE_ONLY | B_OPEN_AT_END);
743 if (temp->InitCheck() != B_OK) {
744 delete temp;
745 return;
748 if (pthread_rwlock_wrlock(&fLogFileLock) == 0) {
749 delete fLogFile;
750 fLogFile = temp;
751 pthread_rwlock_unlock(&fLogFileLock);
752 } else {
753 delete temp;
754 return;
757 fLogPath.SetTo(str);