btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / kits / mail / MailSettings.cpp
blob52cabe4ff5553e18da5a3ef3b604c548fe9cb9ed
1 /*
2 * Copyright 2004-2015, Haiku Inc. All rights reserved.
3 * Copyright 2001-2003 Dr. Zoidberg Enterprises. All rights reserved.
5 * Distributed under the terms of the MIT License.
6 */
9 //! The mail daemon's settings
12 #include <MailSettings.h>
14 #include <stdio.h>
15 #include <string.h>
16 #include <stdlib.h>
18 #include <Directory.h>
19 #include <Entry.h>
20 #include <File.h>
21 #include <FindDirectory.h>
22 #include <MailDaemon.h>
23 #include <Message.h>
24 #include <Messenger.h>
25 #include <Path.h>
26 #include <PathFinder.h>
27 #include <String.h>
28 #include <Window.h>
30 #include <MailPrivate.h>
33 // #pragma mark - BMailSettings
36 BMailSettings::BMailSettings()
38 Reload();
42 BMailSettings::~BMailSettings()
47 status_t
48 BMailSettings::InitCheck() const
50 return B_OK;
54 status_t
55 BMailSettings::Save()
57 BPath path;
58 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
59 if (status != B_OK) {
60 fprintf(stderr, "Couldn't find user settings directory: %s\n",
61 strerror(status));
62 return status;
65 path.Append("Mail");
67 status = BPrivate::WriteMessageFile(fData, path, "new_mail_daemon");
68 if (status != B_OK)
69 return status;
71 BMessenger(B_MAIL_DAEMON_SIGNATURE).SendMessage(
72 BPrivate::kMsgSettingsUpdated);
73 return B_OK;
77 status_t
78 BMailSettings::Reload()
80 // Try directories from most specific to least
81 directory_which which[] = {
82 B_USER_SETTINGS_DIRECTORY,
83 B_SYSTEM_SETTINGS_DIRECTORY};
84 status_t status = B_ENTRY_NOT_FOUND;
86 for (size_t i = 0; i < sizeof(which) / sizeof(which[0]); i++) {
87 BPath path;
88 status = find_directory(which[i], &path);
89 if (status != B_OK)
90 continue;
92 path.Append("Mail/new_mail_daemon");
93 BFile file;
94 status = file.SetTo(path.Path(), B_READ_ONLY);
95 if (status != B_OK)
96 continue;
98 // read settings
99 BMessage settings;
100 status = settings.Unflatten(&file);
101 if (status != B_OK) {
102 fprintf(stderr, "Couldn't read settings from '%s': %s\n",
103 path.Path(), strerror(status));
104 continue;
107 // clobber old settings
108 fData = settings;
109 return B_OK;
112 return status;
116 // # pragma mark - Global settings
119 int32
120 BMailSettings::WindowFollowsCorner()
122 return fData.FindInt32("WindowFollowsCorner");
126 void
127 BMailSettings::SetWindowFollowsCorner(int32 whichCorner)
129 if (fData.ReplaceInt32("WindowFollowsCorner", whichCorner) != B_OK)
130 fData.AddInt32("WindowFollowsCorner", whichCorner);
134 uint32
135 BMailSettings::ShowStatusWindow()
137 int32 showStatusWindow;
138 if (fData.FindInt32("ShowStatusWindow", &showStatusWindow) != B_OK) {
139 // show during send and receive
140 return 2;
143 return showStatusWindow;
147 void
148 BMailSettings::SetShowStatusWindow(uint32 mode)
150 if (fData.ReplaceInt32("ShowStatusWindow", mode) != B_OK)
151 fData.AddInt32("ShowStatusWindow", mode);
155 bool
156 BMailSettings::DaemonAutoStarts()
158 return fData.FindBool("DaemonAutoStarts");
162 void
163 BMailSettings::SetDaemonAutoStarts(bool startIt)
165 if (fData.ReplaceBool("DaemonAutoStarts", startIt) != B_OK)
166 fData.AddBool("DaemonAutoStarts", startIt);
170 BRect
171 BMailSettings::ConfigWindowFrame()
173 return fData.FindRect("ConfigWindowFrame");
177 void
178 BMailSettings::SetConfigWindowFrame(BRect frame)
180 if (fData.ReplaceRect("ConfigWindowFrame", frame) != B_OK)
181 fData.AddRect("ConfigWindowFrame", frame);
185 BRect
186 BMailSettings::StatusWindowFrame()
188 BRect frame;
189 if (fData.FindRect("StatusWindowFrame", &frame) != B_OK)
190 return BRect(100, 100, 200, 120);
192 return frame;
196 void
197 BMailSettings::SetStatusWindowFrame(BRect frame)
199 if (fData.ReplaceRect("StatusWindowFrame", frame) != B_OK)
200 fData.AddRect("StatusWindowFrame", frame);
204 int32
205 BMailSettings::StatusWindowWorkspaces()
207 uint32 workspaces;
208 if (fData.FindInt32("StatusWindowWorkSpace", (int32*)&workspaces) != B_OK)
209 return B_ALL_WORKSPACES;
211 return workspaces;
215 void
216 BMailSettings::SetStatusWindowWorkspaces(int32 workspace)
218 if (fData.ReplaceInt32("StatusWindowWorkSpace", workspace) != B_OK)
219 fData.AddInt32("StatusWindowWorkSpace", workspace);
221 BMessage msg('wsch');
222 msg.AddInt32("StatusWindowWorkSpace",workspace);
223 BMessenger(B_MAIL_DAEMON_SIGNATURE).SendMessage(&msg);
227 int32
228 BMailSettings::StatusWindowLook()
230 return fData.FindInt32("StatusWindowLook");
234 void
235 BMailSettings::SetStatusWindowLook(int32 look)
237 if (fData.ReplaceInt32("StatusWindowLook", look) != B_OK)
238 fData.AddInt32("StatusWindowLook", look);
240 BMessage msg('lkch');
241 msg.AddInt32("StatusWindowLook", look);
242 BMessenger(B_MAIL_DAEMON_SIGNATURE).SendMessage(&msg);
246 bigtime_t
247 BMailSettings::AutoCheckInterval()
249 bigtime_t value;
250 if (fData.FindInt64("AutoCheckInterval", &value) != B_OK) {
251 // every 5 min
252 return 5 * 60 * 1000 * 1000;
254 return value;
258 void
259 BMailSettings::SetAutoCheckInterval(bigtime_t interval)
261 if (fData.ReplaceInt64("AutoCheckInterval", interval) != B_OK)
262 fData.AddInt64("AutoCheckInterval", interval);
266 bool
267 BMailSettings::CheckOnlyIfPPPUp()
269 return fData.FindBool("CheckOnlyIfPPPUp");
273 void
274 BMailSettings::SetCheckOnlyIfPPPUp(bool yes)
276 if (fData.ReplaceBool("CheckOnlyIfPPPUp", yes))
277 fData.AddBool("CheckOnlyIfPPPUp", yes);
281 bool
282 BMailSettings::SendOnlyIfPPPUp()
284 return fData.FindBool("SendOnlyIfPPPUp");
288 void
289 BMailSettings::SetSendOnlyIfPPPUp(bool yes)
291 if (fData.ReplaceBool("SendOnlyIfPPPUp", yes))
292 fData.AddBool("SendOnlyIfPPPUp", yes);
296 int32
297 BMailSettings::DefaultOutboundAccount()
299 return fData.FindInt32("DefaultOutboundAccount");
303 void
304 BMailSettings::SetDefaultOutboundAccount(int32 to)
306 if (fData.ReplaceInt32("DefaultOutboundAccount", to) != B_OK)
307 fData.AddInt32("DefaultOutboundAccount", to);
311 // #pragma mark -
314 BMailAccounts::BMailAccounts()
316 BPath path;
317 status_t status = AccountsPath(path);
318 if (status != B_OK)
319 return;
321 BDirectory dir(path.Path());
322 if (dir.InitCheck() != B_OK)
323 return;
325 std::vector<time_t> creationTimeList;
326 BEntry entry;
327 while (dir.GetNextEntry(&entry) != B_ENTRY_NOT_FOUND) {
328 BNode node(&entry);
329 time_t creationTime;
330 if (node.GetCreationTime(&creationTime) != B_OK)
331 continue;
333 BMailAccountSettings* account = new BMailAccountSettings(entry);
334 if (account->InitCheck() != B_OK) {
335 delete account;
336 continue;
339 // sort by creation time
340 int insertIndex = -1;
341 for (unsigned int i = 0; i < creationTimeList.size(); i++) {
342 if (creationTimeList[i] > creationTime) {
343 insertIndex = i;
344 break;
347 if (insertIndex < 0) {
348 fAccounts.AddItem(account);
349 creationTimeList.push_back(creationTime);
350 } else {
351 fAccounts.AddItem(account, insertIndex);
352 creationTimeList.insert(creationTimeList.begin() + insertIndex,
353 creationTime);
359 status_t
360 BMailAccounts::AccountsPath(BPath& path)
362 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
363 if (status != B_OK)
364 return status;
365 return path.Append("Mail/accounts");
369 BMailAccounts::~BMailAccounts()
371 for (int i = 0; i < fAccounts.CountItems(); i++)
372 delete fAccounts.ItemAt(i);
376 int32
377 BMailAccounts::CountAccounts()
379 return fAccounts.CountItems();
383 BMailAccountSettings*
384 BMailAccounts::AccountAt(int32 index)
386 return fAccounts.ItemAt(index);
390 BMailAccountSettings*
391 BMailAccounts::AccountByID(int32 id)
393 for (int i = 0; i < fAccounts.CountItems(); i++) {
394 BMailAccountSettings* account = fAccounts.ItemAt(i);
395 if (account->AccountID() == id)
396 return account;
398 return NULL;
402 BMailAccountSettings*
403 BMailAccounts::AccountByName(const char* name)
405 for (int i = 0; i < fAccounts.CountItems(); i++) {
406 BMailAccountSettings* account = fAccounts.ItemAt(i);
407 if (strcmp(account->Name(), name) == 0)
408 return account;
410 return NULL;
414 // #pragma mark -
417 BMailAddOnSettings::BMailAddOnSettings()
422 BMailAddOnSettings::~BMailAddOnSettings()
427 status_t
428 BMailAddOnSettings::Load(const BMessage& message)
430 const char* pathString = NULL;
431 if (message.FindString("add-on path", &pathString) != B_OK)
432 return B_BAD_VALUE;
434 BPath path(pathString);
436 if (!path.IsAbsolute()) {
437 BStringList paths;
438 BPathFinder().FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY, "mail_daemon",
439 paths);
441 status_t status = B_ENTRY_NOT_FOUND;
443 for (int32 i = 0; i < paths.CountStrings(); i++) {
444 path.SetTo(paths.StringAt(i), pathString);
445 BEntry entry(path.Path());
446 if (entry.Exists()) {
447 status = B_OK;
448 break;
451 if (status != B_OK)
452 return status;
455 status_t status = get_ref_for_path(path.Path(), &fRef);
456 if (status != B_OK)
457 return status;
459 BMessage settings;
460 message.FindMessage("settings", &settings);
462 MakeEmpty();
463 Append(settings);
465 fOriginalSettings = *this;
466 fOriginalRef = fRef;
467 return B_OK;
471 status_t
472 BMailAddOnSettings::Save(BMessage& message)
474 BPath path(&fRef);
475 status_t status = message.AddString("add-on path", _RelativizePath(path));
476 if (status == B_OK)
477 status = message.AddMessage("settings", this);
478 if (status != B_OK)
479 return status;
481 fOriginalSettings = *this;
482 fOriginalRef = fRef;
483 return B_OK;
487 void
488 BMailAddOnSettings::SetAddOnRef(const entry_ref& ref)
490 fRef = ref;
494 const entry_ref&
495 BMailAddOnSettings::AddOnRef() const
497 return fRef;
501 bool
502 BMailAddOnSettings::HasBeenModified() const
504 return fRef != fOriginalRef
505 || !fOriginalSettings.HasSameData(*this, true, true);
509 /*! Cuts off the ".../add-ons/mail_daemon" part of the provided \a path
510 in case it exists. Otherwise, the complete path will be returned.
512 const char*
513 BMailAddOnSettings::_RelativizePath(const BPath& path) const
515 const char* string = path.Path();
516 const char* parentDirectory = "/mail_daemon/";
517 const char* at = strstr(string, parentDirectory);
518 if (at == NULL)
519 return string;
521 return at + strlen(parentDirectory);
525 // #pragma mark -
528 BMailProtocolSettings::BMailProtocolSettings()
530 fFiltersSettings(5, true)
535 BMailProtocolSettings::~BMailProtocolSettings()
540 status_t
541 BMailProtocolSettings::Load(const BMessage& message)
543 status_t status = BMailAddOnSettings::Load(message);
544 if (status != B_OK)
545 return status;
547 type_code typeFound;
548 int32 countFound;
549 message.GetInfo("filters", &typeFound, &countFound);
550 if (typeFound != B_MESSAGE_TYPE)
551 return B_BAD_VALUE;
553 for (int i = 0; i < countFound; i++) {
554 int32 index = AddFilterSettings();
555 if (index < 0)
556 return B_NO_MEMORY;
558 BMailAddOnSettings* filterSettings = fFiltersSettings.ItemAt(index);
560 BMessage filterMessage;
561 message.FindMessage("filters", i, &filterMessage);
562 if (filterSettings->Load(filterMessage) != B_OK)
563 RemoveFilterSettings(index);
565 return B_OK;
569 status_t
570 BMailProtocolSettings::Save(BMessage& message)
572 status_t status = BMailAddOnSettings::Save(message);
573 if (status != B_OK)
574 return status;
576 for (int i = 0; i < CountFilterSettings(); i++) {
577 BMessage filter;
578 BMailAddOnSettings* filterSettings = fFiltersSettings.ItemAt(i);
579 filterSettings->Save(filter);
580 message.AddMessage("filters", &filter);
582 return B_OK;
586 int32
587 BMailProtocolSettings::CountFilterSettings() const
589 return fFiltersSettings.CountItems();
593 int32
594 BMailProtocolSettings::AddFilterSettings(const entry_ref* ref)
596 BMailAddOnSettings* filterSettings = new BMailAddOnSettings();
597 if (ref != NULL)
598 filterSettings->SetAddOnRef(*ref);
600 if (fFiltersSettings.AddItem(filterSettings))
601 return fFiltersSettings.CountItems() - 1;
603 delete filterSettings;
604 return -1;
608 void
609 BMailProtocolSettings::RemoveFilterSettings(int32 index)
611 fFiltersSettings.RemoveItemAt(index);
615 bool
616 BMailProtocolSettings::MoveFilterSettings(int32 from, int32 to)
618 if (from < 0 || from >= (int32)CountFilterSettings() || to < 0
619 || to >= (int32)CountFilterSettings())
620 return false;
621 if (from == to)
622 return true;
624 BMailAddOnSettings* settings = fFiltersSettings.RemoveItemAt(from);
625 fFiltersSettings.AddItem(settings, to);
626 return true;
630 BMailAddOnSettings*
631 BMailProtocolSettings::FilterSettingsAt(int32 index) const
633 return fFiltersSettings.ItemAt(index);
637 bool
638 BMailProtocolSettings::HasBeenModified() const
640 if (BMailAddOnSettings::HasBeenModified())
641 return true;
642 for (int32 i = 0; i < CountFilterSettings(); i++) {
643 if (FilterSettingsAt(i)->HasBeenModified())
644 return true;
646 return false;
650 // #pragma mark -
653 BMailAccountSettings::BMailAccountSettings()
655 fStatus(B_OK),
656 fInboundEnabled(true),
657 fOutboundEnabled(true),
658 fModified(true)
660 fAccountID = real_time_clock();
664 BMailAccountSettings::BMailAccountSettings(BEntry account)
666 fAccountFile(account),
667 fModified(false)
669 fStatus = Reload();
673 BMailAccountSettings::~BMailAccountSettings()
679 void
680 BMailAccountSettings::SetAccountID(int32 id)
682 fModified = true;
683 fAccountID = id;
687 int32
688 BMailAccountSettings::AccountID() const
690 return fAccountID;
694 void
695 BMailAccountSettings::SetName(const char* name)
697 fModified = true;
698 fAccountName = name;
702 const char*
703 BMailAccountSettings::Name() const
705 return fAccountName;
709 void
710 BMailAccountSettings::SetRealName(const char* realName)
712 fModified = true;
713 fRealName = realName;
717 const char*
718 BMailAccountSettings::RealName() const
720 return fRealName;
724 void
725 BMailAccountSettings::SetReturnAddress(const char* returnAddress)
727 fModified = true;
728 fReturnAdress = returnAddress;
732 const char*
733 BMailAccountSettings::ReturnAddress() const
735 return fReturnAdress;
739 bool
740 BMailAccountSettings::SetInboundAddOn(const char* name)
742 entry_ref ref;
743 if (_GetAddOnRef("mail_daemon/inbound_protocols", name, ref) != B_OK)
744 return false;
746 fInboundSettings.SetAddOnRef(ref);
747 return true;
751 bool
752 BMailAccountSettings::SetOutboundAddOn(const char* name)
754 entry_ref ref;
755 if (_GetAddOnRef("mail_daemon/outbound_protocols", name, ref) != B_OK)
756 return false;
758 fOutboundSettings.SetAddOnRef(ref);
759 return true;
763 const entry_ref&
764 BMailAccountSettings::InboundAddOnRef() const
766 return fInboundSettings.AddOnRef();
770 const entry_ref&
771 BMailAccountSettings::OutboundAddOnRef() const
773 return fOutboundSettings.AddOnRef();
777 BMailProtocolSettings&
778 BMailAccountSettings::InboundSettings()
780 return fInboundSettings;
784 const BMailProtocolSettings&
785 BMailAccountSettings::InboundSettings() const
787 return fInboundSettings;
791 BMailProtocolSettings&
792 BMailAccountSettings::OutboundSettings()
794 return fOutboundSettings;
798 const BMailProtocolSettings&
799 BMailAccountSettings::OutboundSettings() const
801 return fOutboundSettings;
805 bool
806 BMailAccountSettings::HasInbound()
808 return BEntry(&fInboundSettings.AddOnRef()).Exists();
812 bool
813 BMailAccountSettings::HasOutbound()
815 return BEntry(&fOutboundSettings.AddOnRef()).Exists();
819 void
820 BMailAccountSettings::SetInboundEnabled(bool enabled)
822 fInboundEnabled = enabled;
823 fModified = true;
827 bool
828 BMailAccountSettings::IsInboundEnabled() const
830 return fInboundEnabled;
834 void
835 BMailAccountSettings::SetOutboundEnabled(bool enabled)
837 fOutboundEnabled = enabled;
838 fModified = true;
842 bool
843 BMailAccountSettings::IsOutboundEnabled() const
845 return fOutboundEnabled;
849 status_t
850 BMailAccountSettings::Reload()
852 BFile file(&fAccountFile, B_READ_ONLY);
853 status_t status = file.InitCheck();
854 if (status != B_OK)
855 return status;
856 BMessage settings;
857 settings.Unflatten(&file);
859 int32 id;
860 if (settings.FindInt32("id", &id) == B_OK)
861 fAccountID = id;
862 settings.FindString("name", &fAccountName);
863 settings.FindString("real_name", &fRealName);
864 settings.FindString("return_address", &fReturnAdress);
866 BMessage inboundSettings;
867 settings.FindMessage("inbound", &inboundSettings);
868 fInboundSettings.Load(inboundSettings);
869 BMessage outboundSettings;
870 settings.FindMessage("outbound", &outboundSettings);
871 fOutboundSettings.Load(outboundSettings);
873 if (settings.FindBool("inbound_enabled", &fInboundEnabled) != B_OK)
874 fInboundEnabled = true;
875 if (settings.FindBool("outbound_enabled", &fOutboundEnabled) != B_OK)
876 fOutboundEnabled = true;
878 fModified = false;
879 return B_OK;
883 status_t
884 BMailAccountSettings::Save()
886 fModified = false;
888 BMessage settings;
889 settings.AddInt32("id", fAccountID);
890 settings.AddString("name", fAccountName);
891 settings.AddString("real_name", fRealName);
892 settings.AddString("return_address", fReturnAdress);
894 BMessage inboundSettings;
895 fInboundSettings.Save(inboundSettings);
896 settings.AddMessage("inbound", &inboundSettings);
897 BMessage outboundSettings;
898 fOutboundSettings.Save(outboundSettings);
899 settings.AddMessage("outbound", &outboundSettings);
901 settings.AddBool("inbound_enabled", fInboundEnabled);
902 settings.AddBool("outbound_enabled", fOutboundEnabled);
904 status_t status = _CreateAccountFilePath();
905 if (status != B_OK)
906 return status;
908 BFile file(&fAccountFile, B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
909 status = file.InitCheck();
910 if (status != B_OK)
911 return status;
912 return settings.Flatten(&file);
916 status_t
917 BMailAccountSettings::Delete()
919 return fAccountFile.Remove();
923 bool
924 BMailAccountSettings::HasBeenModified() const
926 return fModified
927 || fInboundSettings.HasBeenModified()
928 || fOutboundSettings.HasBeenModified();
932 const BEntry&
933 BMailAccountSettings::AccountFile() const
935 return fAccountFile;
939 status_t
940 BMailAccountSettings::_CreateAccountFilePath()
942 BPath path;
943 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
944 if (status != B_OK)
945 return status;
946 path.Append("Mail/accounts");
947 create_directory(path.Path(), 777);
949 if (fAccountFile.InitCheck() == B_OK)
950 return B_OK;
952 BString fileName = fAccountName;
953 if (fileName == "")
954 fileName << fAccountID;
955 for (int i = 0; ; i++) {
956 BString testFileName = fileName;
957 if (i != 0) {
958 testFileName += "_";
959 testFileName << i;
961 BPath testPath(path);
962 testPath.Append(testFileName);
963 BEntry testEntry(testPath.Path());
964 if (!testEntry.Exists()) {
965 fileName = testFileName;
966 break;
970 path.Append(fileName);
971 return fAccountFile.SetTo(path.Path());
975 status_t
976 BMailAccountSettings::_GetAddOnRef(const char* subPath, const char* name,
977 entry_ref& ref)
979 BStringList paths;
980 BPathFinder().FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY, subPath, paths);
982 for (int32 i = 0; i < paths.CountStrings(); i++) {
983 BPath path(paths.StringAt(i), name);
984 BEntry entry(path.Path());
985 if (entry.Exists()) {
986 if (entry.GetRef(&ref) == B_OK)
987 return B_OK;
990 return B_ENTRY_NOT_FOUND;