1 /* PoorManWindow.cpp 2 * 3 * Philip Harrison 4 * Started: 4/25/2004 5 * Version: 0.1 6 */ 7 8 #include "PoorManWindow.h" 9 10 #include <string.h> 11 #include <time.h> 12 #include <arpa/inet.h> 13 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> 32 33 #include "PoorManApplication.h" 34 #include "PoorManPreferencesWindow.h" 35 #include "PoorManView.h" 36 #include "PoorManServer.h" 37 #include "PoorManLogger.h" 38 #include "constants.h" 39 40 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 45 46 47 PoorManWindow::PoorManWindow(BRect frame) 48 : 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) 55 { 56 //preferences init 57 fWebDirectory.SetTo(STR_DEFAULT_WEB_DIRECTORY); 58 fIndexFileName.SetTo("index.html"); 59 fDirListFlag = false; 60 61 fLogConsoleFlag = true; 62 fLogFileFlag = false; 63 fLogPath.SetTo(""); 64 65 fMaxConnections = (int16)32; 66 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); 72 73 // PoorMan Window 74 SetSizeLimits(318, 1600, 53, 1200); 75 // limit the size of the size of the window 76 77 // ----------------------------------------------------------------- 78 // Three Labels 79 80 // Status String 81 fStatusView = new BStringView("Status View", B_TRANSLATE("Status: Stopped")); 82 83 // Directory String 84 fDirView = new BStringView("Dir View", B_TRANSLATE("Directory: (none)")); 85 86 // Hits String 87 fHitsView = new BStringView("Hit View", B_TRANSLATE("Hits: 0")); 88 89 // ----------------------------------------------------------------- 90 // Logging View 91 92 fLoggingView = new BTextView(STR_TXT_VIEW, B_WILL_DRAW ); 93 94 fLoggingView->MakeEditable(false); // user cannot change the text 95 fLoggingView->MakeSelectable(true); 96 fLoggingView->SetViewColor(WHITE); 97 fLoggingView->SetStylable(true); 98 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); 105 106 107 // ----------------------------------------------------------------- 108 // menu bar 109 fFileMenuBar = new BMenuBar("File Menu Bar"); 110 111 // menus 112 fFileMenu = BuildFileMenu(); 113 if (fFileMenu) 114 fFileMenuBar->AddItem(fFileMenu); 115 116 fEditMenu = BuildEditMenu(); 117 if (fEditMenu) 118 fFileMenuBar->AddItem(fEditMenu); 119 120 fControlsMenu = BuildControlsMenu(); 121 if (fControlsMenu) 122 fFileMenuBar->AddItem(fControlsMenu); 123 124 // File Panels 125 BWindow* change_title; 126 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); 132 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); 138 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); 154 155 pthread_rwlock_init(&fLogFileLock, NULL); 156 } 157 158 159 PoorManWindow::~PoorManWindow() 160 { 161 delete fServer; 162 delete fLogFile; 163 pthread_rwlock_destroy(&fLogFileLock); 164 } 165 166 167 void 168 PoorManWindow::MessageReceived(BMessage* message) 169 { 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; 215 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; 223 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); 230 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); 235 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); 240 241 if (time != -1) { 242 BString timeString; 243 if (BDateTimeFormat().Format(timeString, time, DATE_FORMAT, 244 TIME_FORMAT) == B_OK) { 245 line << '[' << timeString << "]: "; 246 } 247 } 248 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 line << '(' << addr << ") "; 255 } 256 } 257 258 line << msg; 259 260 text_run run; 261 text_run_array runs; 262 263 run.offset = 0; 264 run.color = color; 265 266 runs.count = 1; 267 runs.runs[0] = run; 268 269 if (Lock()) { 270 if (fLogConsoleFlag) { 271 fLoggingView->Insert(fLoggingView->TextLength(), 272 line.String(), line.Length(), &runs); 273 fLoggingView->ScrollToOffset(fLoggingView->TextLength()); 274 } 275 276 if (fLogFileFlag) { 277 if (pthread_rwlock_rdlock(&fLogFileLock) == 0) { 278 fLogFile->Write(line.String(), line.Length()); 279 pthread_rwlock_unlock(&fLogFileLock); 280 } 281 } 282 283 Unlock(); 284 } 285 286 break; 287 } 288 default: 289 BWindow::MessageReceived(message); 290 break; 291 } 292 } 293 294 295 void 296 PoorManWindow::FrameMoved(BPoint origin) 297 { 298 fFrame.left = origin.x; 299 fFrame.top = origin.y; 300 } 301 302 303 void 304 PoorManWindow::FrameResized(float width, float height) 305 { 306 if (fIsZoomed) { 307 fLastWidth = width; 308 fLastHeight = height; 309 } 310 } 311 312 313 bool 314 PoorManWindow::QuitRequested() 315 { 316 if (fStatus) { 317 time_t now = time(NULL); 318 BString timeString; 319 BDateTimeFormat().Format(timeString, now, DATE_FORMAT, TIME_FORMAT); 320 321 BString line; 322 line << "[" << timeString << "]: " << B_TRANSLATE("Shutting down.") 323 << "\n"; 324 325 if (fLogConsoleFlag) { 326 fLoggingView->Insert(fLoggingView->TextLength(), 327 line, line.Length()); 328 fLoggingView->ScrollToOffset(fLoggingView->TextLength()); 329 } 330 331 if (fLogFileFlag) { 332 if (pthread_rwlock_rdlock(&fLogFileLock) == 0) { 333 fLogFile->Write(line, line.Length()); 334 pthread_rwlock_unlock(&fLogFileLock); 335 } 336 } 337 338 fServer->Stop(); 339 fStatus = false; 340 UpdateStatusLabelAndMenuItem(); 341 } 342 343 SaveSettings(); 344 be_app_messenger.SendMessage(B_QUIT_REQUESTED); 345 return true; 346 } 347 348 349 void 350 PoorManWindow::Zoom(BPoint origin, float width, float height) 351 { 352 if (fIsZoomed) { 353 // Change to the Minimal size 354 fIsZoomed = false; 355 ResizeTo(318, 53); 356 } else { 357 // Change to the Zoomed size 358 fIsZoomed = true; 359 ResizeTo(fLastWidth, fLastHeight); 360 } 361 } 362 363 364 void 365 PoorManWindow::SetHits(uint32 num) 366 { 367 fHits = num; 368 UpdateHitsLabel(); 369 } 370 371 372 // Private: Methods ------------------------------------------ 373 374 375 BMenu* 376 PoorManWindow::BuildFileMenu() const 377 { 378 BMenu* ptrFileMenu = new BMenu(STR_MNU_FILE); 379 380 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_SAVE_AS, 381 new BMessage(MSG_MENU_FILE_SAVE_AS), CMD_FILE_SAVE_AS)); 382 383 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_SAVE_SELECTION, 384 new BMessage(MSG_MENU_FILE_SAVE_SELECTION))); 385 386 ptrFileMenu->AddSeparatorItem(); 387 388 ptrFileMenu->AddItem(new BMenuItem(STR_MNU_FILE_QUIT, 389 new BMessage(B_QUIT_REQUESTED), CMD_FILE_QUIT)); 390 391 return ptrFileMenu; 392 } 393 394 395 BMenu* 396 PoorManWindow::BuildEditMenu() const 397 { 398 BMenu* ptrEditMenu = new BMenu(STR_MNU_EDIT); 399 400 BMenuItem* CopyMenuItem = new BMenuItem(STR_MNU_EDIT_COPY, 401 new BMessage(B_COPY), CMD_EDIT_COPY); 402 403 ptrEditMenu->AddItem(CopyMenuItem); 404 CopyMenuItem->SetTarget(fLoggingView, NULL); 405 406 ptrEditMenu->AddSeparatorItem(); 407 408 BMenuItem* SelectAllMenuItem = new BMenuItem(STR_MNU_EDIT_SELECT_ALL, 409 new BMessage(B_SELECT_ALL), CMD_EDIT_SELECT_ALL); 410 411 ptrEditMenu->AddItem(SelectAllMenuItem); 412 SelectAllMenuItem->SetTarget(fLoggingView, NULL); 413 414 ptrEditMenu->AddSeparatorItem(); 415 416 BMenuItem* PrefMenuItem = new BMenuItem(STR_MNU_EDIT_PREF, 417 new BMessage(MSG_MENU_EDIT_PREF)); 418 ptrEditMenu->AddItem(PrefMenuItem); 419 420 return ptrEditMenu; 421 } 422 423 424 BMenu* 425 PoorManWindow::BuildControlsMenu() const 426 { 427 BMenu* ptrControlMenu = new BMenu(STR_MNU_CTRL); 428 429 BMenuItem* RunServerMenuItem = new BMenuItem(STR_MNU_CTRL_RUN_SERVER, 430 new BMessage(MSG_MENU_CTRL_RUN)); 431 RunServerMenuItem->SetMarked(false); 432 ptrControlMenu->AddItem(RunServerMenuItem); 433 434 BMenuItem* ClearHitCounterMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_HIT_COUNTER, 435 new BMessage(MSG_MENU_CTRL_CLEAR_HIT)); 436 ptrControlMenu->AddItem(ClearHitCounterMenuItem); 437 438 ptrControlMenu->AddSeparatorItem(); 439 440 BMenuItem* ClearConsoleLogMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_CONSOLE, 441 new BMessage(MSG_MENU_CTRL_CLEAR_CONSOLE)); 442 ptrControlMenu->AddItem(ClearConsoleLogMenuItem); 443 444 BMenuItem* ClearLogFileMenuItem = new BMenuItem(STR_MNU_CTRL_CLEAR_LOG_FILE, 445 new BMessage(MSG_MENU_CTRL_CLEAR_LOG)); 446 ptrControlMenu->AddItem(ClearLogFileMenuItem); 447 448 return ptrControlMenu; 449 } 450 451 452 void 453 PoorManWindow::SetDirLabel(const char* name) 454 { 455 BString dirPath(B_TRANSLATE("Directory: ")); 456 dirPath.Append(name); 457 458 if (Lock()) { 459 fDirView->SetText(dirPath.String()); 460 Unlock(); 461 } 462 } 463 464 465 void 466 PoorManWindow::UpdateStatusLabelAndMenuItem() 467 { 468 if (Lock()) { 469 if (fStatus) 470 fStatusView->SetText(B_TRANSLATE("Status: Running")); 471 else 472 fStatusView->SetText(B_TRANSLATE("Status: Stopped")); 473 fControlsMenu->FindItem(STR_MNU_CTRL_RUN_SERVER)->SetMarked(fStatus); 474 Unlock(); 475 } 476 } 477 478 479 void 480 PoorManWindow::UpdateHitsLabel() 481 { 482 if (Lock()) { 483 sprintf(fHitsLabel, B_TRANSLATE("Hits: %lu"), GetHits()); 484 fHitsView->SetText(fHitsLabel); 485 486 Unlock(); 487 } 488 } 489 490 491 status_t 492 PoorManWindow::SaveConsole(BMessage* message, bool selection) 493 { 494 entry_ref ref; 495 const char* name; 496 BPath path; 497 BEntry entry; 498 status_t err = B_OK; 499 FILE* f; 500 501 err = message->FindRef("directory", &ref); 502 if (err != B_OK) 503 return err; 504 505 err = message->FindString("name", &name); 506 if (err != B_OK) 507 return err; 508 509 err = entry.SetTo(&ref); 510 if (err != B_OK) 511 return err; 512 513 entry.GetPath(&path); 514 path.Append(name); 515 516 if (!(f = fopen(path.Path(), "w"))) 517 return B_ERROR; 518 519 if (!selection) { 520 // write the data to the file 521 err = fwrite(fLoggingView->Text(), 1, fLoggingView->TextLength(), f); 522 } else { 523 // find the selected text and write it to a file 524 int32 start = 0, end = 0; 525 fLoggingView->GetSelection(&start, &end); 526 527 BString buffer; 528 char * buffData = buffer.LockBuffer(end - start + 1); 529 // copy the selected text from the TextView to the buffer 530 fLoggingView->GetText(start, end - start, buffData); 531 buffer.UnlockBuffer(end - start + 1); 532 533 err = fwrite(buffer.String(), 1, end - start + 1, f); 534 } 535 536 fclose(f); 537 538 return err; 539 } 540 541 542 void 543 PoorManWindow::DefaultSettings() 544 { 545 BAlert* serverAlert = new BAlert(B_TRANSLATE("Error Server"), 546 STR_ERR_CANT_START, B_TRANSLATE("OK")); 547 serverAlert->SetFlags(serverAlert->Flags() | B_CLOSE_ON_ESCAPE); 548 BAlert* dirAlert = new BAlert(B_TRANSLATE("Error Dir"), 549 STR_ERR_WEB_DIR, B_TRANSLATE("Cancel"), B_TRANSLATE("Select"), 550 B_TRANSLATE("Create public_html"), B_WIDTH_AS_USUAL, B_OFFSET_SPACING); 551 dirAlert->SetShortcut(0, B_ESCAPE); 552 int32 buttonIndex = dirAlert->Go(); 553 554 switch (buttonIndex) { 555 case 0: 556 if (Lock()) 557 Quit(); 558 be_app_messenger.SendMessage(B_QUIT_REQUESTED); 559 break; 560 561 case 1: 562 fPrefWindow = new PoorManPreferencesWindow( 563 fSetwindowFrame, 564 STR_WIN_NAME_PREF); 565 fPrefWindow->ShowWebDirFilePanel(); 566 break; 567 568 case 2: 569 if (create_directory(STR_DEFAULT_WEB_DIRECTORY, 0755) != B_OK) { 570 serverAlert->Go(); 571 if (Lock()) 572 Quit(); 573 be_app_messenger.SendMessage(B_QUIT_REQUESTED); 574 break; 575 } 576 BAlert* dirCreatedAlert = 577 new BAlert(B_TRANSLATE("Dir Created"), STR_DIR_CREATED, 578 B_TRANSLATE("OK")); 579 dirCreatedAlert->SetFlags(dirCreatedAlert->Flags() | B_CLOSE_ON_ESCAPE); 580 dirCreatedAlert->Go(); 581 SetWebDir(STR_DEFAULT_WEB_DIRECTORY); 582 be_app->PostMessage(kStartServer); 583 break; 584 } 585 } 586 587 588 status_t 589 PoorManWindow::ReadSettings() 590 { 591 BPath p; 592 BFile f; 593 BMessage m; 594 595 if (find_directory(B_USER_SETTINGS_DIRECTORY, &p) != B_OK) 596 return B_ERROR; 597 p.Append(STR_SETTINGS_FILE_NAME); 598 599 f.SetTo(p.Path(), B_READ_ONLY); 600 if (f.InitCheck() != B_OK) 601 return B_ERROR; 602 603 if (m.Unflatten(&f) != B_OK) 604 return B_ERROR; 605 606 if (MSG_PREF_FILE != m.what) 607 return B_ERROR; 608 609 //site tab 610 if (m.FindString("fWebDirectory", &fWebDirectory) != B_OK) 611 fWebDirectory.SetTo(STR_DEFAULT_WEB_DIRECTORY); 612 if (m.FindString("fIndexFileName", &fIndexFileName) != B_OK) 613 fIndexFileName.SetTo("index.html"); 614 if (m.FindBool("fDirListFlag", &fDirListFlag) != B_OK) 615 fDirListFlag = false; 616 617 //logging tab 618 if (m.FindBool("fLogConsoleFlag", &fLogConsoleFlag) != B_OK) 619 fLogConsoleFlag = true; 620 if (m.FindBool("fLogFileFlag", &fLogFileFlag) != B_OK) 621 fLogFileFlag = false; 622 if (m.FindString("fLogPath", &fLogPath) != B_OK) 623 fLogPath.SetTo(""); 624 625 //advance tab 626 if (m.FindInt16("fMaxConnections", &fMaxConnections) != B_OK) 627 fMaxConnections = (int16)32; 628 629 //windows' position and size 630 if (m.FindRect("frame", &fFrame) != B_OK) 631 fFrame.Set(82.0f, 30.0f, 400.0f, 350.0f); 632 if (m.FindRect("fSetwindowFrame", &fSetwindowFrame) != B_OK) 633 fSetwindowFrame.Set(112.0f, 60.0f, 492.0f, 340.0f); 634 if (m.FindBool("fIsZoomed", &fIsZoomed) != B_OK) 635 fIsZoomed = true; 636 if (m.FindFloat("fLastWidth", &fLastWidth) != B_OK) 637 fLastWidth = 318.0f; 638 if (m.FindFloat("fLastHeight", &fLastHeight) != B_OK) 639 fLastHeight = 320.0f; 640 641 fIsZoomed?ResizeTo(fLastWidth, fLastHeight):ResizeTo(318, 53); 642 MoveTo(fFrame.left, fFrame.top); 643 644 fLogFile = new BFile(fLogPath.String(), B_CREATE_FILE | B_WRITE_ONLY 645 | B_OPEN_AT_END); 646 if (fLogFile->InitCheck() != B_OK) { 647 fLogFileFlag = false; 648 //log it to console, "log to file unavailable." 649 return B_OK; 650 } 651 652 SetDirLabel(fWebDirectory.String()); 653 654 return B_OK; 655 } 656 657 658 status_t 659 PoorManWindow::SaveSettings() 660 { 661 BPath p; 662 BFile f; 663 BMessage m(MSG_PREF_FILE); 664 665 //site tab 666 m.AddString("fWebDirectory", fWebDirectory); 667 m.AddString("fIndexFileName", fIndexFileName); 668 m.AddBool("fDirListFlag", fDirListFlag); 669 670 //logging tab 671 m.AddBool("fLogConsoleFlag", fLogConsoleFlag); 672 m.AddBool("fLogFileFlag", fLogFileFlag); 673 m.AddString("fLogPath", fLogPath); 674 675 //advance tab 676 m.AddInt16("fMaxConnections", fMaxConnections); 677 678 //windows' position and size 679 m.AddRect("frame", fFrame); 680 m.AddRect("fSetwindowFrame", fSetwindowFrame); 681 m.AddBool("fIsZoomed", fIsZoomed); 682 m.AddFloat("fLastWidth", fLastWidth); 683 m.AddFloat("fLastHeight", fLastHeight); 684 685 if (find_directory(B_USER_SETTINGS_DIRECTORY, &p) != B_OK) 686 return B_ERROR; 687 p.Append(STR_SETTINGS_FILE_NAME); 688 689 f.SetTo(p.Path(), B_WRITE_ONLY | B_ERASE_FILE | B_CREATE_FILE); 690 if (f.InitCheck() != B_OK) 691 return B_ERROR; 692 693 if (m.Flatten(&f) != B_OK) 694 return B_ERROR; 695 696 return B_OK; 697 } 698 699 700 status_t 701 PoorManWindow::StartServer() 702 { 703 if (fServer == NULL) 704 fServer = new PoorManServer(fWebDirectory.String(), fMaxConnections, 705 fDirListFlag, fIndexFileName.String()); 706 707 poorman_log(B_TRANSLATE("Starting up... ")); 708 if (fServer->Run() != B_OK) { 709 return B_ERROR; 710 } 711 712 fStatus = true; 713 UpdateStatusLabelAndMenuItem(); 714 poorman_log(B_TRANSLATE("done.\n"), false, INADDR_NONE, GREEN); 715 716 return B_OK; 717 } 718 719 720 status_t 721 PoorManWindow::StopServer() 722 { 723 if (fServer == NULL) 724 return B_ERROR; 725 726 poorman_log(B_TRANSLATE("Shutting down.\n")); 727 fServer->Stop(); 728 fStatus = false; 729 UpdateStatusLabelAndMenuItem(); 730 return B_OK; 731 } 732 733 734 void 735 PoorManWindow::SetLogPath(const char* str) 736 { 737 if (!strcmp(fLogPath, str)) 738 return; 739 740 BFile* temp = new BFile(str, B_CREATE_FILE | B_WRITE_ONLY | B_OPEN_AT_END); 741 742 if (temp->InitCheck() != B_OK) { 743 delete temp; 744 return; 745 } 746 747 if (pthread_rwlock_wrlock(&fLogFileLock) == 0) { 748 delete fLogFile; 749 fLogFile = temp; 750 pthread_rwlock_unlock(&fLogFileLock); 751 } else { 752 delete temp; 753 return; 754 } 755 756 fLogPath.SetTo(str); 757 } 758