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.
9 //! The mail daemon's settings
12 #include <MailSettings.h>
18 #include <Directory.h>
21 #include <FindDirectory.h>
22 #include <MailDaemon.h>
24 #include <Messenger.h>
26 #include <PathFinder.h>
30 #include <MailPrivate.h>
33 // #pragma mark - BMailSettings
36 BMailSettings::BMailSettings()
42 BMailSettings::~BMailSettings()
48 BMailSettings::InitCheck() const
58 status_t status
= find_directory(B_USER_SETTINGS_DIRECTORY
, &path
);
60 fprintf(stderr
, "Couldn't find user settings directory: %s\n",
67 status
= BPrivate::WriteMessageFile(fData
, path
, "new_mail_daemon");
71 BMessenger(B_MAIL_DAEMON_SIGNATURE
).SendMessage(
72 BPrivate::kMsgSettingsUpdated
);
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
++) {
88 status
= find_directory(which
[i
], &path
);
92 path
.Append("Mail/new_mail_daemon");
94 status
= file
.SetTo(path
.Path(), B_READ_ONLY
);
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
));
107 // clobber old settings
116 // # pragma mark - Global settings
120 BMailSettings::WindowFollowsCorner()
122 return fData
.FindInt32("WindowFollowsCorner");
127 BMailSettings::SetWindowFollowsCorner(int32 whichCorner
)
129 if (fData
.ReplaceInt32("WindowFollowsCorner", whichCorner
) != B_OK
)
130 fData
.AddInt32("WindowFollowsCorner", whichCorner
);
135 BMailSettings::ShowStatusWindow()
137 int32 showStatusWindow
;
138 if (fData
.FindInt32("ShowStatusWindow", &showStatusWindow
) != B_OK
) {
139 // show during send and receive
143 return showStatusWindow
;
148 BMailSettings::SetShowStatusWindow(uint32 mode
)
150 if (fData
.ReplaceInt32("ShowStatusWindow", mode
) != B_OK
)
151 fData
.AddInt32("ShowStatusWindow", mode
);
156 BMailSettings::DaemonAutoStarts()
158 return fData
.FindBool("DaemonAutoStarts");
163 BMailSettings::SetDaemonAutoStarts(bool startIt
)
165 if (fData
.ReplaceBool("DaemonAutoStarts", startIt
) != B_OK
)
166 fData
.AddBool("DaemonAutoStarts", startIt
);
171 BMailSettings::ConfigWindowFrame()
173 return fData
.FindRect("ConfigWindowFrame");
178 BMailSettings::SetConfigWindowFrame(BRect frame
)
180 if (fData
.ReplaceRect("ConfigWindowFrame", frame
) != B_OK
)
181 fData
.AddRect("ConfigWindowFrame", frame
);
186 BMailSettings::StatusWindowFrame()
189 if (fData
.FindRect("StatusWindowFrame", &frame
) != B_OK
)
190 return BRect(100, 100, 200, 120);
197 BMailSettings::SetStatusWindowFrame(BRect frame
)
199 if (fData
.ReplaceRect("StatusWindowFrame", frame
) != B_OK
)
200 fData
.AddRect("StatusWindowFrame", frame
);
205 BMailSettings::StatusWindowWorkspaces()
208 if (fData
.FindInt32("StatusWindowWorkSpace", (int32
*)&workspaces
) != B_OK
)
209 return B_ALL_WORKSPACES
;
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
);
228 BMailSettings::StatusWindowLook()
230 return fData
.FindInt32("StatusWindowLook");
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
);
247 BMailSettings::AutoCheckInterval()
250 if (fData
.FindInt64("AutoCheckInterval", &value
) != B_OK
) {
252 return 5 * 60 * 1000 * 1000;
259 BMailSettings::SetAutoCheckInterval(bigtime_t interval
)
261 if (fData
.ReplaceInt64("AutoCheckInterval", interval
) != B_OK
)
262 fData
.AddInt64("AutoCheckInterval", interval
);
267 BMailSettings::CheckOnlyIfPPPUp()
269 return fData
.FindBool("CheckOnlyIfPPPUp");
274 BMailSettings::SetCheckOnlyIfPPPUp(bool yes
)
276 if (fData
.ReplaceBool("CheckOnlyIfPPPUp", yes
))
277 fData
.AddBool("CheckOnlyIfPPPUp", yes
);
282 BMailSettings::SendOnlyIfPPPUp()
284 return fData
.FindBool("SendOnlyIfPPPUp");
289 BMailSettings::SetSendOnlyIfPPPUp(bool yes
)
291 if (fData
.ReplaceBool("SendOnlyIfPPPUp", yes
))
292 fData
.AddBool("SendOnlyIfPPPUp", yes
);
297 BMailSettings::DefaultOutboundAccount()
299 return fData
.FindInt32("DefaultOutboundAccount");
304 BMailSettings::SetDefaultOutboundAccount(int32 to
)
306 if (fData
.ReplaceInt32("DefaultOutboundAccount", to
) != B_OK
)
307 fData
.AddInt32("DefaultOutboundAccount", to
);
314 BMailAccounts::BMailAccounts()
317 status_t status
= AccountsPath(path
);
321 BDirectory
dir(path
.Path());
322 if (dir
.InitCheck() != B_OK
)
325 std::vector
<time_t> creationTimeList
;
327 while (dir
.GetNextEntry(&entry
) != B_ENTRY_NOT_FOUND
) {
330 if (node
.GetCreationTime(&creationTime
) != B_OK
)
333 BMailAccountSettings
* account
= new BMailAccountSettings(entry
);
334 if (account
->InitCheck() != B_OK
) {
339 // sort by creation time
340 int insertIndex
= -1;
341 for (unsigned int i
= 0; i
< creationTimeList
.size(); i
++) {
342 if (creationTimeList
[i
] > creationTime
) {
347 if (insertIndex
< 0) {
348 fAccounts
.AddItem(account
);
349 creationTimeList
.push_back(creationTime
);
351 fAccounts
.AddItem(account
, insertIndex
);
352 creationTimeList
.insert(creationTimeList
.begin() + insertIndex
,
360 BMailAccounts::AccountsPath(BPath
& path
)
362 status_t status
= find_directory(B_USER_SETTINGS_DIRECTORY
, &path
);
365 return path
.Append("Mail/accounts");
369 BMailAccounts::~BMailAccounts()
371 for (int i
= 0; i
< fAccounts
.CountItems(); i
++)
372 delete fAccounts
.ItemAt(i
);
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
)
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)
417 BMailAddOnSettings::BMailAddOnSettings()
422 BMailAddOnSettings::~BMailAddOnSettings()
428 BMailAddOnSettings::Load(const BMessage
& message
)
430 const char* pathString
= NULL
;
431 if (message
.FindString("add-on path", &pathString
) != B_OK
)
434 BPath
path(pathString
);
436 if (!path
.IsAbsolute()) {
438 BPathFinder().FindPaths(B_FIND_PATH_ADD_ONS_DIRECTORY
, "mail_daemon",
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()) {
455 status_t status
= get_ref_for_path(path
.Path(), &fRef
);
460 message
.FindMessage("settings", &settings
);
465 fOriginalSettings
= *this;
472 BMailAddOnSettings::Save(BMessage
& message
)
475 status_t status
= message
.AddString("add-on path", _RelativizePath(path
));
477 status
= message
.AddMessage("settings", this);
481 fOriginalSettings
= *this;
488 BMailAddOnSettings::SetAddOnRef(const entry_ref
& ref
)
495 BMailAddOnSettings::AddOnRef() const
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.
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
);
521 return at
+ strlen(parentDirectory
);
528 BMailProtocolSettings::BMailProtocolSettings()
530 fFiltersSettings(5, true)
535 BMailProtocolSettings::~BMailProtocolSettings()
541 BMailProtocolSettings::Load(const BMessage
& message
)
543 status_t status
= BMailAddOnSettings::Load(message
);
549 message
.GetInfo("filters", &typeFound
, &countFound
);
550 if (typeFound
!= B_MESSAGE_TYPE
)
553 for (int i
= 0; i
< countFound
; i
++) {
554 int32 index
= AddFilterSettings();
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
);
570 BMailProtocolSettings::Save(BMessage
& message
)
572 status_t status
= BMailAddOnSettings::Save(message
);
576 for (int i
= 0; i
< CountFilterSettings(); i
++) {
578 BMailAddOnSettings
* filterSettings
= fFiltersSettings
.ItemAt(i
);
579 filterSettings
->Save(filter
);
580 message
.AddMessage("filters", &filter
);
587 BMailProtocolSettings::CountFilterSettings() const
589 return fFiltersSettings
.CountItems();
594 BMailProtocolSettings::AddFilterSettings(const entry_ref
* ref
)
596 BMailAddOnSettings
* filterSettings
= new BMailAddOnSettings();
598 filterSettings
->SetAddOnRef(*ref
);
600 if (fFiltersSettings
.AddItem(filterSettings
))
601 return fFiltersSettings
.CountItems() - 1;
603 delete filterSettings
;
609 BMailProtocolSettings::RemoveFilterSettings(int32 index
)
611 fFiltersSettings
.RemoveItemAt(index
);
616 BMailProtocolSettings::MoveFilterSettings(int32 from
, int32 to
)
618 if (from
< 0 || from
>= (int32
)CountFilterSettings() || to
< 0
619 || to
>= (int32
)CountFilterSettings())
624 BMailAddOnSettings
* settings
= fFiltersSettings
.RemoveItemAt(from
);
625 fFiltersSettings
.AddItem(settings
, to
);
631 BMailProtocolSettings::FilterSettingsAt(int32 index
) const
633 return fFiltersSettings
.ItemAt(index
);
638 BMailProtocolSettings::HasBeenModified() const
640 if (BMailAddOnSettings::HasBeenModified())
642 for (int32 i
= 0; i
< CountFilterSettings(); i
++) {
643 if (FilterSettingsAt(i
)->HasBeenModified())
653 BMailAccountSettings::BMailAccountSettings()
656 fInboundEnabled(true),
657 fOutboundEnabled(true),
660 fAccountID
= real_time_clock();
664 BMailAccountSettings::BMailAccountSettings(BEntry account
)
666 fAccountFile(account
),
673 BMailAccountSettings::~BMailAccountSettings()
680 BMailAccountSettings::SetAccountID(int32 id
)
688 BMailAccountSettings::AccountID() const
695 BMailAccountSettings::SetName(const char* name
)
703 BMailAccountSettings::Name() const
710 BMailAccountSettings::SetRealName(const char* realName
)
713 fRealName
= realName
;
718 BMailAccountSettings::RealName() const
725 BMailAccountSettings::SetReturnAddress(const char* returnAddress
)
728 fReturnAdress
= returnAddress
;
733 BMailAccountSettings::ReturnAddress() const
735 return fReturnAdress
;
740 BMailAccountSettings::SetInboundAddOn(const char* name
)
743 if (_GetAddOnRef("mail_daemon/inbound_protocols", name
, ref
) != B_OK
)
746 fInboundSettings
.SetAddOnRef(ref
);
752 BMailAccountSettings::SetOutboundAddOn(const char* name
)
755 if (_GetAddOnRef("mail_daemon/outbound_protocols", name
, ref
) != B_OK
)
758 fOutboundSettings
.SetAddOnRef(ref
);
764 BMailAccountSettings::InboundAddOnRef() const
766 return fInboundSettings
.AddOnRef();
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
;
806 BMailAccountSettings::HasInbound()
808 return BEntry(&fInboundSettings
.AddOnRef()).Exists();
813 BMailAccountSettings::HasOutbound()
815 return BEntry(&fOutboundSettings
.AddOnRef()).Exists();
820 BMailAccountSettings::SetInboundEnabled(bool enabled
)
822 fInboundEnabled
= enabled
;
828 BMailAccountSettings::IsInboundEnabled() const
830 return fInboundEnabled
;
835 BMailAccountSettings::SetOutboundEnabled(bool enabled
)
837 fOutboundEnabled
= enabled
;
843 BMailAccountSettings::IsOutboundEnabled() const
845 return fOutboundEnabled
;
850 BMailAccountSettings::Reload()
852 BFile
file(&fAccountFile
, B_READ_ONLY
);
853 status_t status
= file
.InitCheck();
857 settings
.Unflatten(&file
);
860 if (settings
.FindInt32("id", &id
) == B_OK
)
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;
884 BMailAccountSettings::Save()
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();
908 BFile
file(&fAccountFile
, B_READ_WRITE
| B_CREATE_FILE
| B_ERASE_FILE
);
909 status
= file
.InitCheck();
912 return settings
.Flatten(&file
);
917 BMailAccountSettings::Delete()
919 return fAccountFile
.Remove();
924 BMailAccountSettings::HasBeenModified() const
927 || fInboundSettings
.HasBeenModified()
928 || fOutboundSettings
.HasBeenModified();
933 BMailAccountSettings::AccountFile() const
940 BMailAccountSettings::_CreateAccountFilePath()
943 status_t status
= find_directory(B_USER_SETTINGS_DIRECTORY
, &path
);
946 path
.Append("Mail/accounts");
947 create_directory(path
.Path(), 777);
949 if (fAccountFile
.InitCheck() == B_OK
)
952 BString fileName
= fAccountName
;
954 fileName
<< fAccountID
;
955 for (int i
= 0; ; i
++) {
956 BString testFileName
= fileName
;
961 BPath
testPath(path
);
962 testPath
.Append(testFileName
);
963 BEntry
testEntry(testPath
.Path());
964 if (!testEntry
.Exists()) {
965 fileName
= testFileName
;
970 path
.Append(fileName
);
971 return fAccountFile
.SetTo(path
.Path());
976 BMailAccountSettings::_GetAddOnRef(const char* subPath
, const char* name
,
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
)
990 return B_ENTRY_NOT_FOUND
;